Distributed URL shortening service - learning project
Find a file
2025-12-30 16:16:10 +05:30
app nginx load balancer and api 2025-12-30 16:16:06 +05:30
db init db and docker 2025-12-30 16:15:46 +05:30
nginx nginx load balancer and api 2025-12-30 16:16:06 +05:30
.gitignore init db and docker 2025-12-30 16:15:46 +05:30
docker-compose.yml init db and docker 2025-12-30 16:15:46 +05:30
Dockerfile init db and docker 2025-12-30 16:15:46 +05:30
pyproject.toml init db and docker 2025-12-30 16:15:46 +05:30
README.md readme 2025-12-30 16:16:10 +05:30

URL Shortener - Distributed Systems Learning Project

A URL shortening service designed to teach distributed systems concepts.

Architecture

[Client] --> [Nginx LB] --> [API Server 1] --> [Redis Cache] --> [PostgreSQL]
                        --> [API Server 2] -->
                        --> [API Server 3] -->

Concepts Covered

Concept Implementation
Load Balancing Nginx with least_conn algorithm
Caching Redis with read-through pattern
Unique ID Generation Snowflake IDs (Twitter-style)
Encoding Base62 for short URLs
Rate Limiting Nginx rate limiting (10 req/sec/IP)
Async Processing Fire-and-forget click tracking

Quick Start

# Start all services
docker compose up -d

# Scale API servers to 3 instances
docker compose up -d --scale api=3

# Test the service
curl -X POST http://localhost/shorten \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/very/long/path"}'

# Follow the redirect
curl -L http://localhost/{short_code}

# Get stats
curl http://localhost/stats/{short_code}

Local Development (without Docker)

# Install dependencies
uv venv
source .venv/bin/activate
uv pip install -e ".[dev]"

# Start PostgreSQL and Redis (via Docker)
docker compose up -d postgres redis

# Run the API server
uvicorn app.main:app --reload

API Endpoints

Method Endpoint Description
POST /shorten Create a short URL
GET /{code} Redirect to original URL
GET /stats/{code} Get click statistics
GET /health Health check

File Structure

.
|-- app/
|   |-- main.py       # FastAPI application
|   |-- encoding.py   # Base62 encoding
|   |-- snowflake.py  # Distributed ID generation
|-- db/
|   |-- init.sql      # Database schema
|-- nginx/
|   |-- nginx.conf    # Load balancer config
|-- docker-compose.yml
|-- Dockerfile
|-- pyproject.toml