Minimum achievable latency for ending a Live Activity after app force-kill via APNs push-to-end

Context

I'm building a study-timer feature for an iOS app (Flutter + native ActivityKit) that displays a Live Activity on the Lock Screen / Dynamic Island while a session is running. When the user force-quits the app by swiping it up from the App Switcher, I want the Live Activity to disappear as quickly as possible.

I have already confirmed (from on-device testing and Apple Developer Forums thread 732418) that:

  1. applicationWillTerminate is not called on swipe-up force-kill, only on OS-initiated termination or crash. So synchronous Activity.end(...) from the app itself is not a solution for the force-kill path.
  2. Shortening staleDate does not visually dismiss the Live Activity once the app process is gone — the Widget Extension keeps rendering the last fresh snapshot and there is no body-reevaluation trigger on the stale transition post-app-death. (I implemented and verified this, then rolled it back.)
  3. The only Apple-official reliable mechanism is APNs push-to-end (Activity.request(pushType: .token) + server sends event: end via APNs).

Current architecture

I have APNs push-to-end working end-to-end. Structure:

  • Client: Activity.request(pushType: .token), subscribe to Activity.pushTokenUpdates, forward each new token to the backend.
  • Backend: On every client heartbeat, upsert (user_id, la_apns_token, la_activity_id, last_heartbeat) into Postgres. A separate scheduler polls for rows whose last_heartbeat < now() - grace_ttl and sends APNs event: end to the stored token.

Parameters I am currently running with:

ParameterValue
Client heartbeat interval60 s
Orphan grace TTL (server)135 s (heartbeat × 2.25, to absorb network jitter)
Scheduler poll interval30 s

The observation

End-to-end latency from "user force-kills the app" to "Live Activity disappears from Lock Screen" is:

  • Worst case: 60 + 135 + 30 = ~225 s (~3.75 min)
  • Typical: ~3 min (as consistently measured on iOS 26.4.1, iPhone 17 Pro Max)
  • Theoretical minimum (if the kill happens exactly at a heartbeat boundary): ~135 s

Users perceive 3 minutes as broken — the timer clearly stopped (no ticking), but the Live Activity "ghost" is still visible on the Lock Screen.

My question

Is there any Apple-supported mechanism to reliably tear down a Live Activity faster than ~2 minutes after the owning app's process is gone, given that applicationWillTerminate does not fire on swipe-kill?

Specifically:

  1. Is there any practical lower bound below ~60 s for this scenario using the current ActivityKit + APNs model, assuming we are not willing to spam heartbeats every few seconds? I can push heartbeat to 20–30 s, but the server cost grows linearly with active sessions.

  2. Does BGAppRefreshTask / BGProcessingTask have any documented lifecycle hook that fires on user-initiated swipe-kill specifically, so that I could do a "last-heartbeat flush" just before the process dies? My understanding is that background tasks are scheduled for later and do not fire synchronously at termination.

  3. Is there any signal from APNs/ActivityKit to my server (e.g. a feedback-service-like mechanism) that indicates "this Live Activity's owning app was force-killed", which would let the server short-circuit the heartbeat-based orphan detection?

  4. Are there any new APIs in iOS 18.x or the upcoming release that address this specific force-kill → LA-dismissal latency? I could not find anything in the 18.x release notes, but I may have missed it.

What I am NOT asking

  • I am not asking how to implement APNs push-to-end (that works).
  • I am not asking about applicationWillTerminate (I already confirmed it does not fire on swipe-kill).
  • I am not asking about shortening staleDate as a visual workaround (I already verified it does not trigger body reevaluation post-kill).

Environment

  • iOS 26.4.1 (also reproducible on 18.x devices I have on hand)
  • iPhone 17 Pro Max, iPhone 15 Pro, iPad Air 11-inch (M3)
  • Xcode 26.x
  • Activity.request(pushType: .token) with ActivityContent + custom stalenessInterval = 120s
  • APNs HTTP/2 via token auth (.p8), targeting api.push.apple.com in production
  • apns-push-type: liveactivity, apns-priority: 10, payload includes event: end

What I have tried (for the record, to avoid "did you try" responses)

  • applicationWillTerminate with DispatchSemaphore 3.5 s sync wait + dismissalPolicy: .immediate — works only for OS-terminate, not swipe-kill.
  • stalenessInterval = 30s + 15 s refresh cadence + override to 5 s on AppLifecycleState.paused — verified not to dismiss the LA after app death.
  • Cold-start reconciliation via Activity<...>.activities on next app launch — works, but that only helps if the user relaunches.
  • Current APNs push-to-end with 60 s / 135 s / 30 s configuration — works, but latency is the complaint.

Any guidance, even "no, ~2 minutes is the floor by design" with a pointer to the relevant doc, would be very helpful. Thank you.

Minimum achievable latency for ending a Live Activity after app force-kill via APNs push-to-end
 
 
Q