Rate Limit Policies
Global Rate Limit
Applies to all authenticated endpoints:- Limit: 20 requests per 60 seconds
- Applies to:
GET /v1/price/:coinIdGET /v1/price/:coinId/history
Login Rate Limit
Stricter limit for authentication endpoint:- Limit: 5 requests per 60 seconds
- Applies to:
POST /auth/login
Excluded Endpoints
The following endpoints are not rate limited:/docs- Swagger documentation UI/docs-json- Swagger OpenAPI JSON specification
How Rate Limiting Works
Request Tracking
Rate limits are tracked per user or IP address:- Authenticated requests: Tracked by user ID from JWT token (
user:<sub>) - Unauthenticated requests: Tracked by IP address (
ip:<address>)
req.ip(primary)X-Forwarded-Forheader (for requests behind proxies/load balancers)socket.remoteAddress(fallback)
Redis-Backed Storage
Rate limit counters are stored in Redis using the@nest-lab/throttler-storage-redis package. This provides:
- Distributed rate limiting: Counters are shared across all API instances
- Automatic expiration: Counters reset after the TTL window (60 seconds)
- High performance: Redis provides fast read/write operations for rate limit checks
Redis is required for the API to function. If Redis is unavailable, requests will fail with a
503 Service Unavailable error.Configuration
Rate limits are configurable via environment variables:| Variable | Default | Description |
|---|---|---|
THROTTLE_TTL_MS | 60000 | Time window in milliseconds (60 seconds) |
THROTTLE_GLOBAL_LIMIT | 20 | Global request limit per window |
THROTTLE_LOGIN_LIMIT | 5 | Login endpoint limit per window |
REDIS_URL | Required | Redis connection string for rate limit storage |
Example Configuration
Rate Limit Responses
When Rate Limit is Exceeded
When you exceed the rate limit, the API returns:When Rate Limiter is Unavailable
If Redis is unavailable, the API returns:Best Practices
Handling Rate Limits
- Implement exponential backoff: Wait progressively longer between retries
- Cache responses: Store price data locally to reduce API calls
- Use batch windows: The price endpoint batches same-coin requests automatically
- Monitor your usage: Track your request patterns to stay within limits
Authentication Benefits
Authenticated requests are tracked by user ID, which provides:- Consistent limits: Rate limits follow your user account, not your IP
- Multi-instance support: Works correctly behind load balancers or when changing networks
- Better tracking: Clear visibility into per-user usage patterns
Multi-Instance Behavior
When running multiple API instances:- All instances share the same Redis storage
- Rate limit counters are synchronized across instances
- A request to any instance counts toward your total limit
- No coordination delay - Redis operations are near-instantaneous
Example Scenario
Implementation Details
The rate limiting is implemented using a custom throttler guard (AppThrottlerGuard) that:
- Extends NestJS’s
ThrottlerGuard - Extracts JWT tokens from the
Authorizationheader - Verifies tokens and uses the
subclaim for user tracking - Falls back to IP-based tracking for invalid/missing tokens
- Excludes documentation endpoints from rate limiting
- Wraps storage errors in
ServiceUnavailableException
src/common/guards/app-throttler.guard.ts