A production-style distributed rate limiting service built using Spring Boot, Redis, Docker, Prometheus, and Grafana.
The service protects APIs from abuse by limiting the number of requests a user can make within a sliding time window.
This project demonstrates backend system design, distributed caching, observability, and containerized deployment similar to real-world API infrastructure used in large-scale systems.
- Client sends request to API
- API extracts
X-User-Idheader - RateLimiterService processes the request
- Redis Sorted Set stores request timestamps
- Requests outside the sliding window are removed
- Redis counts remaining requests in the window
- If request count exceeds limit → request blocked
- Prometheus scrapes application metrics
- Grafana visualizes system performance and traffic
- Distributed rate limiting using Redis
- Sliding window rate limiting algorithm
- Per-user and per-endpoint request limits
- Redis Sorted Set based request tracking
- Docker containerized deployment
- Prometheus metrics integration
- Grafana monitoring dashboards
- Production-style backend architecture
| Component | Technology |
|---|---|
| Backend | Spring Boot |
| Cache | Redis |
| Rate Limiting | Redis Sorted Sets |
| Build Tool | Maven |
| Containerization | Docker |
| Monitoring | Prometheus |
| Visualization | Grafana |
| Metrics | Micrometer |
ratelimiter
│
├── src/main/java/com/rahul/ratelimiter
│ ├── controller
│ │ └── RateLimitController.java
│ │
│ ├── service
│ │ └── RateLimiterService.java
│ │
│ ├── model
│ │ └── RateLimitProperties.java
│ │
│ └── RatelimiterApplication.java
│
├── src/main/resources
│ └── application.properties
│
├── docs
│ ├── architecture.png
│ └── grafana-dashboard.png
│
├── monitoring
│ ├── prometheus.yml
│ └── grafana-dashboard.json
│
├── docker-compose.yml
├── Dockerfile
├── pom.xml
└── README.md
Example configuration in application.properties:
ratelimiter.windowSeconds=60
ratelimiter.limits.data=10
ratelimiter.limits.login=5
ratelimiter.limits.admin=2
| Endpoint | Limit | Window |
|---|---|---|
| /api/data | 10 requests | 60 seconds |
| /api/login | 5 requests | 60 seconds |
| /api/admin | 2 requests | 60 seconds |
This project uses a Sliding Window Algorithm implemented using Redis Sorted Sets.
For every request:
- Request timestamp is added to a Redis Sorted Set
- Entries outside the time window are removed
- Remaining entries are counted
- If count exceeds limit → request rejected
rate_limit:user123:/api/data
timestamp → requestId
This ensures that only requests within the last N seconds are counted.
git clone https://github.com/rahulreddyin/distributed-rate-limiter-api.git
cd distributed-rate-limiter-api
docker compose up -d
Verify containers:
docker ps
Expected services:
| Service | Port |
|---|---|
| Spring Boot API | 8080 |
| Redis | 6379 |
| Prometheus | 9090 |
| Grafana | 3000 |
For local development:
./mvnw spring-boot:run
Application URL:
http://localhost:8080
All requests must include:
Header: X-User-Id
GET /api/data
Request:
GET http://localhost:8080/api/data
Header: X-User-Id: user123
Response:
{
"message": "Request allowed",
"endpoint": "/api/data"
}{
"error": "Too Many Requests",
"message": "Rate limit exceeded"
}HTTP status:
429 Too Many Requests
Spring Boot exposes Prometheus metrics through Actuator.
Metrics endpoint:
http://localhost:8080/actuator/prometheus
Prometheus collects:
- JVM metrics
- HTTP request metrics
- Redis command metrics
- Custom rate limiter metrics
Grafana visualizes system performance and API traffic.
Example dashboard:
Allowed requests
ratelimiter_requests_allowed_total
Blocked requests
ratelimiter_requests_blocked_total
API request throughput
sum(rate(http_server_requests_seconds_count{uri="/api/data"}[5m]))
Allowed requests
ratelimiter_requests_allowed_total
Blocked requests
ratelimiter_requests_blocked_total
Request rate
sum(rate(http_server_requests_seconds_count{uri="/api/data"}[5m]))
Prometheus UI
http://localhost:9090
Grafana Dashboard
http://localhost:3000
Login:
Username: admin
Password: admin
Run the full stack:
docker compose up --build
Services started:
| Service | Port |
|---|---|
| Spring Boot API | 8080 |
| Redis | 6379 |
| Prometheus | 9090 |
| Grafana | 3000 |
Client request
GET /api/admin
Header: X-User-Id: admin123
Redis key generated
rate_limit:admin123:/api/admin
Redis stores timestamp in Sorted Set.
Old entries are removed automatically to maintain the sliding window.
This project demonstrates:
- distributed rate limiting
- sliding window algorithms
- Redis Sorted Set based request tracking
- API request throttling
- observability using Prometheus
- monitoring dashboards with Grafana
- containerized backend services
- scalable backend architecture
Potential enhancements:
- token bucket algorithm
- Redis Lua script atomic rate limiting
- API gateway integration
- Kubernetes deployment
- multi-node load testing
Rahul Reddy
GitHub
https://github.com/rahulreddyin

