</> MAANG.io
system design · 301

Advanced

Master system design interviews with scalable architecture patterns, distributed systems, and real-world design challenges.

0/480 solved 0% complete

Section 4: Cacheable by Construction - API Design

Executive Summary: Section 3 showed that this system lives or dies on an 85% CDN hit ratio. An API can quietly destroy that number. Put one personal field in the page and the signed-in 20% stops being cacheable, or worse, gets cached for the wrong person. This section designs a contract where cacheability is a property of the shape, not a hope. Everyone gets one public page, and a small private call carries what is yours. Writes are retry-safe by verb or by key, and lists page with cursors.

The board still shows Section 3's funnel: 10,500 page views a second at peak, 85% served by the edge, about 1,600 renders a second reaching the origin. Start the API by saying what it must protect.

You: "My API has one job before any other: keep that funnel intact. So I'll split it along a single line. Everything public is keyed by URL and cacheable. Everything personal is small, private and never cached."

The Endpoint Map

# Public reads: identical for every viewer, cacheable at the CDN
GET   /questions/{id}/{slug}                      HTML page
GET   /api/v1/questions/{id}                      question bundle (JSON)
GET   /api/v1/questions?tag=postgresql&sort=hot|new|unanswered&cursor=…
GET   /api/v1/posts/{postId}/comments?parent=…&cursor=…    "continue this thread"
GET   /api/v1/search?q=…&cursor=…
GET   /api/v1/questions/similar?title=…           duplicate suggestions while typing

# Private read: per viewer, never cached
GET   /api/v1/questions/{id}/viewer-state          myVotes, canEdit, bookmarked

# Writes
POST  /api/v1/questions                  Idempotency-Key header      → 201
POST  /api/v1/questions/{id}/answers     Idempotency-Key header      → 201
POST  /api/v1/posts/{postId}/comments    Idempotency-Key; { body, parentCommentId? }  → 201
PUT   /api/v1/posts/{postId}/vote        { value: 1 | -1 | 0 }       → { score, myVote }
PATCH /api/v1/posts/{postId}             If-Match: "rev-7"           → 200 or 412
POST  /api/v1/questions/{id}/accept      { answerId }                → 200
POST  /api/v1/posts/{postId}/flags       { reason }                  → 202

Every {id} is a 64-bit ID carrying its logical shard in 10 bits (laid out in Section 5), so any server routes Priya's question or Ana's comment without a lookup. The {slug} is cosmetic: a wrong or stale slug gets a 301 to the canonical URL, giving each question one cache key and one URL for search engines.

Quick check before moving on:

Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.