Skip to content

Instantly share code, notes, and snippets.

@ayourtch
Created November 24, 2024 21:05
Show Gist options
  • Save ayourtch/abf5c9255634e3a347049c57a46a8831 to your computer and use it in GitHub Desktop.
Save ayourtch/abf5c9255634e3a347049c57a46a8831 to your computer and use it in GitHub Desktop.
Experiment rate limit in nginx suggested by Claude AI
# Define a shared memory zone to store rate limit state
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
# Define a map to store the last failed attempt timestamp
map $remote_addr $last_failed_time {
volatile;
default 0;
}
# Define a map to store the retry count
map $remote_addr $retry_count {
volatile;
default 0;
}
# Calculate delay based on retry count (2^retry_count - 1)
map $retry_count $delay {
default 0;
"0" 0;
"1" 1;
"2" 3;
"3" 7;
"4" 15;
"5" 31;
}
server {
listen 80;
server_name example.com;
location / {
# Check if we need to delay based on previous 429
if ($last_failed_time) {
set $wait_time 0;
# If Retry-After header was present in last response
if ($http_retry_after) {
set $wait_time $http_retry_after;
}
# Else use exponential backoff
if ($wait_time = 0) {
set $wait_time $delay;
}
# Calculate if enough time has passed
set $current_time $time_iso8601;
if ($current_time - $last_failed_time < $wait_time) {
return 429 'Too Many Requests\n';
}
}
# Apply rate limiting
limit_req zone=req_limit_per_ip burst=5 nodelay;
# Track failed attempts
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
# If request is rate limited (429)
error_page 429 = @handle_429;
# Proxy to backend
proxy_pass http://backend;
}
location @handle_429 {
# Increment retry count
set $retry_count_new $retry_count;
if ($retry_count_new != "") {
set $retry_count_new $retry_count;
add_header X-Retry-Count $retry_count_new;
}
# Store timestamp of this failure
set $last_failed_time $time_iso8601;
# Return 429 with appropriate headers
add_header Retry-After $delay;
return 429 'Too Many Requests\n';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment