Designing APIs for Mobile Clients: Bandwidth, Latency, and Offline
APIs designed for desktop web clients on reliable broadband do not perform well on mobile without deliberate adaptation. Mobile clients operate under constraints that server-side developers often underestimate: variable and often poor network conditions, limited battery budgets where every radio transmission costs energy, smaller screens that need different data shapes than desktop, and the expectation of usable offline states that desktop web apps rarely require. Building an API that serves mobile clients well requires understanding these constraints and making design decisions that account for them.
The Network Is Unreliable
Mobile networks are not just slower than wired networks — they are fundamentally less reliable. Connections drop mid-request. Latency spikes to hundreds or thousands of milliseconds without warning. A user enters a tunnel, an elevator, or a dead zone, and requests fail. The API and the client must both be designed to handle this gracefully.
On the API side: keep responses small. Every unnecessary field in a response is bytes that must transit an unreliable mobile network. Compress all text responses. Use efficient serialization. Support partial content ranges for large responses that might need to be resumed.
On the client side: every API call must handle failure gracefully. Not “show an error and stop,” but “enqueue the failed operation, retry when connectivity returns, deconflict with any state changes that occurred during the failure.” This is harder to build than happy-path behavior, and the API must be designed to support it — idempotency keys for retryable writes, consistent response shapes that are safe to cache and replay.
The reliable-request assumption that most server-side developers work under — send a request, receive a response — is not available to mobile clients. Design the API’s error handling and retry contract with this in mind.
Minimize Request Count
Every HTTP request on a mobile network incurs costs beyond the data transfer: the radio wake-up from idle state (tens to hundreds of milliseconds on LTE), the TCP handshake, TLS negotiation, and the request-response round trip. On a poor connection, ten small requests are significantly worse than one larger request, even if the total data is similar.
This argues for response shapes that are richer than a minimal REST design would produce — returning related data alongside the primary resource rather than requiring the client to make secondary requests. A mobile client rendering a user profile might need the user’s recent activity, their follower count, and their subscription status alongside the basic profile fields. Returning all of this in a single response is more expensive on the server (more data to fetch and serialize) and more efficient on the mobile client (one network round trip instead of four).
Composite endpoints or GraphQL-style field selection allow mobile clients to request exactly the data they need for a given screen in a single request. This is a case where the mobile client’s needs diverge from the minimal REST ideal, and accommodating that divergence is worth the design complexity.
Batch APIs serve mobile clients well in contexts where multiple operations are naturally grouped — syncing offline actions, loading the initial state for a new session, refreshing multiple feed components. A single batch request replaces multiple individual requests, reducing the round-trip count that mobile clients cannot afford to accumulate.
Bandwidth-Aware Response Design
Pagination defaults that are appropriate for web clients may be wrong for mobile. A desktop web client scrolling an infinite list might request 50 items per page. A mobile client on a 3G connection might need 20 items to render the initial screen and load more on scroll — fetching 50 upfront wastes bandwidth and delays the initial render.
Allow clients to specify page size within a reasonable range, and recommend mobile-appropriate defaults in documentation. Do not make mobile clients use the same default page size as web clients.
Consider image handling explicitly. A product image appropriate for a desktop retina display (2000px × 2000px, 400KB) is unnecessarily large for a mobile list view (100px × 100px). APIs that serve media should support size or quality parameters that allow mobile clients to request appropriately scaled assets:
GET /products/123/image?width=200&format=webp
WebP achieves better compression than JPEG for photographic content at equivalent quality, reducing bandwidth for mobile clients that support it. Most modern mobile browsers and native clients support WebP.
Delta Sync and Efficient State Refresh
Mobile clients frequently need to refresh their local state from the server — after returning from background, after recovering from offline, after a timed refresh interval. A naive refresh fetches everything from scratch: pull all resources, replace local state. This is bandwidth-intensive and slow.
Delta sync returns only what has changed since the client’s last sync. The client sends a since timestamp or a sync token representing its last known state. The server returns only records created, modified, or deleted since that point:
GET /items?modified_since=2026-05-01T10:00:00Z
{
"items": [...changed items...],
"deleted_ids": ["item_abc", "item_def"],
"sync_token": "tok_f4e8b2d1",
"has_more": false
}
The sync_token is an opaque value the client stores and sends on the next sync, replacing the raw timestamp. This allows the server to change its internal representation of the sync cursor without breaking clients.
Deleted records must be explicitly communicated — a client cannot infer deletion from absence if it is only receiving changed records. The deleted_ids array (or a deletions array for richer metadata) tells the client which local records to remove.
Offline Support and Conflict Resolution
Mobile clients that support offline operation allow users to continue working — creating records, modifying data — without a network connection. When connectivity returns, the client syncs accumulated changes to the server. This requires the API to handle writes that may conflict with server-side changes that occurred during the offline period.
Optimistic concurrency control (using ETags or version numbers, covered elsewhere) handles the detection of conflicts: the server rejects a write that would overwrite newer server-side changes and returns a conflict response. The client must handle this: merge if possible, prompt the user for resolution if not.
For write-heavy offline workflows, idempotency keys allow the client to safely replay queued writes after a failed sync without duplicating operations. The server treats a retried write with the same idempotency key as the original, returning the original result rather than executing again.
The API design implications: every mutable resource needs some form of version tracking. Conflict responses must be distinct from other error types and must include the current server state so the client can merge. Deletions must be communicated in delta syncs so offline clients do not attempt to modify records that no longer exist.
Battery and Radio Efficiency
Radio hardware on mobile devices is a significant power consumer. An app that keeps the radio awake with frequent API polls drains the battery faster than one that batches its network activity. The API should support efficient patterns: delta sync instead of full refresh, webhooks or push notifications instead of polling, long-lived connections (WebSockets or SSE) where real-time updates justify the cost.
Batch API calls where possible. Five requests sent sequentially keep the radio busy longer than five requests batched into one call that returns combined results. The radio can sleep between batch syncs; it cannot sleep between sequential individual requests.
Where push notification infrastructure is available, prefer pushing state changes to mobile clients over having them poll. A push notification that triggers a targeted delta sync is dramatically more battery-efficient than continuous polling. The API’s role in this is providing an efficient sync endpoint that retrieves only what has changed since the notification was received.
Mobile-aware API design is not a separate API — it is a set of additional capabilities (delta sync, field filtering, compression, idempotent retries, conflict resolution) added to the same API that web clients use. The web client ignores features it does not need. The mobile client uses the features that make its experience reliable. Building these capabilities in from the start is significantly less costly than retrofitting them after mobile clients have shipped into production with the constraints they impose.