πŸ“NoteπŸ’»Tech

Beginner System Design Interview: Design Bitly w/ a Ex-Meta Staff Engineer

Tony Duong

Tony Duong

Jun 17, 2026 ・ 5 min

#system-design#bitly#url-shortener#interview#distributed-systems#redis#caching
Beginner System Design Interview: Design Bitly w/ a Ex-Meta Staff Engineer

Notes from Hello Interview (Evan, ex-Meta staff engineer) on designing a URL shortener like Bitly β€” positioned as the classic beginner system design question, with concepts explained more slowly than in their advanced videos.

Interview roadmap

  1. Requirements (functional + non-functional)
  2. Core entities
  3. API
  4. High-level design (satisfy functional requirements)
  5. Deep dives (satisfy non-functional requirements)

Skip data flow for user-facing product designs (save that for infra questions like rate limiters or message queues).

Back-of-envelope math upfront is optional β€” only estimate when numbers change the design.

What the system does

A URL shortener converts long URLs into short ones; visiting the short URL redirects to the original.

Functional requirements

  • Users can create a short URL from a long URL
  • Users can be redirected to the original URL from the short URL

Common optional extensions in interviews:

  • Custom alias β€” user provides their own short code (e.g. bit.ly/Evan) if not taken
  • Expiration time β€” short URL valid only for a period (e.g. conference link for one week)

Non-functional requirements

Typical scale Evan gives candidates:

  • 100 million DAU
  • ~1 billion URLs shortened over all time

Other NFRs to call out in context:

Concern URL shortener framing
Low-latency redirects Redirect path must be fast β€” users feel latency immediately
Unique short codes Collisions redirect users to wrong sites β€” must guarantee uniqueness
Scalability Support 100M DAU and 1B stored mappings
CAP Favor availability + partition tolerance over strong consistency (see below)

Core entities

  • User β€” owns short URLs (email, password hash, etc. are auxiliary; don't over-detail in interviews)
  • URL mapping β€” short code ↔ long URL (the core table)

API

  • POST /urls β€” body: long URL (+ optional custom alias, optional expiration) β†’ returns short URL
  • GET /{shortCode} β€” redirect to long URL (302 in the high-level design)

High-level design (v1)

Client β†’ Load balancer β†’ URL Service β†’ Database (URL mappings)
  • Create: insert (shortCode, longUrl) β†’ return short URL
  • Redirect: lookup shortCode β†’ return 302 redirect to long URL

301 vs 302 redirects

Code Behavior When to use
302 Temporary β€” browser always hits your server Default when you don't need analytics, or want every redirect logged
301 Permanent β€” browsers/CDNs may cache; may skip your server When redirects are truly permanent and you don't need per-click logging

For Bitly without analytics, 302 is fine. With analytics, 302 ensures redirects always reach your server so you can count clicks.

Deep dive: generating short codes

Bad approaches:

  1. Prefix of long URL β€” many URLs share prefixes (twitter.com/...) β†’ one-to-many mapping, collisions
  2. Hash long URL only β€” deterministic, so same long URL always gets same short code (OK for dedup), but hash collisions need handling; append salt/rehash on collision

Good approaches:

Counter + base62 (recommended in video)

  • Maintain an auto-incrementing counter per new URL
  • Base62 encode the counter (0–9, A–Z, a–z) for compact strings
  • 6 characters β†’ 62⁢ β‰ˆ 56 billion combinations
  • No collisions β€” sequential IDs are unique by construction

Random number + base62

  • Pick random integer in [0, 56B), base62 encode
  • Birthday paradox: collision probability rises faster than intuition β€” with ~1B URLs, collisions become a real concern
  • Must check DB and retry on collision

Hash long URL + base62 slice

  • Hash (MD5, Murmur, SHA-256) β†’ base62 β†’ take first 6 chars
  • Deterministic dedup for same long URL
  • On collision, append salt and rehash

Deep dive: CAP and consistency

URL shortener does not need strong read-after-write consistency (unlike banking or ticket booking).

If a user creates a short URL and shares it instantly, eventual consistency is acceptable β€” a brief "try again in a minute" error is tolerable. Favor AP over CP.

Deep dive: scaling reads (redirect-heavy)

Redirects dominate traffic β€” read-heavy workload.

Read/write service split

  • Write service β€” creates short URLs
  • Read service β€” handles redirects
  • API Gateway routes POST /urls β†’ write service, GET /{shortCode} β†’ read service

Scale each tier horizontally (auto-scaling groups behind load balancer).

Redis cache (read-through LRU)

  • On redirect: check Redis for shortCode β†’ longUrl
  • Cache miss: read DB, populate cache, return
  • Read-through + LRU eviction for hot short URLs

Primary key lookup on Postgres (B-tree) is already fast, but cache removes DB load at scale.

Peak redirect QPS (rough): 100M DAU Γ— a few redirects/day β†’ ~1K req/s average, 10–100K req/s at peak with burst multiplier.

Key Takeaways

  • Bitly is the classic entry-level system design question β€” requirements β†’ entities β†’ API β†’ design β†’ deep dives
  • Counter + base62 is the cleanest collision-free short-code strategy; random needs birthday-paradox math
  • Never use URL prefix as short code β€” shared prefixes break one-to-one mapping
  • 302 vs 301 depends on whether you need server-side redirect logging (analytics)
  • Read/write split + Redis read-through cache for redirect-heavy scaling
  • Eventual consistency is OK β€” not every system needs strong read-after-write
  • Only run back-of-envelope estimates when they change architectural decisions
Tony Duong

By Tony Duong

A digital diary. Thoughts, experiences, and reflections.