Frontend Labs
⋯

Part V — Casebook: Real Interview Problems, Solved

Every case follows the same template as §2: business context → requirements → estimates → API & data → design → deep dives → failure modes → strategic lens → follow-ups, followed by a 🏗️ flow diagram, 🌍 how it's built in production (from real engineering blogs and papers), and ⚠️ corner cases. The strategic lens (business, cost, org, evolution) is expected at Staff level and above and from managers; at Senior level it's what lifts a solid answer to a strong one. The cases get harder roughly in order. Practice them out loud against a 45-minute timer, drawing as you go (§63), before reading the solutions.


31. URL Shortener (warm-up)

Business context. A marketing-links product (like bit.ly). Revenue comes from click analytics for paying customers. Redirect latency and availability are the product. A broken link in a printed ad can't be fixed.

Requirements. Create a short URL (optional custom alias, expiry); redirect; click analytics. NFRs: 100M new URLs/month; 10B redirects/month; redirect p99 < 50 ms at the edge; 99.99% redirect availability; links never collide or change.

Estimates.

Writes: 100M / 2.6M s ≈ 40/s (peak ~200/s)  → trivial
Reads:  10B / 2.6M s ≈ 4,000/s (peak ~20k/s, viral spikes 100k+/s on one key)
Storage: 100M * 12 months * 5 yrs * ~500 B ≈ 3 TB  → fits easily in a KV store
Key space: base62, 7 chars → 62^7 ≈ 3.5 trillion  → enough for decades

API.

POST /v1/links {long_url, custom_alias?, expires_at?} → {short_code}
GET  /{short_code} → 301/302 Location: long_url
GET  /v1/links/{code}/stats?from&to

Generating codes: the core decision.

Approach Pros Cons
Hash(long_url) and take 7 chars Deterministic, same URL → same code Collisions need a check-and-retry loop; per-customer links need a salt
Counter + base62 (range allocation: each server leases a block of 1M IDs from a coordinator) No collisions, no coordination per request Sequential codes are enumerable → mix the bits with a reversible permutation if that matters
Random 7 chars + uniqueness check Simple, non-guessable Extra read per write (fine at 40/s)
Pre-generated key service Fast handout Another service to run

Design.

Create:  client → API → ID-range allocator (lease blocks) → base62 → KV store (code → url, owner, expiry)
Redirect: client → CDN/edge (cache 301s for popular codes) → redirect service → cache (Redis) → KV store
          └── emit click event (async, fire-and-forget to a local buffer → Kafka) → analytics pipeline

Deep dives.

  • 301 vs 302: 301 is cached by browsers (cheaper, but you lose analytics on repeat clicks); 302 records every click. The business need (paid analytics) means 302, plus edge caching at the CDN for a few seconds to absorb viral spikes.
  • The analytics write path must never slow the redirect. Buffer locally and drop on overload. Losing 0.01% of click events is acceptable; a slow redirect isn't.
  • Abuse: phishing and malware links hurt domain reputation. Run safe-browsing checks on creation, and rescan asynchronously.

Strategic lens. The real risk to the business isn't scale. It's domain reputation (spam filters blocking the short domain) and link permanence. Multi-region read replicas for redirects and a DR-tested KV store matter more than clever ID schemes.

Follow-ups: custom domains per customer (TLS certificates at scale, e.g. ACME automation); GDPR deletion of click data; how to expire links (a TTL in the KV store plus lazy checks).

🏗️ Flow: redirect hot path with an analytics side channel.

 Browser ─GET /aZ3kQ9x─▶ Edge PoP
                          ├─ edge KV / cache hit (popular code, TTL 60 s) ──▶ 302 Location: … (≈10 ms)
                          └─ miss ─▶ Redirect svc ─▶ Redis (code→url) ─miss─▶ KV store (DynamoDB/Bigtable)
                                         │                                     (replicated, multi-region)
                                         └─ enqueue click {code, ts, ip-hash, ua, referrer}
                                            to in-memory ring buffer → batch → Kafka (drop if full)
 Kafka ─▶ stream job (bot filter, dedupe) ─▶ OLAP (per-link per-minute counts) ─▶ customer dashboards

🌍 How it's built in production.

  • Twitter's t.co wraps every link in a tweet, which lets Twitter check links for malware and phishing at click time (not only at creation) and measure engagement. It's the same pattern: a redirect service plus safety checks plus analytics.
  • ID generation in the wild: Twitter's Snowflake (2010: 41 bits timestamp + 10 bits machine + 12 bits sequence) and Instagram's Postgres-generated IDs (§9.7) are the standard references for coordination-free, time-ordered IDs. Encode them in base62 for short codes.

⚠️ Corner cases.

  • Reserved paths: a user registers the custom alias api, login, or admin, which collides with your routes. Keep a reserved-word list.
  • Case sensitivity and look-alikes: base62 is case-sensitive, but people retype links in lowercase from print. Offer a case-insensitive alphabet (base36) for printed codes, and avoid ambiguous characters (0/O, 1/l/I).
  • Never reuse expired codes: an old printed QR code would send people to a new owner's URL (phishing). Expired codes are tombstoned forever.
  • Destination edits: if customers can change the target URL, cached redirects at the edge and in browsers (if you used 301) keep the old target. Use short TTLs and purge on edit.
  • Redirect loops and chains: a short link pointing at another short link, or at itself. Resolve and reject on creation.
  • Bot inflation: link previewers (Slack, iMessage, social crawlers) fetch the URL and count as clicks. Classify by user agent and behavior, and report "human clicks" separately.

Generated from real-life-system-design-guide.md · 8 Oct 2026 16:36