System requirements


Functional:

  • Create short URL from long URL
  • Redirect short URL to original URL
  • Support optional expiration (default: 1 year)
  • Optional custom alias (nice to have)

Non-Functional:

  • High read throughput (read-heavy system)
  • Low latency redirects (<50ms)
  • High availability (no single point of failure)
  • Horizontally scalable
  • Globally available (multi-region)

Estimations:

  • 100K users × 10 URLs/day = 1M writes/day (~12 writes/sec)
  • Reads ≈ 1000/sec
  • Keyspace: Base62 → 62⁶ ≈ 56.8 billion combinations (no need for recycling)




API Design

POST /create Flow:

  1. Receive long_url
  2. Generate unique ID (Snowflake)
  3. Convert ID → Base62 → url_key
  4. Store mapping in DB
  5. Cache in Redis
  6. Return short URL


GET /url_key Flow:

  1. Check cache
  2. If hit → redirect to long_url
  3. If miss → query DB
  4. Cache result
  5. Check expiration
  6. Redirect to long_url or return error if expired





High-Level Architecture

Client → GeoDNS → Nearest Region

Each region contains:

  • Load Balancer
  • Stateless App Servers
  • Redis (cache)
  • Sharded Database (primary + replicas)
  • Distributed ID Generator (Snowflake)




Detailed component design

Key Generation (Core Decision)

  • Use Snowflake ID generator for globally unique IDs
  • Convert ID to short key using Base62 encoding

Why:

  • No collisions
  • No race conditions
  • No need for KGS or coordinator
  • Works across multiple regions

Database Design

Table: url_mapping

  • url_key (Primary Key)
  • long_url
  • created_at
  • expiration_date
  • user_id (optional)

Sharding:

  • Partition by hash(url_key)

Replication:

  • Primary + read replicas per region
  • Async replication across regions

Caching Strategy

  • Cache hot URLs in Redis
  • Key → url_key, Value → long_url
  • Use LRU eviction
  • Store millions of entries to reduce DB load

Multi-Region Design

  • GeoDNS routes user to nearest region
  • Each region handles reads + writes independently
  • IDs generated locally using Snowflake

Replication:

  • Asynchronous between regions

Consistency:

  • Eventual consistency (acceptable for URL shortener)

Expiration & Cleanup

  • Store expiration_date in DB
  • On read: check expiry → reject if expired
  • Background job deletes expired entries
  • No need to recycle keys (huge keyspace)

Scaling & Optimizations

  • Add DB shards for write scaling
  • Use read replicas for read-heavy traffic
  • Use CDN like Cloudflare to cache redirects at edge
  • Increase cache size to reduce DB hits

Tradeoffs

  • Sequential Base62 keys → predictable URLs
  • → Can add randomness if needed
  • Eventual consistency across regions
  • → Slight delay in propagation but acceptable

Final Summary

  • Use Snowflake + Base62 for key generation (no KGS)
  • Use Redis cache for fast reads
  • Use sharded DB + replicas for scalability
  • Use GeoDNS + multi-region deployment
  • Use async replication for global availability