Introduction
The boom in crypto trading multiplied user counts. For exchanges like Coinbase that means sharp traffic spikes: a price can move in minutes, and the system has to absorb the load without failing. Database autoscaling, CDN caching, and load tests are table stakes. To actually scale, they had to optimize network requests in the mobile and web apps.
This piece covers how Coinbase cut redundant API calls by 64% at peak hours, 30% on app init, and 40% in critical user journeys. Apps got faster; infrastructure load and scaling cost went down.
It is an adapted translation of a Coinbase engineering write-up: not a one-off “make this screen faster”, but systematic work on over-fetching, polling, cache, and guardrails. The approach applies to any GraphQL or REST client.
Why does cutting network requests matter?
For users. Fast load means instant transactions. Less data means the app stays smooth on constrained devices. Reliable UX builds trust.
For the business. Servers handle more concurrent clients. Growing the audience gets easier. Fewer machines and less traffic mean a smaller cloud bill.
Coinbase architecture
The data layer sits on Relay and GraphQL. A client request hits the gateway, then resolvers that aggregate data from other APIs. One such request can fan out into 1 to 100+ internal microservice calls.
That is why it is critical to count how many requests fire on cold start, first load, and key journeys: portfolio, buy, sell. Pattern analysis was the starting point for the work.
Three optimization tracks
| Track | Goal |
|---|---|
| Fight over-fetching | Stop pulling unused data and dead requests |
| Peak load | Temporarily drop non-critical work during traffic spikes |
| Guardrails | Stop new releases from bringing regressions back |
1. Fighting over-fetching
Leftover requests usually come from a poorly designed API, aggressive polling, unused fields, and dead code left after A/B tests.
The N+1 problem in APIs
The platform holds a lot of reference data: assets, prices, balances. Rendering a portfolio often meant three sequential service calls: asset list, then prices, then balances. Classic N+1: a pile of small calls instead of one aggregated request.
What they did:
- APIs accept several parameters in one call.
- Resolvers use data loaders (batched loading).
- Lists are paginated.
In some places the request count dropped by almost 90%.
Using polling wisely
Polling is a simple way to keep data fresh, but it burns resources if the interval is too tight or polling keeps running when the screen is off-focus.
In React Native, navigation leaves old screens mounted. If the home screen polls every 2 seconds with 40 requests, and the user goes a minute deep in the stack, the system fires 1,200 wasted requests.
Recommendations:
- Unsubscribe from polling when the screen loses focus.
- Look at behavior: if people spend only a few seconds on a screen, polling may not be needed.
- Measure infrastructure impact at peak hours.
- Consider alternatives: WebSockets, push notifications, GraphQL subscriptions.
Fetching data you do not need
- Conditional features (for example, UK-only) should check country first. GraphQL has
@skipand@includefor this. - Static data such as a user profile belongs in the client cache.
- Large lists (300 assets) should be paginated, not loaded in full.
Caching tools: a sane TTL, GraphQL cache-policy directives, a CDN at the edge, client cache, and React memoization.
Cleaning up dead code
After A/B tests and feature removals, unused code and its requests have to go. Coinbase uses static analyzers to find dead modules and drop them from production immediately.
2. Optimizing for peak load
During market volatility Coinbase forecasts a spike and automatically turns on optimizations via a config service. The goal is to temporarily drop non-critical work and unload the backend.
What they do:
- Turn off prefetch (optimistic fetch).
- Raise client cache TTL.
- Dial down retry aggressiveness on errors.
- Disable non-core features (promos) — during big market moves almost nobody opens them.
- Switch product features to lightweight versions.
Request volume drops by about 64% without a noticeable hit to user experience.
3. Guardrails
To keep releases from bringing regressions back, checkpoints sit on the whole path: client to gateway, GraphQL to services, by request type and platform.
New metrics
Key GraphQL metrics used to omit app version, so it was hard to see which build regressed. Adding version let them catch issues before production. A separate metric — share of cacheable operations — shows where caching can be more aggressive.
Monitoring and anomalies
They track request counts on init, per critical journey, and per screen.
Regression example: one new field without an A/B test added 20+ internal calls for every user. Monitoring caught it in development; the team optimized service-to-service calls before ship.
Results and takeaways
With these approaches Coinbase achieved:
- −64% requests at peak load;
- −30% requests on app start;
- −40% requests in critical journeys — about 20% of all traffic to the most important services.
That meant higher stability and uptime, lower infrastructure cost, and the ability to serve more users without losing quality.
What can any team take from this?
- Audit network patterns — not only at peak, but regularly.
- Fight N+1 — batched requests, data loaders, pagination.
- Be skeptical of polling — unsubscribe and look for alternatives.
- Cache everything you can — on the client, at the edge, in the CDN.
- Add guardrails — metrics, monitoring, checkpoints.
- Automate cleanup — static analyzers, PR checks, AI reviewers.
- Share the knowledge — internal talks and docs so the practices do not live with one person.
Optimizing network requests is not a one-off campaign. It pays back in app speed, user loyalty, and the cloud bill.
Frequently asked questions
- Why does cutting network requests matter?
- Leftover requests slow load, burn traffic on weak devices, and stress infrastructure. Coinbase showed you can drop redundant API calls without hurting UX: faster transactions for users and fewer servers for the business.
- How did Coinbase cut requests by 64% at peak?
- A config service turns off prefetch at peak, raises cache TTL, dials down retries, and disables non-core features. Critical journeys stay; leftover traffic drops by about 64%.
- What are over-fetching and the N+1 API problem?
- Over-fetching is requesting data the screen does not show. N+1 is when an asset list fires a separate price and balance call per item. The fix: batched parameters, data loaders in GraphQL resolvers, and pagination. In some cases request count dropped by almost 90%.
- When is polling harmful in a mobile app?
- When the interval is too tight and polling does not stop off-focus. In React Native old screens stay mounted: polling every 2 seconds with 40 requests for a minute off-screen yields 1,200 wasted calls. Unsubscribe on blur and consider WebSockets, push, and GraphQL subscriptions.
- Which guardrails keep regressions out of production?
- Request metrics on cold start, per screen, and per critical journey, app version on GraphQL metrics, and the share of cacheable operations. Monitoring catches anomalies in development, before ship.
Related: HTTPS Git push in Bitbucket · Prep quizzes