patterntypescriptexpressModerate
Rate Limit Headers: Standard Communication to Clients
Viewed 0 times
rate limit429RateLimit-RemainingRetry-Afterthrottlingexpress-rate-limit
Problem
APIs implement rate limiting but don't communicate limits to clients. Clients don't know when to back off, how many requests remain, or when limits reset — leading to unnecessary 429 errors and poor retry logic.
Solution
Return standard rate limit headers with every response.
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 100,
standardHeaders: 'draft-7', // Use RateLimit headers (IETF draft)
legacyHeaders: false,
handler: (req, res) => {
res.status(429).json({
type: 'https://api.example.com/errors/rate-limit',
title: 'Too Many Requests',
status: 429,
retryAfter: res.getHeader('Retry-After'),
});
},
});
// Headers returned on each response:
// RateLimit-Limit: 100
// RateLimit-Remaining: 47
// RateLimit-Reset: 1699900800
// Retry-After: 34 (only on 429)Why
Without rate limit headers, clients must guess limits and implement exponential backoff without context. Standard headers let clients implement proactive throttling and efficient retry.
Gotchas
- The IETF RateLimit header draft (draft-7) differs from the widely used X-RateLimit-* convention — check which your clients expect.
- Always include Retry-After on 429 responses so clients know exactly when to retry.
- Rate limits should be per-user or per-API-key, not per-IP, for authenticated APIs.
Revisions (0)
No revisions yet.