Why CDN configuration for a mobile app breaks under peak loads
Configuring a CDN for a mobile app looks workable right up until the first peak: under steady traffic, edge nodes serve requests, response is stable, and the origin server is barely loaded.
But as soon as the number of concurrent sessions grows — evening prime time, a sale, a push notification with images — download delays do not increase smoothly but collapse: the feed stops loading further, and screens open empty.
The first failure point is caching.
When caching rules are set as one common string rather than separated by object groups (catalog images, covers, interface static assets, profile data), edge nodes treat some responses as unverifiable and go to the origin server for them every time a screen opens.
Peak load moves to the origin, and it begins responding more slowly than it would if there were no distribution at all.
The second failure point is the mobile network. A user goes into the subway, switches between networks, loses signal mid-download: an interrupted request is repeated in full instead of resuming from the point of interruption.
Each such case means extra traffic, an extra trip to the origin, and one more step toward those download delays that a person describes as “the app is slow.”
The third failure point is the objects themselves. Heavy images without adaptation to the screen, serving one file at all resolutions, and the absence of compression and bundling of small requests multiply the transfer volume several times over.
Edge nodes reduce the distance to the user, but they do not save you from sending more than necessary.
In all three scenarios, the failure points are the same: caching rules, handling interruptions, and content preparation. Let’s break down how this is addressed.
What a CDN gives an app: speed, resilience, reach
The logic of a CDN is simple: static assets — images, fonts, interface elements, video, JS bundles — are served not from the origin server but from the point of presence closest to the user.
The first request fetches the object from the origin; after that it lives in cache with a specified time to live and is served from the user's region.
The difference in response speed on long-distance routes is multiple times, not “a little faster,” because the main component of latency disappears: the packet's journey halfway around the world.
Static caching is configured by content type, not “set and forget.” Images and fonts are cached for a long time, HTML and profile data — briefly or not at all, and API responses get separate rules.
Invalidation is configured separately: on release, new asset versions get a new address rather than resetting the cache entirely across all regions.
Otherwise, after every update the app runs in a mixed state for a couple of hours — some users get the old interface, some the new one.
Resilience to peaks is the second measurable effect. A mass mailing, registration opening, live stream, or seasonal promotion creates a burst of requests that the origin server cannot handle.
Edge nodes take it on: the share of requests that get through remains at the level of an ordinary day, there are no timeout failures, and only the non-cacheable portion reaches the origin — usually a few percent of the total volume.
Offloading the server directly lowers its resource requirements and outbound traffic costs, which shrink several times over.
We work with Cloudflare and other delivery networks: the choice of provider is determined by the geography of the audience, the share of video, and protection requirements. Then come caching rules, cache-control headers, a fallback origin, and monitoring of the hit ratio. Without this, a CDN merely shifts the load rather than removing it.
Content delivery schemes and when each is appropriate
The choice of delivery scheme determines not “speed in general,” but which requests can be served without reaching the origin server. Dynamic content — a personalized feed, authorization, payment responses — cannot be cached: an error in the key serves another user's data.
Static assets and media are cached by filename with a version, and it is on them that the scheme delivers the main gain in response time and load.
| Delivery scheme | When it fits | Limitations |
|---|---|---|
| Ready-made external network | Audience across dozens of regions, static assets and media predominate, no plans to maintain your own infrastructure | Caching rules are set in the operator's panel; some region-specific settings and invalidation speed depend on its policies |
| Own nodes | Requirement to keep data in your own environment, coverage of one or two regions | Expanding geography is manual work; operations and redundancy fall on the team |
| Hybrid scheme | Static assets and media on external nodes, dynamic and private traffic through your own | Routing is more complex: configurations and rules need to be synchronized across two environments |
| Direct delivery from origin | Small audience, almost all traffic is short data requests | Latency and load grow linearly with the number of users; resilience rests entirely on the origin |
The scheme itself works only together with caching rules: a key based on the resource version, a short time to live for frequently changing content, and forced invalidation after a client release.
Without this, even a correctly chosen scheme serves outdated files — and the user sees the old screen after updating the app.
Implementation stages: from audit to handover of policies
The order of work hardly depends on the size of the app — only the depth of each step changes. We start with measurements: until there are numbers for current delivery, any change becomes a guess.
- Delivery audit. We look at what the servers serve and from where: content composition, share of repeat requests from one user, audience geography, response time on the first request and on an already warm cache. We calculate what portion of traffic is even cacheable.
- Route scheme. We separate flows: requests for user data go directly, while static assets, images, and updatable content go through distribution nodes. We describe update delivery separately so that rolling out a new version does not hit the servers.
- Cache configuration. For each content type we set its own time to live and update policy: mutable files are checked before serving, immutable ones are stored for a long time. We normalize the cache key so that copies of the same file do not multiply.
- Load testing. We run the scheme against a real traffic profile — peak bursts, slow channels, first app install. We record the cache hit ratio, response time, and system behavior when an individual node fails.
- Trialing on live traffic. We enable it gradually, on part of the audience, comparing metrics before and after. This way a mistake in the rules costs seconds of degradation, not an hour.
- Handover of policies. We provide the route map, cache rules by content type, the cache purge procedure on release, a dashboard with metrics, and an on-call instruction.
Schemes, caching rules, and documentation on delivery
After launch, the client's team is left not only with working delivery but also with a full set of artifacts by which the environment can be developed without us.
We hand over configurations to a repository, not “verbally”: a change goes through code review, is rolled back with a single revision, and staging and production environments do not diverge.
- Routing scheme — which domains serve static assets, media, and app requests, how traffic is divided between origins, and in what order it switches if one of them fails.
- Caching rules — time to live for each content class, file versioning via a hash in the name, and a list of what is not cached: personalized responses and authorization requests.
- Access policies — signed links with a limited lifetime, protection against embedding content on third-party sites, and restrictions by region and request rate to origins.
- Content release policy — the procedure for publishing a version, cache warm-up before traffic is opened, who confirms the rollout, and how the previous build is restored.
- Configuration as code — routes and rules in a repository, deployed in Cloudflare: changes go through review and do not diverge between environments.
- Metrics and alerts — cache hit ratio, serving time by region, error spikes, and thresholds after which the on-call engineer receives a notification.
- Operations manual — a map of domains and nodes, access levels, responsible parties, and the procedure for planned maintenance.
Case study: cut catalog load time by three times
The client is a home goods retail chain, Severny Dom: a catalog of 40 thousand items, iOS and Android apps.
A product card pulled both data and every image from the main environment, so during a sharp influx of users response time rose to 5–6 seconds, and every fifth download was interrupted. The origin server hit its ceiling and served images more slowly than they could be requested.
What we did as part of the implementation case
We separated traffic: static assets — product photos, banners, video reviews — were moved to the CDN, while dynamic content and personal data remained through the origin server.
We configured caching rules by object type, versioning of links to photos, and background loading of previews so that the catalog opens from an already warm cache. Delivery was tied to geo-routing: the user receives content from the point of presence closest to them.
Metrics before and after
| Metric | Before | After |
|---|---|---|
| Peak response time | 5–6 s | 1.7 s |
| Share of interrupted downloads | 19% | 6% |
| Load on origin server | 100% | 25–30% |
With a tenfold influx of users in the first minute of the sale, the catalog opened without degradation: the delivery network takes requests onto itself, and the origin server does not have to be scaled for peak load.
How static caching differs from streaming delivery
Static assets and streaming are two different contracts between the app and the edge server. Static assets are the same for everyone: the app shell, images, fonts, scripts.
They are kept at the edge with a long time to live and are reset not by a timer but by a change in filename — when a new build is released, fresh copies are pulled in immediately, while old ones live out their term without errors for users.
Personal data is structured the opposite way: the response is unique for a specific user, and a shared cache on such a response turns into a leak between accounts.
Therefore private requests bypass the cache or use a per-user key, and access to files is granted via signed links with a short lifetime — a link leaked from logs or forwarded onward stops working before it can be used.
A stream is not cached as a whole: the recording is split into short fragments that are assembled on the device, and at the edge it is worthwhile to keep only hot fragments of popular recordings.
This relieves load from the main storage but requires careful configuration of content protection so that fragments cannot be downloaded bypassing the app. Mixing modes in one rule is not allowed — this is exactly where delivery breaks.
Common technical concerns before starting work
Before starting CDN configuration, the same questions come up: what to do with an already deployed delivery scheme, whether changes are needed in the app, and who is responsible for failures after handover.
We address them specifically — both implementation timelines and the operating mode depend on the answers.
We already have our own delivery scheme deployed — do we have to break it?
No. We map the existing infrastructure: origins, caching rules, failure points. We switch by traffic shares and compare metrics; reverting the weight takes minutes.
Will changes be needed in the app code?
Usually not: addresses for static assets and media live in the delivery configuration. Client changes are needed only if we move origin selection logic there — we do them with backward compatibility.
What happens during a spike after a mailing?
The edge cache handles the spike: requests do not reach the origin. We set headroom and prefetch rules so that isolated misses do not cascade, plus an anomaly protection threshold.
How will we know that delivery is working well?
We set up delivery analytics: cache hit ratio, time to first byte, slow regions, and share of errors by code. We compare snapshots before and after the switch.
Who is responsible for failures after handover?
For the first weeks, we do: on-call duty, incident analysis, configuration changes. After that we hand over the scheme and policies to your team or remain on support; response time is fixed in writing.
How is content security handled?
We restrict access to origins with signatures and tokens so that a link cannot be used outside the app. We mark private materials as non-cacheable and disable directory listing.
Let's discuss the task and come back with an estimate and plan
For the estimate to be accurate rather than based on analogy, we need inputs about current delivery: what is served and from where, how file addresses are structured, and whether data sets are versioned.
Describe the content types — images, video, updatable reference data — and the serving points: one origin server, several regions, or a third-party provider.
In response, we prepare an implementation plan with a work breakdown and a zero-downtime switchover scheme: traffic is transferred by shares, old addresses continue to respond, and reverting to the previous scheme is available at any step.
- What to send for the estimate: the delivery scheme, a list of domains and addresses, and where content is served from now.
- Load profile: daily and peak traffic volume, user geography, share of video and large files.
- Delivery requirements: how often content is updated, how long it lives on nodes, and whether private links are needed.
- Scope of work: distribution setup, update and storage rules, protection of content from embedding on third-party sites, and alerts about deviations.
- Zero-downtime implementation scheme: staged transfer by traffic shares, parallel operation of the old and new schemes, and a pre-described rollback.
- Timelines: enabling for part of the audience — days; full switchover and stabilization — weeks; depends on the number of domains and link requirements.
- Post-launch support: on-call duty for alerts, analysis of deviations, and revision of update rules as load grows.
Describe the task and send the inputs — we will come back with an estimate, implementation plan, and timelines for your app.







