Load testing a notification hub - push-notification

I have a requirement to deliver push notifications to an app that runs on iOS and Android, with approximately 2 million installations in total. I've built a PoC using Azure Notification Hubs. This works fine tested against a handful of phones / tablets I could borrow. I've also tried the same with Amazon's SNS and that worked well too.
I have no reason to believe that hubs wouldn't scale as I need it to but I wondered if there was any provision for load testing. I can't borrow 2m phones but maybe I could configure a hub to call a service I host, thereby simulating a push to either the GCM or APNS gateways? This would help build confidence in my end-to-end performance / volume testing.

I believe this is not supported. If there is a load testing capability, it's internal to Azure and not offered for public use.
However, Microsoft does provide an SLA for the Basic and Standard tiers of Notification Hubs. They claim they use the Notification Hubs service to deliver things like the Breaking News alerts for the Bing News apps. The SLA guarantees 99.9% successful message delivery within five minutes (over a month).
The Service Bus SLA (which covers Notification Hubs) is here: http://www.microsoft.com/en-us/download/details.aspx?id=4767
I could not find SLAs for GCM or APNS.
Notification Hubs do provide a fairly rich reporting API, that you can query with OData filters to determine how many notifications are sent over given periods of time.
But I expect that the variable load conditions that affect the service as a whole will mean that no specific promise is made about the specific timeliness of any delivery (within the five-minute guaranteed delivery time). In other words, all of your 2 million notifications might be delivered within fifteen seconds, or it might take 4 minutes to send the first message, with all of them delivered at 4.9 minutes, depending on who else is using the service and how heavily they are using it.

Related

How will a popular project handle rate-limit for topic subscriptions per project?

Introduction
So from the official firebase docs. It states there that:
The frequency of new subscriptions is rate-limited per project. If you send too many subscription requests in a short period of time, FCM servers will respond with a 429 RESOURCE_EXHAUSTED ("quota exceeded") response. Retry with exponential backoff.
The topic subscription add/remove rate is limited to 3,000 QPS per project.
qps = queries per second.
Now here's the thing. It says "per project". What if an app gets very popular and thousands of users open the app at the same time then click a button that subscribes to a topic or unsubscribe?
Wouldn't hitting the rate limit 3000 queries per second highly possible?
Here's my real question
Does firebase_messaging's subscribeToTopic(..) and unsubscribeFromTopic(..) methods automatically handle retries? (referring to "Retry with exponential backoff" above)
If not, then how would a very popular app handle topic subscriptions from a massive number of users?
Because the plugin does not provide any documentation about this.
Coming from a different platform (Android) for your question on subscribeToTopic() retry?, but possibly both function similarly. On Android it returns a Task where in Flutter it returns Future (Task = Future for Flutter if I understood that correctly), which I presume is a hint that Google gave the responsibility for the retries to the developers.
I'm not sure what your looking for as an answer. The correct way is to implement an exponential backoff as mentioned in the docs. Depending on your use-case, different strategies can be implemented.
e.g. forced subscription -- like a general topic, that runs every app start is easy. One-off subscriptions, you might need some verifications i.e. a way to check if the user actually finished subscribing, retry if not.

Throttle messaging in Firebase

We have 1M+ devices registered. Is there a way to limit how quickly the messages get delivered? Obviously it's real hard to scale if 1M+ notifications at the exact same time cause a massive spike of traffic to your backend. Would be great if instead of all the messages getting delivered immediately to all devices, you could make it only send X messages per second.
The best way to control the delivery of those message is actually by calling FCM with the token IDs yourself, preferably with the batched delivery feature from the legacy API (look for the registration_ids parameter there). You can scale this up to as many calls to the API as you need to deliver your message to all devices.
Using topics is also possible, but you lose control of the delivery performance since the fan-out happens in a process you don't control.
Alternatively: consider sending a data message that contains a timestamp on when it should be displayed. That way you separate the delivery time from the display time, removing the critical path (but of course introducing other considerations).

Firebase analytics dispatch period

I would like to use Firebase for analytics on iOS and Android app. My users are most of the time in remote area with poor or no network. I would like to optimize battery life so I don't want firebase to create web requests all the time. Is there a way to dispatch data only on command ?
I would like to have the same behaviour than google analytics with the analytics.setLocalDispatchPeriod(0); and send data only when the user is connected to wifi for example.
The SDK already tries to minimize the upload interval times to one per hour to avoid draining battery. If there is any problem with the network, it won't retry immediately but in hours later or back-off if needed. It also has several methods to optimize data latency so it won't be good to freely control the scheduling system.

Delegating Tasks for Mission Critical Application

I'm working on a mission critical application.
The application fetches Stock Market data from different stock markets like NYSE, NASDAQ, etc. using third party service.
Customers can come to the application and add their Portfolio (which company's shares they have).
And then set Alerts. eg. Notify me when AAPL price goes above $xxx on NASDAQ. when MSFT price goes below $zzz on NYSE.
I've a cron job that fetches market data from third party service for all the tickers users have added (AAPL, GOOG, MSFT, etc...) every 1 min.
After I get the data, I fetch all the alerts that users have created and then send them notification via Email, SMS, Pushover, Twitter, Facebook Message, etc. Also add that notification to app's database so user can see it in App when they log in.
Now since this is time intensive application, failure to fetch data may result in big loss since customers are paying for the time critical data.
Currently, I'm pushing all the notification sending part to Queue. Worker (on my server) sends notification.
Are there any other better ways to delegate as much work as possible to third party servers?
Would you recommend using Iron.io worker so it does the job of sending the notifications as well.
And may be also fetching data from the market.
Thanks!
Architecturally there are a number of approaches but it sounds as if you're making the right choices. Using a queue to decouple the producer from the notification process makes sense. This enables a more proper SOA architecture where you can change/update/evolve various parts of the app independently without worrying too much about tightly coupled code.
That said, your question is specifically around offloading to third parties. There are third parties that can abstract the notification part out of your code. I'm not super familiar with them but there are many options: PubNub, Pusher, Twilio, SendGrid, Mailgun, AWS SNS, etc.
I work for Iron.io. We have many customers doing exactly what you're trying to accomplish: creating workers that become little mini-services and calling them from either push events, scheduled tasks, or on-demand. This frees you up from having to deal with the queuing, routing, scheduling, and worker/background server capacity.
We're happy to help you architect things right from the beginning, just reach out to support#iron.io.

Can I export my Urban Airship push device tokens?

I'm evaluating Urban Airship as a push solution and I was wondering if it's possible to export my device tokens should I decide to stop using their service?
I've noticed they have an API endpoint to download device data (http://docs.urbanairship.com/reference/api/v3/device_information.html#device-token-list-api) but I was wondering if anyone actually went through the process of switching their push solution from UA to an internal solution (i.e. run my own push server and ping old users).
Thank you!
I'm not sure if there is an API call for it, but you could go to Audience->device tokens, and make a script to fetch all of them.
In the company I work, we decided on a different approach.
All communication with Urban Airships goes through our own backend, where we at the same time store the devicetokens sent from the device. That way we can shift to another way of sending push notifications without modifying our apps. It is of course a bit more time consuming to do the initial development. On the other hand, if you go for the solution you are currently considering, the switch to you own implementation (or another push provider) will properly require several migrations, or at least maintaining two different ways of sending push notification for a considerable time.
BTW:we have been using UA for almost 3 years, and have been very happy with their service.

Resources