But recently, I found some disordered VoIP notifications. My VoIP app received the StopRing push before the StartRing push.
Do you know what was happening on the device? It's possible there is a push level issue involved here, but I can also see why this could happen under very "normal" conditions.
Notice the odd discrepancy in timing:
Then we can see the StartRing send first, but received in the app after the StopRing. The StartRing took about 6s to send and the StopRing took about 1s.
The pushes were sent 5s apart.
// receive StopRing
2026-04-0909:54:48.858
// receive StartRing
2026-04-0909:54:49.524
...but were delivered ~2/3 of a second from each other. You are actually thinking about the question here the wrong way— the question isn't just "why did stop arrive before start", it's "how did they end up arriving so close to each other".
I suspect what started this is that the device was actually offline at the point the original push was sent, then came back online shortly after the stop push was queued. So, the starting point here is that both pushes reach the device at roughly the same time, when the device came back online.
At that point, a few different factors come into play.
To start with, APNS priority is really about overall "management" at the network level, not absolute priority at the individual push level. That is, if you submit a VoIP push and a standard push "at the same time", which one will ACTUALLY reach the device first isn't formally defined. They're both moving through the APNS infrastructure and trying to micromanage push ordering would be both expensive (in CPU time) and probably end up slowing everything down for no real benefit.
Similarly, when pushes are queued, we don't necessarily try and sort the queue pushes to ensure they're in the "right" order. I don't actually know what order we deliver the push back log, but there's a decent chance we intentionally deliver newer pushes "first", under the theory that it's more important that recent pushes get processed vs. older.
Next, there's going to be some kind of variation between standard push delivery and VoIP push delivery— they're both moving through separate daemon's, so they aren't going to have exactly the same performance.
That leads to the final and likely most important factor, which is what actually happened within your app. In particular:
-
Was your app running when the pushes arrived?
-
Where EXACTLY did you receive the push notification, and when do you initialize PKPushRegistry?
Those points are critical because it's fairly easy to unintentionally create EXACTLY the kind of time gap you're seeing. All you need to do is:
a) Use an "early" delegate like application(_:didFinishLaunchingWithOptions:) or application(_:didReceiveRemoteNotification:) to receive your push.
b) Set up PKPushRegistry object relatively "late", for example, as part of your early interface bring-up.
A configuration like that then sets up the following situation:
-
Both pushes arrive and are processed,
-
The APNS notification is queued for delivery but the app NOT woken or launched.
-
callservicesd receives the VoIP push and launches your app.
-
Your app launches and receives the APNS push in an early delegate.
-
Your app continues initializing (for 2/3 of a second?).
-
Your app creates its PKPushRegistry and receives the VoIP push.
Which brings me back to my first question... what was happening on the device?
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware