Our app supports large-file uploads (20 GB+) and uploads of many files. We use a background URLSession so transfers can continue if the user backgrounds the app.
In separate affected-device captures, Console logs and a sysdiagnose show dasd declining upload activities under Energy Budget Policy or Data Budget Policy. Upload tasks are created and resumed, but no bytes are transferred. Subsequent uploads can also remain queued, including after earlier uploads are cancelled and the app is relaunched.
The issue is intermittent but can persist: one device recovered after approximately 24 hours; another remained affected for several days. We have not established what causes recovery or how the relevant budget eligibility is computed or replenished.
Foreground and power observations
For the energy-budget reproduction, the user kept the app foregrounded. Application lifecycle logs and RunningBoard running-active-Visible notifications corroborate foreground/active state around the affected task creation and resume operations.
The rejection repeatedly reports:
Energy Budget Policy
[energyBudget]: Required:1.00, Observed:0.00
Decision: MNP
Battery samples were approximately 68%, with Low Power Mode off. New uploads using the same session succeeded while the device was connected to external power and were rejected again after disconnection.
Discretionary configuration versus daemon classification
Our upload-session factory does not set isDiscretionary to true. In a separate, successful reproduction, instrumentation read isDiscretionary from the actual owning URLSession.configuration at task creation:
10:35:04.234749-0500 Frame.io:
Upload task 1 created in session com.frameio.backgroundSession.diagnostics, configured isDiscretionary: false
The corresponding daemon entry was:
10:35:04.245137-0500 nsurlsessiond:
NDSession <8BA476D9-E790-46B6-B1DA-0246E14BBDAF> Task <1B16494D-BBE8-448F-9297-9DB8772ADD92>.<1> current discretionary status for com.frame.FrameIO is discretionary (opt-in: 0)
All five tasks in that successful upload showed this combination. We do not yet have the instrumented configuration readout from the failed energy-budget reproduction.
Implementation notes
Large files are split into smaller files to support resumable uploads through our backend API. Each part is submitted as a file-backed upload task through the same background session, using a stable session identifier across launches.
Goal
User-initiated uploads make progress while the app is foregrounded and the network is available, and continue when possible after backgrounding. We understand background execution is system-controlled, but need to avoid uploads remaining stalled for days with no actionable recovery.
We are considering switching between foreground and background URLsessions when the app moves between the foreground and background, but have concerns about that the bookkeeping on that path could be a brittle pattern.
We have also considered using a BGContinuedProcessingTaskRequest for the entire upload, but have concerns about running into new scheduling issues there.
Questions
What session configuration and task-submission pattern does Apple recommend for this requirement? Is a background URLSession appropriate for both foreground and background uploading, or should we use a different architecture?
Is it expected that tasks created and resumed while the app is foreground/active, with the owning session reporting isDiscretionary = false, can be blocked by Energy Budget or Data Budget Policy? If so, what supported approach allows these user-initiated uploads to progress while the app remains foregrounded?
When this restriction persists across cancellation, new uploads, and app relaunch, what supported recovery mechanism should we implement? Can the app detect the restriction and take an effective action, rather than requiring external power or waiting an unknown amount of time?
For 20 GB+ files and large upload batches split into file-backed tasks, are there recommended chunk sizes, outstanding-task limits, or session-management practices that prevent this failure mode?
If the captured foreground behavior is unexpected, is this a known OS issue with an available fix or supported workaround? What additional evidence is needed to obtain a concrete remediation?