Engineering Note
We added rate limiting to protect our Rails API. Then we realised we were blocking real customers too.
Rate limiting sounds simple:
Allow X requests per minute.
Block everything above it.
Production is rarely that simple.
We had APIs serving different types of traffic:
* Normal user requests
* Mobile clients
* Background jobs
* Third-party integrations
* Unexpected traffic spikes
Using one limit for everything created problems.
Some customers were hitting limits during legitimate traffic spikes, while abusive traffic was still getting through other endpoints.
So we changed the approach:
* Different limits for different API types
* Customer-level limits instead of only IP-based limits
* Separate limits for expensive endpoints
* Clear 429 responses with retry information
* Monitoring for rejected requests
The result?
We reduced unnecessary API load by around 35% without creating noticeable impact for normal customers.
The important learning:
Rate limiting isn't about blocking traffic.
It's about protecting system capacity without punishing legitimate usage.
A good limit protects your Rails application.
A bad one becomes a customer problem.
Allow X requests per minute.
Block everything above it.
Production is rarely that simple.
We had APIs serving different types of traffic:
* Normal user requests
* Mobile clients
* Background jobs
* Third-party integrations
* Unexpected traffic spikes
Using one limit for everything created problems.
Some customers were hitting limits during legitimate traffic spikes, while abusive traffic was still getting through other endpoints.
So we changed the approach:
* Different limits for different API types
* Customer-level limits instead of only IP-based limits
* Separate limits for expensive endpoints
* Clear 429 responses with retry information
* Monitoring for rejected requests
The result?
We reduced unnecessary API load by around 35% without creating noticeable impact for normal customers.
The important learning:
Rate limiting isn't about blocking traffic.
It's about protecting system capacity without punishing legitimate usage.
A good limit protects your Rails application.
A bad one becomes a customer problem.