A scalable, production-ready URL shortener system built with Spring Boot, Spring Cloud Gateway, Redis, and MongoDB.
- gateway/: API Gateway (Spring Cloud Gateway)
- application/: Main URL shortener service
- Redis: In-memory cache and rate limiter
- MongoDB: Persistent storage for URLs and analytics
- Start Redis and MongoDB
- Redis:
docker run -d --name redis -p 6379:6379 redis:alpine - MongoDB:
docker run -d --name mongo -p 27017:27017 mongo:latest
- Redis:
- Start the main application
cd application && mvn spring-boot:run(runs on port 8081)
- Start the gateway
cd gateway && mvn spring-boot:run(runs on port 8080)
- Test endpoints
- Shorten:
curl -X POST http://localhost:8080/api/urls/shorten -H "Content-Type: application/json" -d '{"longUrl":"https://example.com"}' - Redirect:
curl -L http://localhost:8080/{shortCode}
- Shorten:
- Clients send requests to the API Gateway (port 8080).
- Gateway routes
/api/urls/**and/{shortCode}to the main app (port 8081). - Gateway applies rate limiting (Redis), validation, and logging.
- Main app persists URLs in MongoDB and caches lookups in Redis.
- Both gateway and application are stateless, enabling horizontal scaling (add more instances behind a load balancer).
- All state (URLs, analytics, rate limits) is stored in Redis and MongoDB, not in service memory.
- Application checks Redis for short URL lookups first, then MongoDB, then populates Redis. This reduces DB load and improves latency.
- Redis-backed rate limiting at the gateway protects backend services from abuse and burst traffic.
- Different rate limits for API and redirect routes.
- Short codes can be generated to support sharding (e.g., hash-based, time-based, or range-based strategies).
- MongoDB can be sharded for very large datasets.
- Redis can be clustered for high throughput.
- Spring Cloud Gateway uses Reactor for efficient, non-blocking I/O, supporting thousands of concurrent connections with minimal resources.
- Actuator endpoints for health and metrics.
- Micrometer integration for Prometheus/Grafana.
- Centralized logging and distributed tracing recommended for production.
- Deploy multiple stateless gateway instances behind a load balancer (Kubernetes, AWS ALB, etc.).
- Use Redis Cluster for distributed rate limiting.
- Tune connection pools and timeouts for downstream services.
- Autoscale based on request rate, CPU, and latency.
- Run multiple instances behind the gateway/load balancer.
- Use Redis for caching and MongoDB for persistence.
- Tune MongoDB and Redis client pools for high concurrency.
- Use bounded thread pools or reactive I/O for maximum throughput.
- Use Redis Cluster for sharding and high availability.
- Enable persistence (AOF/RDB) as needed.
- Monitor memory usage and set TTLs for cache keys.
- Use replica sets for high availability.
- Add sharding as dataset grows.
- Create indexes on
shortCodeand TTL indexes for expiring URLs.
- Use base62 encoding, hash-based, or time-based strategies to avoid global counters.
- Allocate ID ranges per instance or shard for distributed generation.
- Ensure idempotency to avoid duplicates during retries.
- Use retries with exponential backoff for downstream calls.
- Implement circuit breakers for non-critical dependencies.
- Gracefully handle shutdowns and drain connections.
- Apply backpressure in the application for burst traffic.
- Instrument gateway and app with Micrometer (Prometheus).
- Track request rate, error rate, latency, Redis hit/miss, DB ops/sec.
- Use centralized logging (ELK, Loki) and distributed tracing (OpenTelemetry).
- Terminate TLS at the gateway.
- Validate input at both gateway and application.
- Rate limit per IP or API key.
- Use authentication/authorization (JWT/OAuth) for protected APIs.
- Build container images for each service.
- Use immutable image tags (avoid
latestin production). - Deploy via CI/CD pipelines (GitHub Actions, GitLab CI, Jenkins).
- Run integration tests with testcontainers for Redis and MongoDB.
- Load test with tools like k6 or Locust.
- Test Redis and MongoDB failover scenarios.
- Validate autoscaling behavior in your environment.
- Monitor end-to-end latency and error rates under load.
- Gateway HTTP client pool and timeouts:
spring.cloud.gateway.httpclient.pool.max-connections=200
spring.cloud.gateway.httpclient.connect-timeout=10000
spring.cloud.gateway.httpclient.response-timeout=30s- Redis TTL for cached URLs:
app.cache.url.ttl=86400- MongoDB indexes:
- Ensure an index on
shortCodeand TTL indexes for expiring URLs.
- Ensure an index on
- Add OpenTelemetry tracing for full request visibility.
- Implement Redis Cluster + Sentinel for HA.
- Add MongoDB sharding for large datasets.
- Build analytics pipeline (Kafka) for real-time metrics.
- Add comprehensive load and chaos testing in CI.
For questions or contributions, please open an issue or pull request!