The plugin's limit_by defaults to consumer. Without an auth plugin there is no consumer, so it silently falls back to the client IP - which behind a load balancer is one shared bucket.
curl -X POST http://localhost:8001/routes/api/plugins \
--data name=rate-limiting \
--data config.minute=100 \
--data config.policy=redis \
--data config.redis_host=redis.internal \
--data config.limit_by=consumer # consumer | credential | ip | header | path
# Trusting the client IP behind a proxy needs this in kong.conf:
trusted_ips = 10.0.0.0/8
real_ip_header = X-Forwarded-For
real_ip_recursive = on
Response headers on every request:
X-RateLimit-Limit-Minute: 100
RateLimit-Remaining: 87
When exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
# Without trusted_ips, limit_by=ip sees the load balancer's address and
# throttles every one of your users as if they were one caller.
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-08-25