URL Shortener
A backend service that creates short URLs and redirects to the original destination. It is a small system, but it is built the way a production service would be, to practise common backend patterns end to end: caching, rate limiting, background jobs, observability and load testing.

Architecture, from the repository. All services run together with Docker Compose.
The redirect path
Redirects are the hot path, so they do as little as possible. The API first looks up the short code in Redis. On a hit it redirects immediately. On a miss it reads PostgreSQL (indexed on short_code), caches the result, then redirects. Click tracking is not written during the request: the API enqueues an analytics job, and a separate RQ worker updates the click count. Redirect latency therefore never waits on a database write.
Short codes and rate limiting
Short codes are the Base62 encoding of the row’s database ID, so they are deterministic, collision-free and cheap to generate. URL creation is rate-limited per IP (10 per minute) with Redis counters that expire at the end of each window.
Observability
The API exposes Prometheus metrics, including redirect counts, cache hits and misses, rate-limited requests and redirect latency, with Grafana dashboards on top. A /health endpoint checks both PostgreSQL and Redis.
Load testing (k6, 50 virtual users for 30 seconds, against the local Docker deployment)
| Redirect endpoint | Value |
|---|---|
| Median latency | 3.97 ms |
| P95 latency | 41.56 ms |
| Error rate | 0% |
The median shows most redirects being served from Redis. The higher percentiles are mostly cache misses that go to the database. A separate test deliberately exceeded the creation limit and received HTTP 429 responses for the extra requests, as intended.
Limitations
It runs a single PostgreSQL and a single Redis instance, with no horizontal scaling and minimal authentication. The point was to understand the patterns, not to run it at scale.
Stack
FastAPI · SQLAlchemy · PostgreSQL · Redis · RQ · Prometheus · Grafana · k6 · Docker Compose