CMD Guide
HomeSystem DesignMicroservices Patterns

System Design Examples

The previous five pages built the BFF pattern one mechanism at a time — the projection layer, the architecture, the byte accounting, the fan-out latency math. This page assembles those mechanisms into three worked system designs: a streaming-media platform serving mobile, web, and TV from the same services; an authentication design that splits work between the gateway and each BFF; and a partner-API BFF that shows "client experience" is not only about devices. Each design ends the way a design review would — with the first bottleneck, the alternative that was rejected, and the trade-off that was knowingly paid.

The why-chain that runs through all three: clients diverge (screen, link, interaction model) → a shared response shape becomes the union of every client's needs → the union punishes the weakest link (cellular, a TV's D-pad, a partner's batch job) → so the projection must move server-side → and the team that owns the screen must own the projection → one BFF per client experience. Every latency and byte figure below is illustrative but internally consistent, built on the chapter's house numbers: ~120 ms cellular RTT, ~40 ms broadband WAN RTT, ~1–2 ms intra-DC network per hop (service work on top).

Design 1 — a streaming platform: three clients, four services, three payloads

The product is a video-streaming home screen. Four shared, screen-agnostic services own the data:

Three client teams each own a BFF against those same four services. The projections differ because the screens differ:

Request flow, per client

Mobile (cellular, ~120 ms RTT), GET /mobile/home for user 8842:

StepWhereWhat happensCost
1cellularApp issues one call, GET /mobile/home~120 ms RTT (paid once)
2in-DCMobile BFF fans out in parallel: catalog (18 ms), continue-watching (8 ms), entitlement (6 ms), recommendations (24 ms)max = 24 ms, not the 56 ms sum
3BFF CPUProject 20 titles (2 rows) down to 6-field cards: 20 × ~140 B ≈ 2.8 KB + framing ≈ ~3 KB~2 ms
4One response returns; absorbed upstream: 20 × 2.5 KB catalog + 3 + 1 + 2 KB ≈ ~56 KB → ~3 KB (~19×)client-perceived ~146 ms (120 + 24 + 2)

Web (broadband, ~40 ms WAN RTT), GET /web/home — same fan-out, different projection:

StepWhat differs from mobileCost
1One call over broadband instead of cellular~40 ms RTT
2Identical parallel fan-out to the same four servicesmax = 24 ms
3Projects 30 titles (3 rows) to hover-rich cards: 30 × ~700 B ≈ 21 KB + framing ≈ ~22 KB returned, ~81 KB absorbed (30 × 2.5 + 6 KB)~2 ms
4Client-perceived total~66 ms (40 + 24 + 2)

TV (living-room broadband, ~40 ms WAN RTT), GET /tv/home:

StepWhat differsCost
1One call; same fan-out40 + 24 ms
2Projects 3 visible rows × 10 tiles = 30 tiles × ~300 B ≈ 9 KB, plus a ~1 KB prefetch manifest for row 4~10 KB returned, ~81 KB absorbed
3User D-pads past row 3 → app follows the row cursor, GET /tv/home/rows?cursor=r4 → one ~3 KB row page (already half-warm from the hint)~40 ms per additional row page
4Client-perceived first paint~66 ms, and row scrolling never blocks on artwork

The punchline in one table — the same four services, three different payloads, and no client team negotiated with another:

ClientFirst response shapeBytes returnedBytes absorbedPerceived latency
Mobile2 rows of 6-field cards~3 KB~56 KB~146 ms
Web3 rows of hover-rich cards~22 KB~81 KB~66 ms
TV3 rows × 10 tiles + 4K art + prefetch hints~10 KB~81 KB~66 ms

Notice what the numbers say about where each BFF earns its keep: mobile's win is bytes (56 KB → 3 KB on a metered radio); TV's win is interaction-shaped data (prefetch hints and row cursors exist only because the input device is a D-pad); web's win is the single round trip and server-side join. A shared endpoint could serve any one of these well — never all three.

Design 2 — authentication: what the gateway does, what each BFF does

Authentication is the sharpest illustration of the gateway-vs-BFF dividing rule from the architecture page: identical for every client → gateway; exists because this client is different → that client's BFF.

At the shared gateway (once, for everyone): TLS termination and token verification — check the JWT's signature, expiry, and issuer (~0.3–0.5 ms warm, consistent with the API-gateway chapter's figures). The gateway answers exactly one question — is this a valid principal? — and forwards the identity downstream. It does not know what a session cookie is, and it does not decide what user 8842 may watch.

At each BFF (per client, because credential handling genuinely differs):

The boundary rule, stated once: authN at the gateway; per-client session and credential shaping in the BFF; authZ stays in the services. When the TV app asks for a 4K stream, entitlement-service — not the TV BFF — decides whether account 8842's plan allows it. Put entitlement logic in a BFF and it silently diverges from the answer mobile gets tomorrow.

Design 3 — the partner BFF: a client experience without a screen

A set-top-box operator wants your catalog inside their guide. Their "client" is a nightly batch job and a burst of morning traffic — a client experience as distinct as mobile-vs-TV, just with no pixels. Pointing them at your internal services would freeze your internals into a public contract; a shared gateway would give them the same chatty, fine-grained shape your own apps outgrew. So they get a BFF:

The lesson: "one BFF per client experience" counts experiences by divergence of needs, not by device type. A partner API, an internal admin tool, and a voice assistant are all candidate experiences.

Deployment topology: mobile, web, TV, and partner clients pass through one shared gateway (TLS, authN, WAF, rate-limit) to four independently owned and scaled BFFs, which fan out to shared catalog, continue-watching, entitlement, and recommendation services
Deployment topology: mobile, web, TV, and partner clients pass through one shared gateway (TLS, authN, WAF, rate-limit) to four independently owned and scaled BFFs, which fan out to shared catalog, continue-watching, entitlement, and recommendation services

Deployment topology: independent curves, isolated failures

The topology is the diagram above: one shared gateway (TLS, authN, WAF, rate-limiting — cross-cutting, platform-owned) routes by path prefix to four BFFs, each owned and deployed by its client team, all fanning out to the same shared services. Two properties fall out of that separation:

The operational bill for these properties is exactly the one the chapter has been honest about: four deployables to build, secure, monitor, and page on — N BFFs = N of everything.

Hostile design review: bottleneck, rejected alternative, price paid

DesignFirst bottleneckAlternative we rejectedTrade-off we accepted
1. Streaming multi-clientrecommendation-service at evening peak: all three BFFs fan out to it, and at 24 ms it is already every home screen's slowest branch — its p99 governs all three clients at once. Fix: per-branch deadline with a popular-titles fallback, plus per-BFF caching so 3× fan-out does not become 3× recs load.One GraphQL edge — real per-client shaping without three deployables, but query-cost control, resolver N+1 storms, and a shared schema team were a poor fit for three strong client teams shipping on different cadences.Three codebases whose auth, retry, and mapping logic can drift; a shared library and cross-BFF contract tests are mandatory, not optional.
2. Auth at the BFFThe web BFF's session-store lookup sits on every request; if it is a remote store, that is an extra in-DC round trip per page view. Fix: replicated store with a short-TTL local cache.Tokens in browser localStorage — no session state to run, but readable by any injected script; one XSS becomes full account takeover.Server-side session state to operate, back up, and fail over — the web team now runs a small stateful system.
3. Partner BFFUnbounded delta queries: a partner asking for "everything since 2019" walks the whole catalog. Fix: cursor pagination with a bounded page size and per-key rate limits from day one.Exposing internal service APIs behind the gateway — zero new code, but it freezes internal shapes into a public contract and hands partners N chatty endpoints.A versioned public contract that must be supported for years; every field added to /v1 is a promise.

When NOT to do any of this

A shared gateway with a thin aggregation layer beats per-client BFFs when the clients do not genuinely diverge: if mobile, web, and TV all render essentially the same card, three BFFs are three copies of one service — pay for one edge, add field filtering (sparse fieldsets) for the small differences, and stop. The same is true organizationally: if one team owns all the clients, the BFF's core payoff — independent ownership and deploy cadence — evaporates, and N BFFs is just N times the on-call surface. And if shaping needs are many, dynamic, and unpredictable rather than three stable experiences, a GraphQL layer (client-defined shaping) fits better than N server-defined projections. The streaming design above earns its three BFFs only because the projections, the interaction models, and the owning teams all diverge; remove any one of those and the design should shrink.

Drill ladder

  1. Q: Why does the TV BFF return prefetch hints and a row cursor while the mobile BFF returns neither? A: The interaction model is the client difference being served. D-pad navigation is predictable — row by row — so the next row's art URLs can be warmed ahead of the keypress; mobile scrolling is fast and erratic, and cellular bytes are the scarce resource, so mobile ships minimal cards and nothing speculative.
  2. Q: The gateway already verified the JWT. Why does the web BFF still run a session store? A: Verification (authN) and credential shaping are different jobs. The gateway answers "is this a valid principal?" once for everyone. The web BFF answers "how does this client safely carry credentials?" — a browser cannot hold bearer tokens safely, so the BFF holds them server-side and gives the browser only an HttpOnly cookie. Mobile skips all of that because secure device storage exists.
  3. Q: At evening peak, recommendation-service p99 degrades from 24 ms to 200 ms. What happens to each client, and what is the fix? A: All three home screens degrade together, because each BFF's fan-out is governed by its slowest branch and recs is that branch in every one of them. Fix: a per-branch deadline (e.g. ~60 ms) with a cached popular-titles fallback — recommendations are deferrable, the home screen is not — plus per-BFF response caching so three BFFs do not triple the load on the struggling service.
  4. Q: The partner asks for one more field in /partner/v1/catalog/updates; the mobile team added a similar field to their BFF yesterday in an afternoon. Why is the partner change slower? A: The mobile BFF's contract is private — one team owns both sides, so change is a same-day deploy. The partner contract is public and versioned: adding a field is cheap, but it becomes a commitment you cannot walk back without a months-long deprecation window, so it gets reviewed as a promise, not a patch.

Takeaways


Authored for this guide as the worked-examples capstone of the BFF chapter. Sources: Phil Calçado, "The Back-end for Front-end Pattern (BFF)" (philcalcado.com, 2015); Sam Newman, "Backends For Frontends" (samnewman.io) and Building Microservices, 2nd ed. (O'Reilly, 2021); Microsoft Azure Architecture Center, "Backends for Frontends pattern"; RFC 8628 (OAuth 2.0 Device Authorization Grant) for the TV login flow. All latency and byte figures are illustrative worked values consistent with this chapter's house numbers (~120 ms cellular RTT, ~40 ms WAN RTT, ~1–2 ms intra-DC), not measurements of a specific system.

🤖 Don't fully get this? Learn it with Claude

Stuck on System Design Examples? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **System Design Examples** (System Design) and want to truly understand it. Explain System Design Examples from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **System Design Examples** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **System Design Examples** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **System Design Examples** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes