Design a URL shortener service in Go — high availability, 10k redirects/sec
go-sen-004
Your answer
Answer as you would in a real interview — explain your thinking, not just the conclusion.
Model answer
Requirements: 10k reads/sec, 1k writes/sec, 99.9% uptime, short codes ~7 chars. Short code generation: use a Snowflake-style ID generator (timestamp + node ID + sequence) encoded to Base62. This avoids distributed coordination for ID generation — each node generates unique IDs independently. Storage: PostgreSQL for durable URL mapping (shortCode PK, longUrl, createdAt, userId). Redis for hot-path caching — cache TTL 24h, eviction policy allkeys-lru. Redirect service: stateless Go HTTP servers (net/http) behind a load balancer; each instance has a local sieve cache (8MB) for the hottest 1% of URLs. Database connection pool: pgx with pool size 10–20 per instance. Analytics: async — publish to a buffered channel, a background goroutine batches writes to ClickHouse/Postgres. For 10k rps with 90% cache hits: only 1k rps hits Postgres — easily handled by a 3-node Postgres cluster with read replicas.
Code example
func NewRouter(cache *Cache, db *DB, analytics *Analytics) http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("GET /{code}", func(w http.ResponseWriter, r *http.Request) {
code := r.PathValue("code")
longURL, err := cache.GetOrFetch(r.Context(), code, func() (string, error) {
return db.FindURL(r.Context(), code)
})
if err != nil {
http.NotFound(w, r)
return
}
analytics.RecordAsync(code, r.RemoteAddr)
http.Redirect(w, r, longURL, http.StatusMovedPermanently)
})
return mux
}
Follow-up
How would you handle URL expiry — short codes that should stop redirecting after 30 days?