TechCoder.io / System Design

Design a URL Shortener (bit.ly)

Full system design walkthrough for a URL shortener: requirements gathering, capacity estimation (100M URLs/day), API design, Base62 hash generation, database schema, caching layer, CDN strategy, and complete architecture diagram — FAANG interview ready.

By TechCoder TeamLast updated: 2026-10-17
In a Nutshell

Full system design walkthrough for a URL shortener: requirements gathering, capacity estimation (100M URLs/day), API design, Base62 hash generation, database schema, caching layer, CDN strategy, and complete architecture diagram — FAANG interview ready. This hands-on tutorial focuses on practical implementation of design a url shortener (bit.ly) concepts.

Design a URL Shortener (bit.ly)

A URL shortener converts a long URL (https://techcoder.io/courses/system-design/module-1/what-is-system-design) into a short alias (https://tc.io/a8f3k). When someone clicks the short URL, they're redirected to the original. Simple idea, rich engineering problems.

[!IMPORTANT] URL shortener is the most common warm-up system design question in FAANG interviews. It tests: estimation, API design, hashing, caching, database schema, and availability — all core skills in one compact problem.

Step 1: Requirements Clarification

PYTHON PLAYGROUND
⏳ Loading editor…

Step 2: API Design

MethodEndpointRequest BodyResponse
POST/api/v1/urls{ "long_url": "...", "custom_alias": "...", "ttl_days": 365 }{ "short_url": "tc.io/a8f3k", "expiry": "2027-09-12" }
GET/{short_code}—301 Redirect to original URL
DELETE/api/v1/urls/{short_code}—200 OK
GET/api/v1/urls/{short_code}/stats—{ "clicks": 1234, "created": "..." }

[!NOTE] Use 301 (Permanent Redirect) if you want browsers to cache the redirect (fewer hits to your servers). Use 302 (Temporary Redirect) if you want every click to hit your servers (needed for click analytics). Most URL shorteners use 302 for analytics.

Step 3: URL Hash Generation

PYTHON PLAYGROUND
⏳ Loading editor…

Step 4: Complete Architecture

Database Schema

CREATE TABLE url_mappings (
    id            BIGSERIAL PRIMARY KEY,
    short_code    VARCHAR(10) UNIQUE NOT NULL,      -- 'a8f3k'
    long_url      TEXT NOT NULL,                   -- original URL
    user_id       BIGINT,                          -- creator (nullable for anonymous)
    expires_at    TIMESTAMPTZ,                     -- NULL = never expires
    created_at    TIMESTAMPTZ DEFAULT NOW(),
    is_active     BOOLEAN DEFAULT TRUE,
    click_count   BIGINT DEFAULT 0                 -- denormalized for fast display
);

CREATE INDEX idx_short_code ON url_mappings(short_code);   -- Primary lookup
CREATE INDEX idx_user_id ON url_mappings(user_id);          -- User's URLs list
CREATE INDEX idx_expires_at ON url_mappings(expires_at)     -- Cleanup job
    WHERE expires_at IS NOT NULL;

Quiz

Quiz

Question 1 of 2

Your URL shortener's redirect endpoint serves 115,000 QPS. Most traffic is to the top 5% of popular URLs (viral links). What is the most impactful single optimization?

Add more database read replicas to distribute query load
Cache the short_code → long_url mapping in Redis (with 24h TTL) — eliminates DB queries for 80%+ of traffic
Cache in Redis AND cache at CDN edge nodes — the top 5% of URLs served from CDN edge eliminates even the Redis + API server hop

Key Takeaways

✅ Core loop: POST long URL → generate unique 7-char code → store in DB → return short URL.
✅ 302 redirect (not 301) enables click analytics by routing every click through your servers.
✅ Redis cache for short_code → long_url mapping; CDN edge for the most popular URLs.
✅ Base62 auto-increment is collision-free but enumerable; Hash approach is non-enumerable but needs collision handling.
✅ Read:Write ratio is 100:1 — optimize heavily for reads (caching, CDN) and accept slightly higher write latency.

Official Resources

What's Next?

URL Shortener is a warm-up. Now tackle a system serving 300 million users.
Next: Design Twitter/X News Feed — Fanout strategies, push vs pull models, and timeline generation at massive scale.