---
title: Why iOS Stops Sending Background Location Updates
description: iOS suspends most apps shortly after they go to the background. Learn why background location updates stop on iOS and how to keep them arriving.
date:
  created: 2026-09-25
  updated: 2026-09-25
authors:
  - robingenz
categories:
  - Capacitor
  - Guides
  - SDKs
links:
  - Capacitor Background Geolocation: sdks/capacitor/background-geolocation.md
faq: true
---

# Why iOS Stops Sending Background Location Updates

Your app records a clean track while it is on screen, then goes quiet a few minutes after the phone goes into a pocket, with no crash and no error in the log. iOS suspends most apps shortly after they move to the background, and location updates keep arriving only for apps that ask to keep running and are configured so that the system does not pause them. This post covers the documented reasons background location updates stop on iOS, from the `location` background mode and the two authorization levels to automatic pausing, reduced accuracy and termination, and maps each one to an option of the [Capacitor Background Geolocation plugin](../../sdks/capacitor/background-geolocation.md).

<!-- more -->

<div class="capawesome-z29o10a">
  <a href="https://capawesome.io/" target="_blank">
    <img alt="Build and deploy your Capacitor app with Capawesome Cloud" src="https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
  </a>
</div>

**Key takeaways:**

- iOS suspends most apps shortly after they move to the background, enqueues their location updates, and delivers them the next time the app runs.
- Continuous background delivery needs the `location` background mode in `Info.plist` and a start while the app is in the foreground; Apple documents that starting from the background fails.
- When In Use authorization keeps working in the background; Always only decides whether iOS relaunches a terminated app, and only for significant-change, visits and region monitoring.
- Core Location may pause updates on its own, and for a When In Use app that pause ends location access until the next launch; the plugin's `iosPausesAutomatically` option defaults to `false`.
- An Apple employee confirmed on the developer forums in March 2023 that since iOS 16.4, apps calling both `startUpdatingLocation()` and `startMonitoringSignificantLocationChanges()` with low accuracy and distance filtering may be suspended.
- The `positionChange` event fires only while the web view is alive, so a silent listener says nothing about whether positions were recorded.

## What iOS suspends

iOS stops background location updates after a few minutes because it suspends the app itself, not because the location session failed. Apple states the rule in its guide on [handling location updates in the background](https://developer.apple.com/documentation/corelocation/handling-location-updates-in-the-background){:target="_blank"}:

> On some Apple devices, the operating system preserves battery life by suspending the execution of background apps. For example, on iOS, iPadOS, and watchOS, the system suspends the execution of most apps shortly after they move to the background. In this suspended state, apps don't run and don't receive location updates from the system. Instead, the system enqueues location updates and delivers them when the app runs again, either in the foreground or background. If your app needs updates in a more timely manner, you can ask the system to not suspend your app while location services are active.

Nothing in that paragraph describes Core Location failing. The session stays registered, the process stops being scheduled, and the updates pile up until the app runs again. Asking the system not to suspend the app while location services are active is what the rest of this post is about.

From JavaScript the symptom is thinner than the cause. The [`positionChange`](../../sdks/capacitor/background-geolocation.md#addlistenerpositionchange-) listener stops firing while [`isWatching()`](../../sdks/capacitor/background-geolocation.md#iswatching) still resolves to `true` the next time you can call it, because the watch session never ended. The plugin documentation puts the boundary on the event itself: it "is only delivered while the web view is alive". A quiet listener is therefore evidence about the web view, not about the location session, which is why the two are worth separating before changing any option.

## The location background mode

The `location` background mode is the declaration that asks iOS to keep the app running while location services are active. It is an `Info.plist` key rather than an entitlement, and the [Capacitor Background Geolocation plugin](../../sdks/capacitor/background-geolocation.md) documents it as the prerequisite for background delivery: "On iOS, position updates are delivered while the app is in the background if the `location` background mode is enabled in the app." To install the plugin, refer to the [Installation](../../sdks/capacitor/background-geolocation.md#installation) section of the plugin documentation; it is part of the [Capawesome Insiders](../../insiders/index.md) subscription and ships from the Capawesome npm registry.

Add the key to the `Info.plist` file of your app:

```xml
<key>UIBackgroundModes</key>
<array>
  <string>location</string>
</array>
```

The Core Location property behind this mode is [`allowsBackgroundLocationUpdates`](https://developer.apple.com/documentation/corelocation/cllocationmanager/allowsbackgroundlocationupdates){:target="_blank"}. Apple describes the pairing in one direction only: apps that receive location updates in the background must include the `UIBackgroundModes` key with the `location` value, and the property may only be set to `true` once that key exists. Doing it the other way round is fatal, in Apple's own words: "Setting the value to true but omitting the `UIBackgroundModes` key and `location` value in your app's `Info.plist` file is a fatal error that terminates the app."

The second half of the rule decides where you start the session. Apple ties the guarantee to the foreground: "When the value of this property is true and you start location updates while the app is in the foreground, Core Location configures the system to keep the app running to receive continuous background location updates", and those updates "continue even if the app subsequently enters the background". Going the other way does not work at all: [`requestWhenInUseAuthorization()`](https://developer.apple.com/documentation/corelocation/cllocationmanager/requestwheninuseauthorization()){:target="_blank"} states that "attempts to start location updates while your app runs in the background will fail". For the plugin, that means calling [`startWatching(...)`](../../sdks/capacitor/background-geolocation.md#startwatching) from a foreground moment, such as app start, a button tap or a resume handler, and never from a silent push handler or a background task.

## Authorization level

Always authorization is not what keeps updates flowing while the app is in the background. Apple's article on [requesting authorization to use location services](https://developer.apple.com/documentation/corelocation/requesting-authorization-to-use-location-services){:target="_blank"} is explicit about it:

> On iOS, an app is in use when it's in the foreground and for a short time when it transitions from the foreground to the background. If you enable background location updates, an app with When in Use authorization continues to run in the background when location services are active; if location services aren't running, the normal suspension rules apply. If the system terminates the app or the app isn't running, the system doesn't launch an app with When in Use authorization to deliver new updates; it does launch an app with Always authorization for some types of location updates.

What Always adds is relaunch. In Apple's own comparison table, the row "Launches a terminated app automatically" reads "No. The user must launch the app." for When In Use, and "Yes for significant location change, visits, and region monitoring services; no for others" for Always. Standard location updates fall into the "no for others" group at either level.

The background permission is still worth requesting, and the plugin says why: "Without the `backgroundLocation` permission, the watch session keeps working but position updates may be suspended while the app is in the background." Both platforms require two separate prompts for it, and the announcement post walks through [the two-step permission flow](./announcing-the-capacitor-background-geolocation-plugin.md#request-permissions-in-two-steps) with [`requestPermissions(...)`](../../sdks/capacitor/background-geolocation.md#requestpermissions).

Two answers to the first prompt quietly break the second step. If the user picks "Allow Once", Apple documents that Core Location ignores further `requestAlwaysAuthorization()` calls because the authorization is temporary, and that this temporary When In Use authorization "expires when the app is no longer in use, reverting to Not Determined status". If the app asks for Always straight from Not Determined, Core Location uses two prompts, and answering the first with "Allow While Using App" grants a provisional Always: the second prompt "displays when Core Location prepares to deliver an event to your app requiring `CLAuthorizationStatus.authorizedAlways`", and Apple notes it "will typically display the second prompt when your app isn't running". [`checkPermissions()`](../../sdks/capacitor/background-geolocation.md#checkpermissions) reports the four standard `PermissionState` values, none of which expresses a provisional state, so this one is invisible from JavaScript. When a user is stuck in either case, [`openSettings()`](../../sdks/capacitor/background-geolocation.md#opensettings) is the way out.

## Automatic pausing

Core Location may pause location updates on its own when the device is unlikely to move, and on supported platforms that behavior is on by default: [`pausesLocationUpdatesAutomatically`](https://developer.apple.com/documentation/corelocation/cllocationmanager/pauseslocationupdatesautomatically){:target="_blank"} defaults to `true`. The plugin ships the opposite default. Its `iosPausesAutomatically` option is `false`, which makes pausing something you opt into.

Apple's own Important callout on that property explains what the default costs an app that never upgraded to Always:

> For apps that have in-use authorization, a pause to location updates ends access to location changes until the app launches again and is able to restart those updates. To prevent location updates from stopping entirely, consider disabling this property and changing location accuracy to kCLLocationAccuracyThreeKilometers when your app moves to the background.

Core Location does not resume by itself either. Apple puts the restart on the app ("After a pause occurs, it's your responsibility to restart location services again when you determine that they're needed") and suggests a local notification to get the user to reopen the app. The plugin's FAQ describes the same trade-off in its own terms: the system "only resumes the position updates once the device has moved significantly again, so a watch session can stay silent for a long time", and `isWatching()` keeps returning `true` throughout.

The pause decision takes a hint from the activity. The Core Location property behind the `iosActivityType` option is [`activityType`](https://developer.apple.com/documentation/corelocation/cllocationmanager/activitytype){:target="_blank"}, which Apple describes as "a cue to determine when the system may pause location updates". Three of the five values the plugin exposes map to [`CLActivityType`](https://developer.apple.com/documentation/corelocation/clactivitytype){:target="_blank"} cases that Apple documents with an explicit pause note: `AutomotiveNavigation` ("might cause the system to pause location updates when the vehicle doesn't move for an extended period of time"), `Fitness` and `OtherNavigation`. `Other`, the default on both sides, carries no such note. `Fitness` carries a second documented effect on top of the pause note, because Apple states that "when activityType is CLActivityType.fitness, the system disables indoor positioning". A courier app that picks `Fitness` because couriers walk has told iOS it may stop tracking whenever a courier stands still.

All three iOS options fit in one call, here at their defaults:

```typescript
import { Accuracy, ActivityType, BackgroundGeolocation } from '@capawesome-team/capacitor-background-geolocation';

const startWatching = async () => {
  await BackgroundGeolocation.startWatching({
    accuracy: Accuracy.High,
    distanceFilter: 10,
    iosActivityType: ActivityType.Other,
    iosPausesAutomatically: false,
    iosShowBackgroundIndicator: true,
    androidNotification: {
      title: 'Location Tracking',
      text: 'Your location is being tracked.',
    },
  });
};
```

## Stationary devices and filters

A device that does not move produces few position updates, by design in both Core Location and the plugin. The Core Location property behind the `distanceFilter` option carries the same name and the same meaning, "the minimum distance in meters the device must move horizontally before an update event is generated", but not the same default: Core Location uses `kCLDistanceFilterNone` and reports every movement, while the plugin defaults to `10` meters. Plugin version 0.2.0 raised that default from `0`, because a stationary device "previously filled the queue with about `86400` duplicates per day on Android".

Cadence is not yours to set on iOS at all. The `androidInterval` option is Android-only, and the plugin spells out the asymmetry: "iOS has no equivalent option: the operating system decides how often it reports a position, which is far less often while the device is stationary." Minute-long gaps in the trace of a parked car are the system saving power, and no plugin option shortens them.

Reduced accuracy is the other reason positions arrive far apart. When the user grants approximate instead of precise location, Apple states that changes to [`desiredAccuracy`](https://developer.apple.com/documentation/corelocation/cllocationmanager/desiredaccuracy){:target="_blank"} "have no effect", and that the [approximate location](https://developer.apple.com/documentation/corelocation/kcllocationaccuracyreduced){:target="_blank"} is delivered "at most a few times per hour" and is "usually within 1–20 kilometers of the actual location". No `accuracy` value in the plugin overrides that. [`requestTemporaryFullAccuracy(...)`](../../sdks/capacitor/background-geolocation.md#requesttemporaryfullaccuracy) asks for full accuracy for the duration of the app session, and it needs a matching entry under the `NSLocationTemporaryUsageDescriptionDictionary` key in `Info.plist` to work.

## The iOS 16.4 report

One behavior change from 2023 still turns up in bug reports, and its only source is a reply by an Apple employee on the Apple Developer Forums, posted on 2023-03-30 in the thread [Background location updates stop in iOS 16.4](https://developer.apple.com/forums/thread/726945){:target="_blank"}. The reply opens with the trigger:

> Beginning in iOS 16.4, apps calling both startUpdatingLocation() AND startMonitoringSignificantLocationChanges() may get suspended in the background if they are specifying low accuracy and distance filtering in the location manager settings.

Read the condition as written, because every part of it has to hold: both services started, a low accuracy, and distance filtering. It is not a blanket change to background location on iOS 16.4, the reply names no time interval, and it does not call the behavior a bug.

The same reply lists what to do about it. For apps that need continuous high-accuracy updates in the background, it names three settings together: `allowsBackgroundLocationUpdates` set to true, `distanceFilter` unset or set to `kCLDistanceFilterNone`, and a `desiredAccuracy` of `kCLLocationAccuracyHundredMeters` or better. It then offers one setting as an alternative on its own, `showsBackgroundLocationIndicator` set to true, "which will avoid the issue". Apps that only need accuracy in the kilometer range are pointed at `startMonitoringSignificantLocationChanges()` instead.

Apple never wrote any of this down outside that thread. The [iOS and iPadOS 16.4 release notes](https://developer.apple.com/documentation/ios-ipados-release-notes/ios-ipados-16_4-release-notes){:target="_blank"} contain no Core Location section, and neither do the 16.5, 16.6 and 17.0 notes. Other vendors still changed their defaults over it. The [changelog of Transistorsoft's competing Capacitor plugin](https://github.com/transistorsoft/capacitor-background-geolocation/blob/master/CHANGELOG.md){:target="_blank"} records that version 4.12.0 (2023-05-04) flipped its `showsBackgroundLocationIndicator` default to `true`, describing iOS 16.4 as "a major change to location-services, exposed only when `Config.showsBackgroundLocationIndicator` is `false` (the default)".

The plugin's `iosShowBackgroundIndicator` option also defaults to `true`, where the Core Location property behind it, [`showsBackgroundLocationIndicator`](https://developer.apple.com/documentation/corelocation/cllocationmanager/showsbackgroundlocationindicator){:target="_blank"}, defaults to `false`. That matches the alternative remedy above, and the plugin documentation gives no reason for the default, so treat it as a fact about defaults rather than a statement about internals. The rule to take from the thread applies to native code you own: if a custom plugin or an `AppDelegate` in your project starts both location services with a low accuracy and a distance filter, that is the combination to change.

## Terminated apps

Termination is the one stop that no option undoes. When the user swipes the app away, the watch session ends, and the plugin treats that as the operating system restriction it is; the announcement post covers [what works in the background and what doesn't](./announcing-the-capacitor-background-geolocation-plugin.md#what-works-in-the-background-and-what-doesnt) in detail, including the gap that cannot be backfilled.

Apple's current documentation describes relaunch by authorization level rather than by how the app was closed, in the comparison table quoted above: no automatic relaunch for When In Use, and for Always only "significant location change, visits, and region monitoring services". If your app has to react to movement while it is not running, region monitoring is the path, which is the job of the [Capacitor Geofences plugin](../../sdks/capacitor/geofences.md). [Announcing the Capacitor Geofences Plugin](./announcing-the-capacitor-geofences-plugin.md) shows how the two run side by side, and [Why Are Your Geofences Not Triggering on iOS?](./why-are-your-geofences-not-triggering-on-ios.md) covers the iOS rules for region monitoring.

The system also terminates apps on its own under memory pressure, and Apple's guidance is to restart the services on the next launch: "If your app actively receives and processes location updates and terminates, it should restart those APIs upon launch in order to continue receiving updates. When you start those services, the system resumes the delivery of queued location updates." For the plugin, that means calling `startWatching(...)` again at app start. The configuration survives without you, since [`setConfig(...)`](../../sdks/capacitor/background-geolocation.md#setconfig) "is persisted natively so that it keeps working when the operating system wakes your app without a web view".

Background App Refresh cuts deeper than any of the above. Apple's archived Location and Maps Programming Guide states that while Background App Refresh is off for an app, "your app won't receive significant-change or region monitoring events even when it's in the foreground", and that the system does not relaunch the app for any location event. The guide sits in Apple's documentation archive and was last updated in 2016, but the switch is still there in the Settings app, and it is worth checking on a device that reports no events at all.

## Updates that never stopped

The most common version of "updates stopped" is a reporting gap rather than a tracking gap. The web view is suspended along with the rest of the app, so no JavaScript runs and no listener fires, while the native session keeps recording. The plugin documentation states the consequence for the `positionChange` event directly: it "is only delivered while the web view is alive. If the queue is enabled, treat the queue as the single source of truth instead."

Turning the queue on is a single call to `setConfig(...)`, for example `setConfig({ maxSize: 50000 })`, after which every position of a watch session is written to a native SQLite database. When the app is in the foreground again, read it with [`getQueuedPositions(...)`](../../sdks/capacitor/background-geolocation.md#getqueuedpositions) and acknowledge each page with [`deleteQueuedPositions(...)`](../../sdks/capacitor/background-geolocation.md#deletequeuedpositions):

```typescript
import { BackgroundGeolocation } from '@capawesome-team/capacitor-background-geolocation';

const drainQueue = async () => {
  let hasMore = true;
  while (hasMore) {
    const result = await BackgroundGeolocation.getQueuedPositions({ limit: 1000 });
    if (!result.positions.length) {
      break;
    }
    await persist(result.positions);
    await BackgroundGeolocation.deleteQueuedPositions({
      upToId: result.positions[result.positions.length - 1].id,
    });
    hasMore = result.hasMore;
  }
};
```

[`getQueueStatus()`](../../sdks/capacitor/background-geolocation.md#getqueuestatus) reports `pendingCount`, `droppedCount` and `lastUploadedAt`, which is enough to tell a suspended web view from a stopped session. The announcement post covers [the queue in full](./announcing-the-capacitor-background-geolocation-plugin.md#the-queue-nothing-gets-lost), from sizing to the HTTP upload.

That gives you a debugging order. Drain the queue before touching any option: if the positions are in it, the native session ran the whole time and the bug is in the JavaScript layer. If the queue has a hole matching the silence, the sections above tell you which rule the app broke.

## Troubleshooting checklist

Each row below maps a symptom to the cause explained earlier in this post and to the setting that changes it.

| Symptom | Cause | Fix |
|---|---|---|
| Updates stop a few minutes after the app is backgrounded, every time | The app is suspended because the `location` background mode is missing | Add `UIBackgroundModes` with the `location` value to `Info.plist` |
| Foreground tracking works, background tracking never starts | The session was started while the app was already in the background | Call `startWatching(...)` from the foreground |
| Background updates are unreliable, `backgroundLocation` was never granted | Only the in-use permission exists, so updates may be suspended in the background | Request `backgroundLocation` in a separate second call |
| The permission prompt was answered once and background access never came back | "Allow Once" grants temporary When In Use, which expires and reverts to Not Determined | Request again in the foreground, or send the user to `openSettings()` |
| `checkPermissions()` reports `granted` but background events still stop | Provisional Always, with the deferred second prompt unanswered | Nothing to read in JavaScript; verify the level in the iOS Settings app |
| Long silences that end once the user moves again | Core Location paused the updates and only resumes after significant movement | Leave `iosPausesAutomatically` at `false` |
| Updates stop whenever the vehicle or the user stops moving | `iosActivityType` is set to `AutomotiveNavigation`, `Fitness` or `OtherNavigation` | Use `ActivityType.Other` unless the activity matches |
| Fewer positions than expected while the device stands still | `distanceFilter` plus the cadence iOS picks for a stationary device | Lower `distanceFilter`; iOS has no interval option |
| Coarse positions a few times per hour, whatever `accuracy` is set to | The user granted reduced accuracy, so `desiredAccuracy` has no effect | `requestTemporaryFullAccuracy(...)` plus the `Info.plist` dictionary entry |
| Everything stops after the user swipes the app away | The app was terminated, and standard location updates never relaunch it | Cover relaunch with the Capacitor Geofences plugin |
| Tracking stops after hours in the background without user action | The system terminated the app under memory pressure | Call `startWatching(...)` at every app start and drain the queue |
| No significant-change or region events at all, foreground included | Background App Refresh is off for the app or globally | Check it in the iOS Settings app |

## FAQ

### Why does iOS stop background location updates after a few minutes?

Because iOS suspends the app. Apple documents that the system suspends the execution of most apps shortly after they move to the background, enqueues their location updates, and delivers them when the app runs again. An app keeps running for location only when it declares the `location` background mode and starts location updates while it is in the foreground.

### Does When In Use authorization work for background location on iOS?

Yes. Apple states that an app with When In Use authorization "continues to run in the background when location services are active" once background location updates are enabled. What Always adds is relaunch after termination, and only for significant-change, visits and region monitoring. For a session started in the foreground, the two authorization levels behave the same.

### What is `allowsBackgroundLocationUpdates`?

It is the Core Location property that configures the system to keep an app running for continuous background location updates. Apple requires the `UIBackgroundModes` key with the `location` value in `Info.plist` first, and setting the property without that key "is a fatal error that terminates the app". Its default is `false`, and with `false` updates "may or may not continue in the background depending on other factors".

### Why does the blue status-bar indicator appear?

iOS shows the blue bar or pill while an app uses location services in the background, and tapping it returns to the app. For apps with When In Use authorization the system shows it regardless of any setting; for apps with Always authorization the `showsBackgroundLocationIndicator` property decides, and its Core Location default is `false`. The plugin's `iosShowBackgroundIndicator` option defaults to `true`.

### Did iOS 16.4 change background location?

An Apple employee confirmed on the Apple Developer Forums in March 2023 that beginning in iOS 16.4, apps calling both `startUpdatingLocation()` and `startMonitoringSignificantLocationChanges()` may get suspended in the background when they specify low accuracy and distance filtering. Apple never listed the change in a release note. The same reply names the remedies, including `showsBackgroundLocationIndicator` set to true as an alternative to the other three.

### Why does `isWatching()` return `true` while no positions arrive?

Because a watch session is registered. `isWatching()` reports whether a session exists, not whether the system is currently delivering updates, and the plugin documentation states that it keeps returning `true` while iOS has paused the position updates. The same holds while the app is suspended in the background.

### Does the Capacitor Background Geolocation plugin require a paid plan?

Yes. It is part of the [Capawesome Insiders](../../insiders/index.md) subscription, which covers every Insiders plugin, and it is published to the Capawesome npm registry. See the [Installation](../../sdks/capacitor/background-geolocation.md#installation) section of the plugin documentation for the setup.

## Stay in the loop

Platform findings like the iOS 16.4 thread above, along with new Insiders plugins and releases, go out in the Capawesome newsletter first.

[Subscribe to the Capawesome Newsletter](https://capawesome.io/newsletter/){ .md-button .md-button--primary }

## Conclusion

Work the list in order the next time a track has a hole in it: `location` in `UIBackgroundModes`, [`startWatching(...)`](../../sdks/capacitor/background-geolocation.md#startwatching) called while the app is on screen, `iosPausesAutomatically` left at `false` until battery numbers say otherwise, and the queue enabled so the next silence is a question you can answer from recorded data instead of a listener that was asleep. For the rest of the plugin, from the permission flow to the HTTP upload contract, see [Announcing the Capacitor Background Geolocation Plugin](./announcing-the-capacitor-background-geolocation-plugin.md).

If you have any questions, join us on the [Capawesome Discord server](https://discord.gg/VCXxSVjefW){:target="_blank"}. To stay updated on the latest news, subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/){:target="_blank"}.
