Background Fetch: What It Is, How It Works, and Update Configuration

Author: IT Sectr Published: 2026-03-27 Reading time: 8 min

Background Fetch is an iOS mechanism that periodically wakes an app in the background to download fresh content. The system analyzes user behavior and selects optimal windows for updates. According to Apple, 2026, the app gets 30 to 120 seconds to perform the operation, after which the system suspends or terminates the process.

Key Takeaways

  • Background Fetch is an iOS API for periodic content updates in the background.
  • The system controls the wake frequency based on user behavior analysis.
  • The minimum interval is set via UIApplication.minimumBackgroundFetchInterval.
  • Deprecation — since iOS 13+, the mechanism is considered legacy; BGTaskScheduler is recommended.
  • Execution time — up to 30 seconds, after which the system forcibly terminates the task.

What is Background Fetch in iOS?

Background Fetch is an iOS API that allows an app to periodically receive fresh data in the background. First introduced in iOS 7 along with the Background App Refresh mechanism. The main goal is to keep content up to date by the time the user opens the app, eliminating the need to wait for loading.

Difference from Push Notifications

Push notifications are server-initiated — the server sends a signal to the device, and the system decides whether to wake the app. Background Fetch is initiated by iOS itself based on device usage patterns. Push is better suited for urgent messages, while Fetch is for scheduled content updates (news, social media feed).

Place in the Background Task Ecosystem

Background Fetch is one of several background execution mechanisms in iOS. BGAppRefreshTask (iOS 13+) performs the same task but with more flexible scheduling. Background Modes (audio, location) are for continuous operations. Silent Push is server-initiated updates. Fetch remains relevant for projects supporting iOS 12 and below.

  • Background Fetch — periodic, system-initiated, iOS 7+.
  • BGAppRefreshTask — periodic, system-initiated, iOS 13+.
  • BGProcessingTask — long-running tasks, iOS 13+.
  • Silent Push — server-initiated, iOS 7+.

How Does Background Fetch Work: Architecture and Lifecycle

iOS uses a machine learning algorithm to determine the optimal time to wake the app. The system analyzes when the user typically opens the app, how long they use it, and how often they return. Based on this data, iOS calculates windows for Background Fetch.

Task Execution Process

When the system decides to wake the app, it calls the application(_:performFetchWithCompletionHandler:) method in AppDelegate. The app should load a minimal amount of new data and call the completion handler with one of three statuses: .newData (data loaded), .noData (no new data), or .failed (error). The status affects the frequency of future wake-ups.

Impact of Completion Handler on Call Frequency

The .newData status tells the system that the update was useful — iOS may increase the wake frequency. .noData indicates there is no data — the frequency stays the same or decreases. .failed signals a problem — the system reduces frequency to save battery. The emphasis should be on an honest status, not on forcing .newData.

StatusMeaningImpact
.newDataData successfully loadedFrequency may increase
.noDataCheck returned no new dataFrequency stays the same
.failedNetwork or server errorFrequency decreases

Setting Up Background Fetch in an Xcode Project

To enable Background Fetch, two steps are required: activate the capability in Xcode and set the minimum interval in code. The capability is located in Target — Signing & Capabilities — Background Modes — check the Background Fetch box. Without this step, the system will not wake the app.

Setting the Minimum Interval

The UIApplication.shared.setMinimumBackgroundFetchInterval method sets the minimum time in seconds between Fetch calls. The value UIApplication.backgroundFetchIntervalMinimum (approximately 15 minutes) tells the system to wake the app as often as energy-efficient. Setting the interval in application(_:didFinishLaunchingWithOptions:) is standard practice.

swift
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey : Any]?
)-> Bool {
    UIApplication.shared.setMinimumBackgroundFetchInterval(
        UIApplication.backgroundFetchIntervalMinimum
    )
    return true
}

Info.plist and Capability

When Background Fetch is enabled in Xcode, it automatically updates Info.plist — adding the UIBackgroundModes key with the fetch value. This is a mandatory step: without it, the app will not receive the performFetchWithCompletionHandler call. You can verify this via P list Source or Build Settings.

Background Fetch Code Examples in Swift

Let’s look at a complete Background Fetch implementation for a news app. The implementation includes data loading, caching, and calling the completion handler. The code runs in AppDelegate — the only place where the system calls fetch.

swift
func application(
    _ application: UIApplication,
    performFetchWithCompletionHandler handler: @escaping (UIBackgroundFetchResult) -> Void
) {
    let url = URL(string: "https://api.example.com/latest")!

    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data, error == nil else {
            handler(.failed)
            return
        }

        do {
            let articles = try JSONDecoder().decode([Article].self, from: data)
            cacheArticles(articles)
            handler(articles.isEmpty ? .noData : .newData)
        } catch {
            handler(.failed)
        }
    }.resume()
}

Caching Loaded Data

After loading data via Background Fetch, it needs to be saved to local storage — CoreData, UserDefaults, or File Manager. By the time the app opens, the data should already be available. Use CoreData with a background context for thread-safe writing. After saving, update the UI on the main thread.

swift
func cacheArticles(_ articles: [Article]) {
    let container = NSPersistentContainer(name: "AppModel")
    container.performBackgroundTask { context in
        articles.forEach { article in
            let entity = ArticleEntity(context: context)
            entity.id = Int64(article.id)
            entity.title = article.title
            entity.body = article.body
        }
        try? context.save()
    }
}

Testing Background Fetch

For testing, use Simulator — select Debug — Simulate Background Fetch in Xcode. On a physical device, you need to wait for the system to decide to perform a fetch. To speed things up, you can set the minimum interval to 1 minute, but the system may still ignore it when the battery is low.

Limitations and Pitfalls

Background Fetch has several limitations that are important to consider when designing the app architecture. The main one is that the system fully controls the call frequency, and the developer cannot guarantee it. Even with a set minimum interval, the system may not call fetch for hours.

Execution Time Limit

The system allocates limited time for the app to execute the task — typically up to 30 seconds. If the app does not call the completion handler within that time, the system forcibly terminates the process and reduces the frequency of future wake-ups. All network requests should be compact — no more than 1-2 per call.

Battery Dependency

iOS takes the battery level into account when scheduling Background Fetch. When the charge is below 20%, the wake frequency decreases. When Low Power Mode is enabled, the system may completely disable background updates for all apps. The user can also disable Background App Refresh for a specific app in Settings.

Network Limitations

URLSession initiated from Background Fetch runs in standard mode — without background session support. For large downloads, use URLSession with background configuration. The system will continue the download even after the fetch completes, but progress will not be tracked until the next wake-up.

Migrating from Background Fetch to BGTaskScheduler

Starting with iOS 13, Apple recommends BGTaskScheduler as a replacement for Background Fetch. BGTaskScheduler provides more flexible scheduling, two task types (refresh and processing), and task registration with identifiers. Migration involves several steps and is recommended for all new projects.

Step-by-Step Migration

The first step is to define task identifiers in Info.plist using the BGTaskSchedulerPermittedIdentifiers key. The second is to register tasks in AppDelegate via BGTaskScheduler.shared.register. The third is to replace the performFetchWithCompletionHandler call with the handler passed to register. The fourth is to call submit to schedule the task.

swift
// Before (Background Fetch)
UIApplication.shared.setMinimumBackgroundFetchInterval(
    UIApplication.backgroundFetchIntervalMinimum
)

// After migration (BGTaskScheduler)
BGTaskScheduler.shared.register(
    forTaskWithIdentifier: "com.example.refresh",
    using: nil
) { task in
    self.handleAppRefresh(task: task as! BGAppRefreshTask)
}

let request = BGAppRefreshTaskRequest(
    identifier: "com.example.refresh"
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)

Advantages of BGTaskScheduler

BGTaskScheduler provides more control: BGProcessingTask for long-running operations (up to 10 minutes), execution conditions via requiresNetworkConnectivity and requiresExternalPower, and an expiration handler for graceful termination. The system also analyzes app usage, but the developer can set more precise requirements.

When to Keep Background Fetch

If the app supports iOS 12 and below, Background Fetch remains the only option for periodic updates. BGTaskScheduler is only available from iOS 13+. In this case, use a wrapper: check availability via if #available(iOS 13, *) and call the appropriate API.

Frequently Asked Questions

How often does iOS call Background Fetch?

The exact frequency is not documented and depends on user behavior. The system analyzes how often the user opens the app and adjusts the frequency accordingly. On average, with active usage, fetch may be called 1–3 times per hour. With infrequent usage — 1–2 times per day.

Why is my Background Fetch not being called?

Check three conditions: Background Fetch capability is enabled in Xcode, minimumBackgroundFetchInterval is set, and the user has not disabled Background App Refresh for the app in Settings. Also check that the device is not in Low Power Mode and the battery level is above 20%.

What is the difference between Background Fetch and BGAppRefreshTask?

Background Fetch is the old API (iOS 7), BGAppRefreshTask is the new API (iOS 13+). BGAppRefreshTask provides more control: expiration handler, rescheduling capability, and status checking. Background Fetch is simpler to implement but less flexible. Apple recommends using BGAppRefreshTask for new projects.

Can I download large files via Background Fetch?

Not recommended. Background Fetch is time-limited (up to 30 seconds). For large downloads, use URLSession with background configuration — the system will continue the download even after the fetch completes. An alternative is BGProcessingTask (iOS 13+), which allows up to 10 minutes and charging conditions.

Does Background Fetch consume battery?

Yes, each wake-up consumes energy for powering the processor, initializing the network stack, and loading data. iOS optimizes the frequency to minimize the impact. With proper implementation — loading only new data, fast completion handler call — the battery impact is minimal.

Summary

  • Background Fetch is an iOS API for periodic background data loading, available since iOS 7 and recommended for replacement with BGTaskScheduler.
  • The system controls the call frequency by analyzing user behavior — the developer cannot guarantee the wake-up time.
  • Three completion handler statuses — .newData, .noData, .failed — affect the frequency of future app wake-ups.
  • 30-second limit — do not run long operations or multiple sequential network requests.
  • Capability is mandatory — Background Fetch in Xcode + setting minimumBackgroundFetchInterval in code.
  • BGTaskScheduler is the modern replacement from iOS 13+, providing more control and two task types.
  • For projects supporting iOS 12 and below, use Background Fetch with BGTaskScheduler availability check via if #available.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also