System Design, but Simple

System Design, but Simple

Share this post

System Design, but Simple
System Design, but Simple
Design a URL shortener

Design a URL shortener

Like you should in an interview. Explained as simply as possible… but not simpler.

Aug 11, 2025
∙ Paid
8

Share this post

System Design, but Simple
System Design, but Simple
Design a URL shortener
3
Share

In this issue, I walk through the exact thinking I’d use in a system design interview out loud, step by step. Clear, practical, and including trade-offs you can defend.

What you’ll learn in ~15 minutes

  • How I would scope the problem without missing important requirements (custom aliases, expirations, availability).

  • A cache-first read path that keeps redirect p95 under ~200 ms.

  • Short-code generation strategies.

  • When I would choose 302 over 301 and the implications for observability and cost.

How this issue is structured
I split the write-up into the same sections I’d narrate at a whiteboard. Free readers get the full walkthrough up to the deep-dive parts. Paid members get the 🔒 sections.

  • Initial Thoughts & Clarifying Questions

  • Functional Requirements

  • Non-Functional Requirements

  • 🔒 Back-of-the-envelope Estimations (QPS, storage, bandwidth, cardinality math)

  • 🔒 System Design (the architecture I’d draw and the excalidraw link for it!)

  • 🔒 Component Breakdown (why each piece exists + alternatives)

  • 🔒 Trade-offs Made

  • 🔒 Security & Privacy (abuse, enumeration resistance, 301/302)

  • 🔒 Monitoring, Logging, and Alerting

Quick note: If you’ve been getting value from these and want the full deep dives, becoming a paid member helps me keep writing—and you’ll immediately unlock the 🔒 sections above, plus a few extras I lean on when I practice.

Members also get

  • 12 Back-of-the-Envelope Calculations Every Engineer Should Know

  • My Excalidraw System Design Template — drop-in canvas you can copy and tweak.

  • My System Design Component Library

Let’s get to it!


Initial Thoughts & Clarifying Questions

I’d start by tightening the scope. At minimum, users should be able to create a short link and later hit that short link to get redirected to the original URL.

Clarifying questions I’d ask (and I’ll state my assumptions so we can move on):

  • Who are the users? Anonymous web users. I’ll assume no login is required for basic shortening; a simple “user” concept exists if we later need ownership/analytics.

  • Custom aliases? Supported, unique if available; conflict returns an error.

  • Expirations? Optional per-link TTL; expired links should stop redirecting.

  • Latency target? ~200 ms for redirects (human-real-time).

  • Scale? Roughly 100M DAU and ~1B total shortened URLs over time.

  • Consistency vs availability? Optimize for high availability with eventual consistency; strong read-after-write is not required for brand-new links.

  • Redirect status? Prefer 302 (temporary) to keep requests flowing through our service for observability/analytics, vs 301 which may get cached across the internet. We’ll justify this later.

Functional Requirements

From what I understand, the core requirements are:

  1. Create a short URL from a long URL. Optionally accept a custom alias and an expiration time. Return the full short URL.

    • POST /urls
      Body: { long_url, custom_alias?, expires_at? } → Returns: { short_url }

  2. Redirect: Hitting the short URL should perform an HTTP redirect to the original URL (respecting expiration).

    • GET /{shortCode} → 302 Location: long_url (or error if expired/not found)

Non-Functional Requirements

I’d expect this system to be:

  • Low-latency on redirects: p95 under ~200 ms end-to-end.

  • Highly available: Favour availability over strict read-after-write consistency; eventual consistency is acceptable for newly created links.

  • Uniqueness: Short codes must be unique (no collisions), including for custom aliases.

  • Scalable: Support ~100M DAU and ~1B stored URLs with headroom for peak QPS.

  • Cost-conscious: Lean heavily on caching to offload reads; keep storage simple.

  • Operable & observable: Clear SLOs, metrics, logs, and tracing.

🔒 Back-of-the-envelope Estimations

I’ll do the math only where it informs decisions:

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2025 Stephane Moreau
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share