Articles · App ExamplesUpdated September 2026

You can add background sync to an app, but you do not get to choose when it runs.

Yes, you can add background sync to an app. Both platforms ship an API for it: BGTaskScheduler on iOS, WorkManager on Android. Neither promises to run your code at a time you pick. So the version that survives real phones is a queue on the device that drains whenever the system wakes you. Treat it as part of mobile app offline sync, not as a timer.

Below: what each platform guarantees, the 15 minute floor on Android, how to build a queue that survives a wake that never comes, and when a silent push or a plain pull to refresh beats background sync outright.

See which trigger your app needs

The short version

The system decides when you run, so the queue has to be the plan.

Both platforms treat the ability to sync data in a background app as something they grant, not something you book. iOS will not start a task before the date you ask for, and promises nothing about starting it then. Android periodic work has a 15 minute floor, and the run time depends on your constraints and on the system.

That points at one design on both. Write every change to a local queue the instant it happens. Drain that queue on any execution you get, including app launch. Make every operation safe to repeat. Background refresh is then a bonus that makes the app feel fresher, not the thing it depends on.

On iOS the earliest begin date is a floor, not an appointment

iOS gives you BGTaskScheduler and two shapes of work. An app refresh task is the short one, for small updates such as the latest stock values, and it needs the fetch background capability. A processing task is longer, for work that runs for minutes. You register a handler at launch and submit a request. The system then launches your app in the background when it is ready.

The sentence that matters lives in the request. An earliest begin date tells the system the task should not start before then. Apple's documentation then says plainly that the system does not guarantee launching the task at that date, only that it will not begin sooner. Nothing sets an upper bound. A person can also switch background refresh off for your app. An execution is a gift, not a booking.

That changes the useful question. Stop asking how often the app will sync. Start asking what it costs if the app does not sync at all today. If somebody just sees an old number, ship it. If a payment, a message or a signature goes missing, background refresh is the wrong mechanism. That write has to leave the device another way.

Apple, BGTaskRequest earliestBeginDate

On Android 15 minutes is the floor and the ceiling is open

Android's recommended answer for work that must continue after the user leaves the app is WorkManager. You describe the work and attach constraints such as network type or charging, and the library persists it across process death and reboots. A one time request runs once. A periodic request repeats, and that is the one people want for a sync loop.

The documented limit is that the minimum repeat interval you can define is 15 minutes, matching the JobScheduler API underneath. That interval is a minimum gap between repetitions, not a schedule. The exact time the worker runs depends on the constraints you attached and on optimisations the system performs. A flex period narrows the window: ask for the last 15 minutes of each hour rather than the top of it. It is still not a promise.

Two louder options exist when a task genuinely cannot wait. Mark the work expedited, so the system prioritises running it soon. Or run a foreground service, which the user can see and which has its own restrictions on when an app may start one. Both cost more battery than a queue that drains later. It is the same trade that runs through offline app functionality: the app should be useful before the sync lands, not because of it.

Android, define your WorkManager work requests

Build the queue, not the timer

An offline queue sync is four decisions, and none of them is about scheduling. Where pending operations live. What makes an operation safe to repeat. What happens when the same record changed on both sides. And what the user sees while a change is still waiting.

Put the queue somewhere that survives the app being killed, which means a local database table rather than component state. Give every operation an id made on the device and send it with the request. A retry after a timeout then updates the same record instead of writing a second one. Back off between retries: a device that woke for 30 seconds of network will otherwise spend that window failing.

Conflicts are the part people postpone. Last write wins is a real policy rather than a failure to pick one, and for plenty of apps it is correct. It stops being correct the moment two people edit the same thing. Resolution then belongs on the server, where both versions exist. That is a different build, and it starts at the server side of a sync.

Then show the pending state on screen. A queued row should look queued, and a failed upload should say so rather than retry in silence. The complaint people file is never that a sync was slow. It is that the app said saved and the change was gone by morning.

Push, pull to refresh, or a background task

Most apps asking for background refresh mobile behaviour do not need it. If the data only matters while somebody is looking at it, a fetch on launch plus pull to refresh is fresher than any background task. It runs at the moment freshness counts, and it is the cheapest thing on this page to build.

Background sync earns its place when data ages while the app is closed and the user expects it current the instant they open it. A delivery status, a shift roster, a feed. And when the server already knows something changed, a silent push tells the device at the right moment instead of guessing. Push with a background task as the backstop is where most production apps land.

The cost is real on both sides. Every extra wake costs battery, which users notice and blame on your app. Each mechanism is also more code to test in conditions you cannot reproduce at a desk. Weigh it like any other app performance call, and measure what stale data costs someone first.

Try it

Which trigger does your app actually need

Three questions about the data, none of them about the API. First: how current must it be when the user opens the app?

Fetch on launch, plus pull to refresh. No background task needed.

Read only sync, so a missed wake costs freshness and nothing else.

How each way of getting fresh data behaves

ApproachRuns with the app closedYou control the timingNeeds server supportBest for
Pull to refreshNoYesNodata on screen right now
Fetch on launchNoat launchNoalmost every app
Periodic background taskYesNoNocontent that can be hours old
Silent pushYesthe server picksYeschanges only the server knows
Offline write queuedrains at the next wakeNoYesedits made with no signal

Building it into an app you own

Background sync is not a feature you bolt on at the end. It decides where your data lives, whether your API accepts a repeated write safely, and what a list screen renders while something is pending. Retrofitting it into an app that assumed a live network is usually a rewrite of the data layer.

Newly is an AI app builder. You describe the app in plain English and it writes a real React Native and Expo project you own. It runs on a cloud iPhone or Android simulator while it builds, then ships to TestFlight and to Google Play internal testing. It is $25 a month, with no free plan. Code comes out as a ZIP or through two way GitHub sync from the Deploy tab, which matters here: background task setup is exactly what you will want to read by hand. It does not ship a backend, so the server half is your choice.

So write the offline behaviour into the description alongside the screens. A driver marks a stop complete with no signal and it uploads later is a specification. Add sync is not. That gap is the difference between an app that survives a tunnel and one that loses an afternoon.

Questions people ask about background sync

Yes, within limits. iOS runs registered background tasks when it decides to. Android WorkManager runs periodic work on a minimum 15 minute interval, at a time the system picks. Both run your code with the app closed. Neither runs it at a moment you specify, so build for a wake that may not arrive.

Describe what your app does with no signal

Write down the one action somebody must take offline, and what should happen to it an hour later. Build the data layer around that sentence.

Start building