How to Scale AirNotifier to 1 Million+ Notifications

How to Scale AirNotifier to 1 Million+ Notifications

Your application is a success. User numbers are climbing, engagement is high, and the push notifications you’re sending are multiplying from thousands to hundreds of thousands, and soon, millions. This is a great problem to have.

But the simple, single-server AirNotifier setup that worked perfectly for your first 10,000 users is now showing signs of strain. API response times are slow, notifications are getting delayed, and you’re worried the entire system might fall over during a peak traffic spike.

If you followed our how-to guide for beginners or used our guide to install AirNotifier with Docker, you have a solid foundation. However, a standard AirNotifier installation is not designed for this kind of load. To handle millions of notifications reliably, you need to move from a single server to a distributed, scalable architecture. This guide will provide the blueprint to do just that.

Understanding the Bottlenecks of a Standard Setup

Before we build a new system, it’s crucial to understand why the old one breaks. A standard AirNotifier instance typically runs the application and its MongoDB database on a single server. This creates three primary bottlenecks at scale:

  1. The Application Server: The single Python (Tornado) process can only handle a finite number of concurrent API requests. As traffic increases, it becomes CPU-bound, leading to slow response times and request timeouts.
  2. The Database: A single MongoDB instance is overwhelmed by the sheer volume of read/write operations. Storing device tokens, queuing notifications, and logging every event creates intense disk I/O and query contention, making the database the slowest part of the system.
  3. The Gateway Connection: All outgoing notifications to Apple (APNs) and Google (FCM) are pushed through a single connection point, which can become saturated or fail, causing delays for every user.

The Blueprint for a Scalable AirNotifier Architecture

To overcome these bottlenecks, we need to evolve our architecture from a single monolithic server into a set of specialised, independently scalable components.

Here’s the four-part blueprint:

1. Implement a Load Balancer

The first step is to stop sending traffic directly to your AirNotifier application. A load balancer (like Nginx or HAProxy) will act as the single entry point for all API requests. Its job is to distribute incoming traffic evenly across multiple application servers.

This immediately solves the single-point-of-failure problem for your application and allows you to scale horizontally by simply adding more servers behind the load balancer.

2. Scale the Application with Multiple Instances

Instead of one large, powerful server (vertical scaling), we will run multiple smaller, identical copies of the AirNotifier application on different servers (horizontal scaling). The load balancer will distribute requests among them.

This means if one application server goes down, the others can handle the load. If you have a traffic spike, you can quickly spin up new instances to meet the demand. This makes your application layer both resilient and elastic.

3. Decouple with a Message Queue

This is the most critical step for achieving massive scale and reliability. Instead of having the application server immediately try to send a notification, we will use a message queue (like RabbitMQ or Redis). As explained in a detailed CloudAMQP article on the topic, this pattern decouples tasks from the main application thread.

The new workflow looks like this:

  1. Your API request hits the load balancer.
  2. The load balancer forwards the request to an available AirNotifier app instance.
  3. The app instance validates the request and, instead of sending the notification, it pushes the notification job onto the message queue. This is an extremely fast operation.
  4. The app instance immediately responds with a “202 Accepted” status, telling the client the job is queued.

This makes your API incredibly fast and ensures that even if the APNs or FCM gateways are temporarily down, no notifications are lost. They simply wait in the queue.

4. Create Dedicated Notification Workers

Now that jobs are in the queue, we need a separate pool of servers whose only job is to process them. These are dedicated workers. They pull jobs from the message queue, connect to the relevant push notification service (APNs/FCM), and send the notification.

The beauty of this model is that you can scale your workers independently. If your notification queue starts to get long, you can simply add more worker instances to clear it faster, without affecting the performance of your main API servers.

Optimising the Database for High Throughput

With our application layer scaled, the database is now the most likely bottleneck. Here’s how to ensure MongoDB can keep up.

Use a Replica Set for High Availability

Instead of a single MongoDB instance, you should always run a replica set. This consists of one primary node (which handles all writes) and multiple secondary nodes that replicate the data from the primary.

This provides two key benefits:

  • High Availability: If the primary node fails, one of the secondary nodes is automatically elected as the new primary, and your application experiences minimal downtime.
  • Read Scaling: You can configure your application to direct read queries (like fetching device information) to the secondary nodes, reducing the load on the primary.

Implement Sharding for Write Scaling

For truly massive scale (tens of millions of users), replication isn’t enough. You’ll need sharding. Sharding distributes your data across multiple replica sets (called “shards”). For example, you could have users A-M on one shard and users N-Z on another.

This means no single database server has to handle the entire write load of your application. For a deeper technical dive, MongoDB’s own documentation on sharding is an excellent resource. Sharding is complex to implement, but it’s the standard for achieving web-scale database performance.

Don’t Forget Your Indexes

This is a simple but critical optimisation. Ensure you have indexes on the fields you query most often in your devices and log collections, such as appname, token, and timestamps. An indexed query can be thousands of times faster than an unindexed one.

Monitoring and Best Practices

Scaling isn’t a “set it and forget it” task. You need to monitor your system to anticipate problems. Keep a close eye on:

  • Queue Length: A consistently growing queue means you need more notification workers.
  • Notification Latency: How long does it take from the moment a notification is queued to when it’s delivered?
  • Error Rates: Track the percentage of failed notifications to spot issues with gateways or expired tokens.
  • System Metrics: Monitor the CPU, memory, and network usage of your load balancers, app servers, workers, and database nodes.

Conclusion: From a Single Server to a Robust System

Scaling AirNotifier from a few thousand to over a million notifications is a journey from a simple application to a complex, distributed system. By replacing a single server with a resilient architecture—built on load balancing, horizontally scaled instances, a message queue, and an optimised database—you can build a notification platform that is fast, reliable, and ready for whatever growth comes next.

Want a second pair of eyes on your set-up, queue, and data design? Book an AirNotifier scaling review with Tyne Solutions. We will profile your current stack, run a guided burst test, and provide you with a clear action plan for over one million sends with confidence.

Schedule a Free Architecture Consultation with Tyne Solutions

AN_image1

AirNotifier: A How-To Guide for Beginners

Are you looking for an easy solution for handling push notifications? If the answer is Yes, then AirNotifier would be a great and user-friendly choice.

In this guide, we’ll be looking at:

  • AirNotifier: an overview
  • Getting Started with AirNotifier
  • Workflow of AirNotifier

Whether you’re new to AirNotifier, or just wanted to get an overview of how it works, this AirNotifier for beginners guide will show you what this push notification server can do and how you can get started on integrating AirNotifier into your projects. 

AirNotifier: An Overview

To start with, AirNotifier is a push notification server used for sending real-time notifications to mobile and desktop applications. A few useful features of AirNotifier include a web interface, an option to broadcast messages to all registered devices, an activity log, and a REST API. If these features sound interesting to you, then please read on for more details.

Features

Cross Platform

AirNotifier supports a range of platforms, including iOS, Android, Chrome browsers, and Windows 10 desktop applications. 

Unlimited Devices

An unlimited number of devices can be registered to AirNotifier. AirNotifier would be a good option if you don’t want to be charged when you exceed a specific number of registered devices. Whether you want to implement push notifications on a project with a small or large user base, AirNotifier will be able to handle the number of users and devices you have.

Open Source

As AirNotifier is open source, not only would this mean that the push notification server doesn’t have any additional fees, but that there is also more control over how AirNotifier can work for you. AirNotifier can be installed on your own server so you would be able to have control over the data that comes through. 

This can be a disadvantage to some people who want a push notification server that is ready right out of the box, although usually these would be paid services, like Pusher and OneSignal. AirNotifier provides a simple way of sending push notifications at no extra cost.

Web Admin UI

AirNotifier comes with a web interface that lets you configure several of its settings, view the access keys and device tokens stored, as well as an activity log that logs events such as when a new device token has been added and registered, or when a message has been sent to a registered device. 

You can also add users to your AirNotifier server, so multiple people can create and manage push notifications for different applications.

AirNotifier also has a broadcast feature where messages can be sent to all registered devices – this can be particularly useful when you want to send any urgent notifications.

The interface also features tabs for tokens and logs. The list of tokens will let you view the registered devices, whereas the logs will show when a token is registered, or deleted, or when a notification has been sent to a registered token.

Access Keys

Access keys in AirNotifier allow your sites to access AirNotifier. Multiple access keys can be created for an application, and configured with different permissions. These permissions include adding or removing device tokens, and sending notifications and broadcasts to the registered devices.

Getting started with AirNotifier

Once you’ve followed the installation steps outlined on Airnotifier’s GitHub, setting up push notifications will be a pretty straightforward experience. AirNotifier’s simple user interface makes it effortless to navigate through, so the next few steps should be easy enough to digest. 

First, we want to create a new application in AirNotifier. The sidebar on the left of the web interface will have a + Create button – clicking this will allow you to create a new app by entering the app’s short name and optionally, a description of the app. Don’t forget to save!

Once the application is created, several options will be displayed on the interface for configuration. Feel free to explore the different features and get familiar with the application interface. 

At the top, there are a few tabs for SettingsAccess keysTokens, etc.

The next step would be to create an access key so your mobile application and site can access AirNotifier. Click on the Create access key button, this will be where you set the details of the key (like a description of what the key does) and the different permissions (like whether or not you want to enable send notifications and the broadcast feature).

The access key will be generated – this key is what you’ll use when you want to send a request to AirNotifier (for example, when registering a device token, or sending a notification to a registered device).

You can make as many access keys as you like! This is a useful feature as sometimes you’d want to have different permissions for different applications. For example, you’d want to provide an access key that allows only the creation and deletion of a token – this would be used in mobile applications as devices would need to register its token to AirNotifier. On the other hand, an access key that only allows for sending notifications or broadcasts can be set in a site or backend.

Now that we’ve set up the AirNotifier application and access key(s), we can move on to setting up AirNotifier so that it can communicate with push notification services like Apple Push Notifications Service (APNs) and Firebase Cloud Messaging (FCM). This is important to set up as AirNotifier cannot directly push notifications to iOS and Android devices.

Dependencies

As outlined above, AirNotifier cannot directly send push notifications to iOS and Android devices. Instead, it needs to communicate with APNs and FCM so that the platforms’ devices can receive notifications. 

Under the Settings tab of your AirNotifier application, there should be several configuration settings for Apple’s APNs, Google’s FCM and Windows’ WNS.

To configure APNs for iOS, the Development Push Notification certificate and private key should be uploaded to AirNotifier.

The process for setting up Google’s FCM is pretty straightforward as well. For FCM, the Project ID and JSON key should be available in the Firebase app project settings (accessed through the Firebase console). This should be pasted to AirNotifier’s FCM fields (shown in the image below).

The installation guides on AirNotifier’s GitHub go into more detail on how to add the APNs/FCM settings. For iOS applications, Apple has some documentation on configuring remote notification support, whereas for Android applications, Firebase has a few guides on how to setup Cloud Messaging. These details relate more to the development of the mobile app rather than the AirNotifier setup, and assuming you’re already developing a mobile application with push notification functionality, APNs/FCM should already be included in the codebase.

Sending notifications

AirNotifier acts as a gateway between your site and APNs/FCM – communication is done through REST APIs. When you’re ready to send notifications to your devices and mobile applications, you would just need to implement a way to send POST requests to AirNotifier, along with the message we want to include in the notification. 

AirNotifier’s GitHub on its API outlines several different requests (for example, sending notifications, adding a device token, and deleting an existing device token) that can be implemented in the mobile application’s and site’s code. 

Custom options for sending notifications (like scheduling) would need to be implemented in the codebase as well – users should remember that AirNotifier can only perform simple actions and more complex functionality should be added on top of AirNotifier’s services. 

Workflow of AirNotifier

  1. Configure the APNs/FCM settings in the AirNotifier web interface. If the settings are properly configured, AirNotifier should now be able to communicate with APNs/FCM.

2. When the app is first launched, the app registers itself to APNs or FCM. APNs/FCM generates a device token and returns this to the app, where it is stored for later use. At this point, the app has the device token, and APNs/FCM can communicate with the app.

 So AirNotifier is able to communicate with APNs/FCM, and APNs/FCM is able to communicate with the app. If AirNotifier wants to send a push notification to the app, it would not be possible as of now due to AirNotifier not knowing who to send the message to (it needs a device token for this). The next few steps outline this process.

3. The app should have an access key for AirNotifier – either this is hardcoded in the app, or the app can get the key from the site database/server (the latter option would be more efficient in case the access key changes). At this point, the app has the device token and access key stored.

4. With the access key, the app can now send and register its device token to AirNotifier (this is sent through a POST request from the app). With the token now registered, AirNotifier should now know where to send the message.

5. When a site needs to send push notifications to a mobile application, the site would have to communicate with AirNotifier (by sending a POST request), and in turn AirNotifier sends the message to APNs/FCM for it to be processed and sent out to the mobile applications.

Conclusion

In conclusion, AirNotifier allows you to send push notifications to mobile devices with very minimal setup. 

Of course, there is the option of just having the site communicate with APNs and FCM directly instead of having to go through AirNotifier, but this would force you to do more work in order to integrate, update, and handle push notifications directly from the site. With AirNotifier, the site simply needs to connect with the push notification server, and AirNotifier handles the rest. 

AirNotifier is definitely an option to consider if you want to implement push notifications that are simple and straightforward.

anintro1

How to install AirNotifier with Docker

AirNotifier

AirNotifier is a great tool for software development teams. It provides a ready-made, easy-to-integrate way to send real time notifications to a range of different platforms.

Most notably, it integrates with both of the major push notification services (APNs and FCM), meaning that you don’t need to write this code yourself. This will free up your team to work on core features, while giving you confidence that your integration code was written by push-notification experts and tested in production by hundreds of other teams.

The Missing Piece

One of the biggest attractions of AirNotifier is that it gives you all of these great features for free. While they do charge for hosting, they also give you the option to self-host. If, like me, you prefer to host on your own infrastructure, AirNotifier is completely free.

That said, the main complaint that I hear about AirNotifier is its lack of documentation. This was the main reason behind our recent article, “AirNotifier: A How-To Guide for Beginners”. If you are interested in finding out more about AirNotifier’s features and how to get started, I strongly encourage you to read that article.

Without good documentation, setting up AirNotifier on your own infrastructure can take a bit of research. So, as a follow-on to our How-To Guide, I decided to write a quick-and-easy deployment guide.

Let’s Dive In

As is true for most cloud software, the easiest way to deploy AirNotifier is with Docker. At Tyne Solutions, we love Docker. Deploying AirNotifier with Docker can reduce deployment time to a matter of minutes. It becomes even easier if someone is nice enough to supply you with a ready-made Docker Compose file. So, that is exactly what we are going to do.

Step 1: Install Docker.

Installing Docker is a very straight-forward process, but the steps differ depending on your operating system. So, instead of giving you step-by-step instructions for our preferred OS, I encourage you to check out the instructions on Docker Docs (https://docs.docker.com/get-docker/). They have very detailed guides for a wide range of operating systems.

Step 2: Install Docker Compose.

Docker Compose is a separate tool that you can install on top of Docker. It enables you to manage deployments through the use of YAML files, giving you repeatable, self-documented deployments.

The installation steps for Docker Compose also differ depending on your operating system. Thankfully, Docker Docs has us covered here too. You can find installation instructions for a range of operating systems here, https://docs.docker.com/compose/install/.

Step 3: Install AirNotifier

We tried to find an existing AirNotifier image of Docker Hub, but the only images we could find were either out-dated, undocumented, or used a modified version of AirNotifier. So, we decided to create our own image and make it available to the public. Our image uses AirNotifier v2, with no modifications. You can find it here, https://hub.docker.com/r/tynesolutions/airnotifier.

Using Docker Compose, deploying this image is almost effortless. Add a new file to your server and call it docker-compose.yml. Then, add the following contents and save the file:

version: “3”

services:

  mongodb:

    container_name: mongodb

    image: mongo:latest

    ports:

      – 27017:27017

    environment:

      – MONGO_DATA_DIR=/data/db

      – MONGO_LOG_DIR=/tmp/mongo/mongo.log

    volumes:

      – ./mongo/data:/data/db

      – ./mongo/log:/tmp/mongo

    command: mongod –logpath=/dev/null # –quiet

  airnotifier:

    container_name: airnotifier

    image: tynesolutions/airnotifier:2

    links:

      – mongodb

    depends_on:

      – mongodb

    volumes:

      – ./certs:/var/airnotifier/pemdir

      – ./logs:/var/log/airnotifier

    ports:

      – 8801:8801

    environment:

      – MONGO_SERVER=mongodb

      – MONGO_PORT=27017

Once saved, open your terminal, navigate to the directory where you saved the file, and run “docker-compose up -d”.

Step 4: Start using AirNotifier

That’s all there is to it.

You now have AirNotifier running at http://your_server_ip_address:8801.