The page costs the critical path, not the sum
Called one by one, the seven take 300 ms. In parallel, the longest dependent chain decides: Catalog, then Recommendations, 40 + 90 = 130 ms.
Await in waves?
Bad: Await in waves
Dependent calls wait for slow Reviews too, so 150 ms, not 130.
Good: Chain on inputs
Each call starts the moment its own inputs land.
Fan-out turns a rare slow call into a common slow page
If each call is slow 1% of the time, 1 − 0.99^N of pages are. That’s 9.6% at 10 calls and 63.4% at 100.
Required parts fail the page; optional parts fade
Catalog and Pricing are required. Reviews and recommendations fall back or drop out under one 250 ms deadline, and the response lists what’s missing.
In GraphQL, Reviews times out and rating is declared Float!. What breaks?
The trap
The null propagates to the nearest nullable parent and wipes out the whole product. Make optional fragments nullable.
One experience, one BFF
Each frontend team owns a backend shaped for its screens and ships both together. Auth and rate limits stay in the gateway; business rules stay in domain services.
350K
backend calls a second at 50,000 page views
Seven calls a view, each with its own tail. For hot reads and big joins, precompute a read model from events and accept seconds of lag.
Say it like this
One call from the app. An aggregator near the services runs the critical path under one deadline, with fallbacks for optional parts. BFFs per experience, federation for many teams, precomputed big joins.