Features β’ Architecture β’ Getting Started β’ Docker β’ API β’ Benchmark
A production-ready distributed Rate Limiter Service built using Node.js, Express.js, Redis, PostgreSQL, Prisma ORM, Docker, and Nginx.
Rate Limiter Service is a production-ready backend application that implements the Token Bucket Algorithm to efficiently control API traffic. The project is horizontally scalable using multiple Node.js instances behind an Nginx Load Balancer while maintaining a shared bucket state through Redis and persistent configuration in PostgreSQL.
- Implements the Token Bucket Algorithm for efficient API rate limiting.
- Supports configurable capacity and refill rate for each client.
- Provides Admin APIs to create, update, retrieve, and delete client configurations.
- Maintains persistent client configurations in PostgreSQL.
- Stores bucket state in Redis for fast read/write operations.
- Caches client configurations in Redis to minimize unnecessary database queries.
- Automatically refills tokens based on the configured refill rate.
- Designed to handle high request throughput with low latency.
- Supports horizontal scaling with multiple Node.js application instances.
- Uses Nginx Round Robin Load Balancer to distribute incoming traffic.
- Ensures consistent rate limiting across all application instances using shared Redis and PostgreSQL.
- Fully containerized using Docker.
- Multi-container orchestration with Docker Compose.
- Automatically applies pending Prisma migrations during container startup.
- Input validation using Zod.
- Structured request logging with Pino.
- Unique request IDs for easier debugging and tracing.
- Graceful shutdown to safely close database and Redis connections.
- Interactive API documentation using Swagger UI.
- Environment-based configuration using .env.
- Clean layered architecture (Controllers β Services β Repositories).
- Performance tested using Autocannon.
The application follows a distributed architecture to provide high performance, scalability, and consistency.
- A client sends a request to the Nginx Load Balancer.
- Nginx distributes incoming traffic across multiple Node.js application instances using the Round Robin strategy.
- Each application instance retrieves the client configuration from Redis Cache. If the configuration is unavailable, it is fetched from PostgreSQL and cached for future requests.
- The current bucket state is stored and updated in Redis, enabling all application instances to share the same rate-limiting state.
- The Token Bucket Algorithm determines whether the request should be allowed or rejected based on the available tokens.
- The updated bucket state is written back to Redis, and the API responds with the remaining token count.
- β‘ Fast β Redis provides low-latency access for bucket state and cached client configurations.
- π Scalable β Multiple application instances can be added behind Nginx without changing the application logic.
- π Consistent β Shared Redis ensures all instances enforce the same rate limits.
- ποΈ Reliable β PostgreSQL acts as the persistent source of truth for client configurations.
- π³ Portable β Docker Compose enables the complete stack to run consistently across development and deployment environments.
Node.js β’ Express.js β’ PostgreSQL β’ Redis β’ Prisma ORM β’ Docker β’ Nginx β’ Git β’ GitHub β’ Postman β’ VS Code β’ Swagger UI β’ Zod β’ Pino β’ Autocannon
Rate-Limiter-Service
β
βββ π assets # README images
βββ π nginx # Nginx Load Balancer configuration
βββ π prisma # Prisma schema & migrations
βββ π src
β βββ config # Database, Redis & Logger configuration
β βββ controllers # Request handlers
β βββ middlewares # Validation & logging middlewares
β βββ repositories # Database access layer
β βββ routes # API routes
β βββ services # Business logic
β βββ utils # Utility functions
β βββ validations # Zod validation schemas
β βββ app.js
β βββ server.js
β
βββ .dockerignore
βββ .env.example
βββ .gitignore
βββ Dockerfile
βββ docker-compose.yml
βββ package.json
βββ README.md
Before running the project, ensure you have the following installed:
- Node.js (v22 or later)
- PostgreSQL
- Redis
- Docker & Docker Compose (optional, recommended)
git clone https://github.com/<your-username>/Rate-Limiter-Service.git
cd Rate-Limiter-Servicenpm installCreate a .env file in the project root using .env.example.
Development
"npm run dev" or "nodemon"Production
npm startBuild and start all services
docker compose up --buildRun in detached mode
docker compose up -dStop all containers
docker compose downThe Docker Compose setup includes:
- Nginx β Load Balancer
- Node.js App 1
- Node.js App 2
- Redis
- PostgreSQL
| Method | Endpoint | Description |
|---|---|---|
POST |
/admin/client |
Create a new client configuration |
GET |
/admin/client |
Retrieve all client configurations |
GET |
/admin/client/:clientId |
Retrieve a specific client configuration |
PUT |
/admin/client/:clientId |
Update an existing client configuration |
DELETE |
/admin/client/:clientId |
Delete a client configuration |
| Method | Endpoint | Description |
|---|---|---|
POST |
/rate-limiter/check |
Validate request and consume a token using the Token Bucket Algorithm |
Interactive API documentation is available through Swagger UI, allowing you to explore and test all endpoints directly from the browser.
Default URL
http://localhost:3000/api-docs
The service was benchmarked using Autocannon to evaluate throughput and latency under concurrent load.
npx autocannon -c 200 -d 20 -m POST \
-H "Content-Type: application/json" \
-b '{"clientId":"docker-test"}' \
http://localhost:3000/rate-limiter/checkThe benchmark demonstrates the application's ability to handle concurrent requests while maintaining low response latency through Redis caching and horizontal scaling with Nginx.

