This question sounds scoped but it really isn't.
Start by clarifying requirements and scale (e.g., read/write ratio, QPS, latency, retention) to frame trade-offs. Then walk through the design in layers: API, data model, ID generation, caching, partitioning, rate limiting, analytics, TTL cleanup, and HA. Finally, discuss trade-offs under different traffic patterns and how you'd evolve the system.
Pro tip: Anchor your design around the read-heavy nature (100:1 read/write) and use a base62-encoded distributed ID generator like Snowflake to avoid collisions without coordination. Mention that analytics should be decoupled via async logging to avoid impacting latency.
Ask about expected QPS, read/write ratio, latency SLA, retention period, and custom alias needs. Estimate storage and bandwidth to inform design choices.
Define REST endpoints (POST /shorten, GET /{code}, GET /analytics/{code}) and a schema with short_code as primary key, original_url, created_at, expires_at, and user_id. Consider a separate analytics table or store.
Use a distributed ID generator (e.g., Snowflake) to produce unique 64-bit IDs, then base62-encode to short codes. Alternatively, use a key generation service with pre-allocated ranges to avoid collisions.
Cache hot URLs in Redis with LRU eviction and TTL. Partition data by short_code hash for even distribution. Use replication for read scalability and failover.
Implement rate limiting per user/IP using token bucket. Log analytics asynchronously to Kafka. Use a background job to delete expired URLs. Ensure HA via multi-AZ deployment and health checks.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.