๐ซ What is HTTP 429 – Too Many Requests?
HTTP 429 means the client has sent too many requests in a given amount of time (rate limiting). Laravel triggers this when requests exceed configured limits โ typically to protect your app from abuse or overloading.
๐ง Common Scenarios Causing 429 in Laravel
- Multiple users behind the same IP (e.g., via NAT, load balancer, or Docker)
- API calls from microservices hitting Laravel endpoints
- Performance testing or bots
- Poorly configured
throttlemiddleware - Mobile or IoT apps making rapid requests
๐ Laravel Rate Limiting Basics
Laravel uses the ThrottleRequests middleware:
Route::middleware('throttle:60,1')->group(function () {
Route::get('/api/data', 'DataController@index');
});
Code language: PHP (php)
This allows 60 requests per minute per user/IP.
โ Solutions to Fix or Improve Rate Limiting
โ 1. Increase Rate Limit Per Route
Route::middleware('throttle:300,1')->get('/api/resource', 'ResourceController@index');
Code language: PHP (php)
Allows 300 requests per minute
โ 2. Define Custom Rate Limiters (Laravel 8+)
In RouteServiceProvider.php:
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Cache\RateLimiting\Limit;
RateLimiter::for('custom-api', function ($request) {
return Limit::perMinute(200)->by(optional($request->user())->id ?: $request->ip());
});
Code language: PHP (php)
Then use:
Route::middleware('throttle:custom-api')->group(...);
Code language: PHP (php)
โ 3. Throttle Based on User ID (Not IP)
Limit::perMinute(300)->by($request->user()?->id ?: $request->ip());
Code language: PHP (php)
This prevents shared IPs (like containers or offices) from hitting the global rate limit.
โ 4. Disable Rate Limiting for Internal IPs
RateLimiter::for('api', function ($request) {
if (in_array($request->ip(), ['127.0.0.1', '172.20.0.2'])) {
return Limit::none();
}
return Limit::perMinute(60);
});
Code language: PHP (php)
โ 5. Handle 429 Gracefully in Frontend/Microservices
Add retry logic:
if (response.status === 429) {
const retryAfter = response.headers['retry-after'] || 1;
await new Promise(r => setTimeout(r, retryAfter * 1000));
retryRequest();
}
Code language: JavaScript (javascript)
โ 6. Use Laravel Job Queues for Heavy APIs
Offload rate-heavy tasks to queues:
dispatch(new ProcessWebhook($data));
Code language: PHP (php)
Avoid synchronous spikes by spreading processing.
โ 7. Track and Log 429 Errors
Use global exception handler:
public function render($request, Throwable $exception)
{
if ($exception instanceof ThrottleRequestsException) {
Log::warning('Rate limit exceeded', [
'ip' => $request->ip(),
'url' => $request->url(),
]);
}
return parent::render($request, $exception);
}
Code language: PHP (php)
โ 8. Use Redis for Smarter Limiting
Laravel supports Redis-backed rate limits:
'limiter' => env('CACHE_DRIVER', 'redis'),
Code language: PHP (php)
Redis allows burst handling and high-speed checks.
โ 9. Use API Gateway or Reverse Proxy Rate Limiting
If using services like:
- NGINX:
limit_req_zone,limit_req - AWS API Gateway: rate/usage plans
- Cloudflare: Rate Limiting Rules
Apply rate limits before Laravel even sees the request.
โ 10. Implement Client Token Quotas
Track usage per API token/user key:
- Use Laravel Passport or Sanctum
- Store request counts in Redis/DB
๐ Microservices Specific Tips
| Problem | Solution |
|---|---|
| Burst API requests | Queue or cache throttle |
| Services on same IP | Use unique user tokens per service |
| Stateless retry loops | Add jitter or exponential backoff |
| API aggregator overload | Add inter-service caching |
๐ Inspect Rate Limit Headers
Laravel adds these headers:
X-RateLimit-LimitX-RateLimit-RemainingRetry-After
Log or inspect them to tune performance or debug issues.
๐ Summary
| Solution | Use Case |
|---|---|
throttle:200,1 | General increase |
| Custom limiter | User-based, IP-based |
| Disable for internal IPs | Microservices, local traffic |
| Queuing heavy jobs | Async deferral |
| Redis backend | Fast & scalable |
| Gateway limits | Layer 7 protection |
๐ Final Thoughts
429 errors protect your app โ but when wrongly configured, they block real users and services. Laravel gives you the tools to fine-tune rate limits by IP, user, or context. For microservices, coordination is key: throttle at the API gateway and queue jobs internally.
Let me know if you want examples with Laravel Sanctum, Redis-backed rate limits, or job queue implementations!
I’m Rajesh Kumar, a DevOps, SRE, DevSecOps, Cloud, and Platform Engineering expert passionate about sharing practical knowledge, real-world experiences, and industry best practices. I have worked at Cotocus and regularly write about technology, travel, investing, health, product reviews, and digital marketing through my various platforms.
I publish technical articles at DevOps School, travel stories at Holiday Landmark, stock market insights at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow, and SEO and digital marketing strategies at Wizbrand.
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services โ all in one place.
Explore Hospitals