iOS 26.5 SIGKILLs audio-recording app at ~50s of background despite UIBackgroundModes: audio - what is the supported API path?

Hi, hoping for guidance on what's a long-running bug for our app.

The problem

We have a transcription app on iPhone 17 Pro Max running iOS 26.5. Recording flow uses AVAudioEngine.installTap(onBus:) to capture PCM into a JS bridge for streaming to a remote transcription service. A parallel AVAudioRecorder writes the same audio to disk as backup.

When the user starts a recording and locks the phone, iOS terminates our process with SIGKILL at approximately 50 seconds of continuous background time, despite:

  • UIBackgroundModes includes audio (verified in shipping IPA's Info.plist)
  • AVAudioSession.setCategory(.playAndRecord, mode: .default) is active
  • AVAudioEngine is running with installTap producing PCM buffers right up to the moment of death
  • UIApplication.backgroundTimeRemaining returns Double.greatestFiniteMagnitude at applicationDidEnterBackground (verified in our event log)

No AVAudioSession.interruptionNotification is delivered before the kill. iOS terminates the process cleanly with no warning event to our observer.

Evidence

Our Swift observer module writes an event log to disk on every system event. On relaunch we ship it to our crash reporter. Excerpt from a recent kill on iOS 26.5 / build 2.1.32:

T=0.000s    session-start (engineRunning: true)
T=57.199s   app-will-resign-active (bufferCallbackCount: 22)
T=58.913s   app-did-enter-background (backgroundTimeRemaining: infinity, bufferCallbackCount: 39)
            [no further audio events captured]
            [Swift heartbeat written every 5s for next ~46 seconds]
T~105s      Process SIGKILLed (heartbeat last-alive: 09:31:01.597Z)

Background time before kill: ~46 seconds. engineRunning: true and bufferCallbackCount was still incrementing at the moment the event log stops capturing - the audio engine was alive and feeding buffers when iOS terminated us.

What we've tried (35 documented attempts)

Hopefully not all relevant but listing for completeness:

  • Various AVAudioSession category/mode/options combinations (Default, Measurement, VoiceChat, .mixWithOthers, .defaultToSpeaker, .allowBluetoothHFP)
  • Parallel AVAudioRecorder writing a .caf file as a "real recording app" signal
  • SFSpeechRecognizer with requiresOnDeviceRecognition = true consuming PCM in-process (50s request rotation)
  • BGContinuedProcessingTask with Progress.completedUnitCount reporting monotonic progress every 5 seconds
  • Live Activity (ActivityKit) with NSSupportsLiveActivitiesFrequentUpdates = true
  • Live Activity update pushes via APNs (confirmed wake widget extension only, not host)
  • Silent device-token APNs background pushes (confirmed iOS ~5/day rate limit)
  • CallKit fake call (CXProvider + CXCallController) - works but creates the green pill UI which our product can't ship
  • WebRTC peer connection with active media stream (via react-native-webrtc loopback)
  • UIBackgroundModes: voip declaration (without CallKit)
  • beginBackgroundTask + engine bounce (Apple's own guidance says don't, our test confirmed it's actively harmful)
  • CLLocationManager background updates

All die at ~50s background. None of them survive.

What works on the same device

Three App Store transcription apps survive indefinite background recording on our exact device + iOS version. We have inspected their IPAs (Mach-O LC_LOAD_DYLIB analysis + embedded entitlement extraction):

Otter (com.aisense.otter) - UIBackgroundModes: audio + fetch + processing + remote-notification. Uses OneSignal-driven Live Activity push tokens + NotificationServiceExtension. No CallKit, PushKit, or WebRTC.

Granola (com.granola.ios-prod) - has UIBackgroundModes: voip but the voip is for their separate outbound-phone-call feature (TwilioVoice + CallKit, lives in their PhoneCalls.framework). Recording-path uses ONLY AVAudioRecorder + PlayAndRecord + ModeDefault + Live Activity with frequentPushesEnabled. Zero PushKit anywhere in the bundle.

Transcribe Speech to Text by DENIVIP (ru.denivip.transcribe) - the smallest API surface: UIBackgroundModes: audio + remote-notification only. AVAudioEngine + .playAndRecord + .default + SFSpeechRecognizer consuming PCM. No CallKit, PushKit, BGTask, Live Activity, WebRTC, or VoIP.

Three apps, three different mechanisms, all working. We've implemented bits of all three approaches in our app and still die at 50s.

Apple Voice Memos (system app, private entitlements) also survives indefinite recording on the same device.

Questions

  1. What is the supported API path for indefinite background microphone-only recording on iOS 26.5? Voice Memos and competitor apps clearly accomplish this - what's the missing piece?

  2. Why does UIApplication.backgroundTimeRemaining return Double.greatestFiniteMagnitude at applicationDidEnterBackground but the process is terminated ~50 seconds later? Is the meaning of this property changing in iOS 26?

  3. What causes the iOS 26 process scheduler to revoke the audio-mode background runtime classification? No AVAudioSession.interruptionNotification is delivered before SIGKILL. Where can we observe the classification change?

  4. Does iOS 26 distinguish "audio recording with no audible output" from "audio recording with audible output (e.g. a media playback session)"? If so, what is the supported API to register as a recording-only background-audio app?

  5. Does BGContinuedProcessingTask (new in iOS 26) actually extend background CPU time for an app that is also using UIBackgroundModes: audio and an active AVAudioSession? Or is it for finish-what-you-started bursts only (per WWDC 2025 session 227)?

Any guidance - even pointers to specific WWDC sessions, sample code, or technotes - would be hugely appreciated. We've spent ~40+ hours on this and want to know what the supported path looks like in iOS 26.

Happy to share more event-log data, IPA inspection notes, or build a focused Xcode reproduction if helpful.

Thanks!

So, this is the most critical detail to focus on:

When the user starts a recording and locks the phone, iOS terminates our process with SIGKILL at approximately 50 seconds of continuous background time.

I'm not sure why the system terminated your app, but I am confident that the crash log provides at least some guidance on the cause and that the system console provides a more in-depth description of the cause. That means your next steps here are:

  1. Looking at the crash log the system generated, particularly the top-level header that includes the exception code and "reason". You can post the full crash log here as well, but the top-level header is what's most useful.

  2. If you look at the system log at the time your app is terminated, you can see the process that kills your app play out across our daemons. The termination itself was probably done by "runningboardd" and would have included some context data about what/who/why the termination occurred. You can also trace backward from that point in time, as whatever initiated the termination would have logged as well. If you find those log messages and are having trouble understanding them, please post the log messages back here.

Covering some of your other comments and questions:

  • UIBackgroundModes includes audio (verified in shipping IPA's Info.plist)
  • AVAudioSession.setCategory(.playAndRecord, mode: .default) is active

That's the configuration I'd recommend for what you're trying to do, assuming you also need to play audio (otherwise you could use record only).

  • CallKit fake call (CXProvider + CXCallController) - works but creates the green pill UI which our product can't ship

This works, but it's not really a relevant/useful comparison. In terms of policy, you’re not a VoIP app, so you can't use CallKit. Similarly, on the technical side, CallKit uses a specialized process to activate its audio session (this is how it's able to activate recording from the background), which is completely different than the standard activation process. That means it's not useful for understanding standard audio API behavior.

HOWEVER, that also means that this:

All die at ~50s background. None of them survive.

I'll also note that the time of "50s" isn't a standard system "time".

  1. What is the supported API path for indefinite background microphone-only recording on iOS 26.5? Voice Memos and competitor apps clearly accomplish this - what's the missing piece?

The basic requirements are:

  1. Have the "audio" background category.
  2. ONLY activate your audio session in the foreground.

That last point can be tricky as many of our higher-level APIs do their own session activation/deactivation. Don't use those APIs.

Why does UIApplication.backgroundTimeRemaining return Double.greatestFiniteMagnitude at applicationDidEnterBackground?

Because your app has the "audio" background category and an active audio session, which means it's allowed to stay active indefinitely (as long as its session is active).

but the process is terminated ~50 seconds later?

Assuming your audio session stayed active, then I don't think the audio system triggered your termination.

Is the meaning of this property changing in iOS 26?

No.

What causes the iOS 26 process scheduler to revoke the audio-mode background runtime classification?

Unless your audio session deactivated, the system wouldn't have ended your process assertion.

No AVAudioSession.interruptionNotification is delivered before SIGKILL. Where can we observe the classification change?

I'm not convinced the audio system triggered your termination, but the system log will tell you everything that happened.

Does iOS 26 distinguish "audio recording with no audible output" from "audio recording with audible output (e.g. a media playback session)"?

No.

Does BGContinuedProcessingTask (new in iOS 26) actually extend background CPU time for an app that is also using UIBackgroundModes: audio and an active AVAudioSession?

It would, but that doesn't really matter. The "audio" background category is all that you need to keep your app active, though you could use BGContinuedProcessingTask if that provided some other useful benefit to your app.

Or is it for finish-what-you-started bursts only (per WWDC 2025 session 227)?

Yes, that's what it's generally "for".

Any guidance - even pointers to specific WWDC sessions, sample code, or technotes - would be hugely appreciated.

Many of our sample projects that record audio also include the "audio" background category. I just tested "Capturing stereo audio from built-in microphones" and it worked fine in the background on my test device.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

iOS 26.5 SIGKILLs audio-recording app at ~50s of background despite UIBackgroundModes: audio - what is the supported API path?
 
 
Q