Prerequisites
- Application running on a Qovery managed cluster
- Basic understanding of NGINX rate limiting
Understanding NGINX Rate Limiting
NGINX rate limiting protects your services by controlling the rate of requests. For detailed information, see NGINX’s official documentation on rate limiting.Initial Setup
Configure Test Service
We’ll usejmalloc/echo-server Docker image for testing:
- Image:
jmalloc/echo-server - Port: 80

Configure NGINX Replicas
Rate limits apply per NGINX instance. For demonstration, set replicas to 1 (not recommended for production):- Go to Cluster Settings → Advanced Settings
- Find
nginx.controller.replicas - Set value to
1

Without rate limits: 100 req/sec × 500 requests = 100% success rate (all HTTP 200 responses)
Global Rate Limit Implementation
Declare at Cluster Level
Configurenginx.controller.http_snippet:
$server_name: Rate limit key (can use$http_x_forwarded_forfor IP-based limits)zone=global:10m: Zone name with 10MB memory allocationrate=10r/s: 10 requests per second threshold

Apply Rate Limit
Configurenginx.controller.server_snippet:

Deploy Changes

Enhancement with Burst
Addingburst=20 nodelay; permits 20-request bursts without delays:
Test Results
Load test: 100 req/sec for 500 total requests Result:- 452 HTTP 503 rejections
- 48 HTTP 200 acceptances (~9.6 req/sec)

Service-Level Rate Limit
Configure rate limiting at the service level using advanced settings: Configuration Settings:network.ingress.nginx_limit_rps: Rate in requests/secondnetwork.ingress.nginx_limit_rpm: Rate in requests/minutenetwork.ingress.nginx_limit_burst_multiplier: Burst multiplier (default: 5)
Example: 10 Requests/Minute with 2× Burst

When both RPM and RPS are set, both rate limits will be enforced simultaneously. Traffic will be restricted based on whichever limit is hit first.
Deploy Service

Test Results
- 479 HTTP 503 rejections
- 21 HTTP 200 acceptances

Custom Header-Based Rate Limiting
Implement rate limiting based on custom HTTP headers.Cluster Configuration
Configurenginx.controller.http_snippet:

Service Configuration
Configurenetwork.ingress.nginx_controller_configuration_snippet:

burst=2: Permits 2 extra requests beyond rate limit during short burstsnodelay: Disables request queuing; excess requests rejected immediately
Deploy and Test

- 473 HTTP 503 rejections
- 27 HTTP 200 acceptances (~5.4 req/sec with burst)


Additional Configuration
Custom HTTP Status Code
Configurenginx.controller.limit_request_status_code:
- Default: HTTP 503
- Alternative: HTTP 429 (commonly used for rate limiting)


Connection Limits
Configurenetwork.ingress.nginx_limit_connections at service level to limit concurrent connections from single IP addresses.
Summary
Global Rate Limit
Global Rate Limit
Applied at cluster level, affects all services. Best for protecting the entire cluster from abuse.
Service-Level Rate Limit
Service-Level Rate Limit
Applied per service using
nginx_limit_rps or nginx_limit_rpm. Best for protecting individual services.Header-Based Rate Limit
Header-Based Rate Limit
Applied based on custom HTTP headers. Best for API key-based rate limiting and multi-tenant applications.
Connection Limits
Connection Limits
Limits concurrent connections per IP. Best for preventing connection exhaustion attacks.