Hi, I have been trying for the better part of a week to diagnose why my Laravel 5.7 based API has suddenly started having issues with throttling (429: Too Many Requests). I have (for years) logged every request via a custom middleware and I don’t see nearly enough requests to constitute any throttling. To confirm this I have run Wireshark on both the affected client and the web server during the affected periods. This confirmed that maybe 20 requests happened before my service started responding with the 429: Too Many Requests. I’m lost as to how to proceed with troubleshooting.
Environment:
IIS 10, PHP 7.1.26, Laravel 5.7.25.
Kernel.php
'api' => [
'throttle:120,1',
'bindings',
AppLibraryCobaltHttpMiddlewareLogMiddleware::class,
],
Thanks in advance.
Have you added logging to the ThrottleRequests middleware?
1 reply
Hi, there.
I have similar with this problem and I fixed it.
In RouteServiceProvider.php,
protected function configureRateLimiting()
{
RateLimiter::for(‘api’, function (Request $request) {
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
});
RateLimiter::for('seventy', function () {
return Limit::perMinute(70); //You can change this number to avoid 429 error.
});
}
this code is for Laravel8.0.
If this code help you, I appreciated it.
No, but that is a great idea for a next step. I will update when I know more.
0 replies
@marlboro if you posted your question elsewhere, could you link it? I’m having similar issues.
0 replies
@Helveg No, but it’s a bug or configuration issue with either PHP or Laravel. Originally this particular API was only called by one device and there were no issues. We added a second device and suddenly the 429’s started. I would have expected each device (unique IP’s) to get N requests before they got throttled. That is not the case or I would not be having issues.
I ended up just increasing the throttle value large enough to make it stop issuing 429’s. It’s hacky, and I hate it, but I had no other choice. Post a link if you get help somewhere else.
0 replies
I got the same issue, my throttle was set to 270, and it is still happening, I believe it should be an issue with laravel, because there is no way for me to have 270 calls to my api from one device of testing in 1 minute
0 replies
I’m currently converting my web app UI to an SPA and running into the same issue. I get the error sporadically when I’m sure I’m nowhere near the limit.
1 reply
This can happen if you have frontend bugs, happened to me as well during infinite reload and SPA was making AJAX calls all the time. Check and fix your JS as well
Just posting this if anyone else was getting the same error.
I was using Memcached as my cache store and after debugging through telnet, I found that it was never expiring my keys. I had to manually restart the service to fix the problem.
Homestead with memcached version 1.5.6.
1 reply
@EvilLooney Your comment seems the most reasonable!
I’m also having this issue with Laravel 8 and PHP8.1 with Memcached on alpine docker.
Were you able to resolve this issue on your without having to restart the caching service?
Thanks!
Did anyone find out the problem? We’re facing same issues here.
0 replies
Same issue. Laravel 5.7, IIS10, PHP 7.3.
0 replies
It’s a sporadic recurring issue, all or most of us reporting the issue face it in controlled testing environments as well where we’re sure to be nowhere near the limit. @driesvints can we get some feedback, troubleshooting tips or a timeline on this?
Is there maybe a way that we can log every time a supposed request gets us closer to the throttle limit to debug it?
0 replies
Also a firefighting tip: you can clear the throttle if it hits your production environment with:
13 replies
@Helveg Yes, logging can be done on the client. Look in the headers of the response. It should look something like this:
DK@DK:~$ curl -I -X POST http://localhost/fake/path
HTTP/1.1 400 Bad Request
Date: Tue, 01 Oct 2019 20:29:45 GMT
Server: Apache/2.4.39 (Fedora) OpenSSL/1.1.1b
X-Powered-By: PHP/7.2.19
Cache-Control: no-cache, private
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Connection: close
Transfer-Encoding: chunked
Content-Type: application/json
You’re looking for X-RateLimit-Limit and X-RateLimit-Remaining
The issue I was having was in the Kernel. Inside of $middlewareGroups under api, ‘throttle:120,1’ was not being respected. As seen in the headers above, it was always set to 60. Here’s what I needed to do to fix it:
/* ... */ protected $middlewareGroups = [ 'web' => [ /* .. */ ], 'throttle' => ['throttle:99,1'], //No idea why, but this works! 'api' => [ 'throttle:5000,1', //These values did not change the throttle limit. 'bindings', ], ]; /* ... */
I found this by adding some dump()’s here: https://github.com/laravel/framework/blob/5.7/src/Illuminate/Routing/MiddlewareNameResolver.php#L29
5 replies
I think the throttle under api section only affects routes for API.
‘throttle’ => [‘throttle:99,1’], //No idea why, but this works!
This works because the throttle middleware is registered here for the /token route.
You just saved my multimillion dollars project.
thanks for this wonderful answer
Also a firefighting tip: you can clear the throttle if it hits your production environment with:
worked thanks
0 replies
I had to remove the throttling from the api middleware in appHttpKernel.php. Just delete the following line in appHttpKernel.php
'throttle:60,1',
0 replies
That’s not very good advice: the throttle is there for good reasons. You’re now vulnerable to being spammed with requests such as login requests. Never advice to completely disable security measures even if they aren’t functioning properly
0 replies
That’s not very good advice: the throttle is there for good reasons. You’re now vulnerable to being spammed with requests such as login requests. Never advice to completely disable security measures even if they aren’t functioning properly
I do agree that any good system architecture should incorporate the necessary security measures. However, these measures should be supplemented with a good understanding of the internals. My response was in the context of the specific OP query assuming they know what they are doing, and not a general system architecture advice.
Also, most apps would use the web middleware for website functions such as Login. Laravel 6.x does not enforce any throttling for this middleware out-of-the box so it would be vulnerable to spamming, unless the developer knows what they are building and incorporates the necessary guards.
Your thoughts are absolutely valid and I appreciate you providing the helpful perspective here. I just wanted to make sure that people who find the solution helpful would know what they are working with.
Cheers!
0 replies
how to increase request limit in laravel.
1 reply
in appHttpKernel.php
‘api’ => [
'throttle:2,1', //means 2 requests per minute we can increase it to as we want like 200000
],
FWIW — I was causing this issue with the «infinite loop» situation with useEffect() in React. I added the empty array to stop triggering repeated requests.
2 replies
Hi @sloan58 Can you explain what exactly you did? php artisan cache:clear didn’t worked for me. I think it is because of useEffect() in my react app.
Thanks in advance. 
Hi @Rizzeol,
Sure thing! There’s a second parameter you can pass to useEffect to specify the data you want to watch so that useEffect fires when that data changes. If you pass an empty array (don’t watch anything), it won’t keep re-rendering when the component updates.
useEffect(() => { doSomethingOnce(); }, []);
i do not recommend removing throttling, it’s a huge security risk,like DOD and DDOS attacks
2 replies
You can, and should rate limit using the webserver, not using PHP itself. It’s one of the worst decisions ever. You won’t avoid DDOS using Laravel’s rate limiting, it still needs to accept the request, check if it’s over the limit and then send the output. You effectively did nothing to prevent DDOS.
The only sane decision is to approach the rate limiting without involving PHP as you want the request to be denied before it even makes PHP do any processing at all.
Throttling via nginx is trivial, easy to understand and best part: actually works.
Nginx throttling is good for sure, but that doesn’t mean Laravel throttling is bad. There are different use cases for both. For instance, you may be able to throttle by IP address with Nginx, but throttling by username or a combination of username/IP or say user ID would be a better case for Laravel.
Also, DDOS attacks are distributed. Even Nginx can’t save you from DDOS. There are other strategies for those kinds of attacks.
Hello,
I tried to comment
//'throttle' => IlluminateRoutingMiddlewareThrottleRequests::class,
and
'api' => [ //'throttle:60:1', IlluminateRoutingMiddlewareSubstituteBindings::class, ],
It worked for me. Sorry for the typo
0 replies
Hi everyone, so, is there a proper way to fix this issue without disabling throttle if I’m using Sanctum for my API authentication and Fortify for my web authentication?
0 replies
My guess is that you’re using a login proxy to passport so server is requesting tokens rather than the user. You should disable the throttling specifically for localhost (ips from server).
0 replies
Am using Laravel 8 for my API and I have a couple of clients accessing my API. Recently I started to get 429 HTTP response after I added some new clients.
What I found out is that, by default rate limit is not IP specific, so when I added more clients (each client has its own IP) I started to get 429. I modified rate limit to use IP and this solved the issue for me.
This is how I did that.
File path app/Providers/RouteServiceProvider.php
Before (IP agnostic rate limiting)RateLimiter::for('api-rate-limit', function (Request $request) { return Limit::perMinute(120); });After (IP aware rate limiting)
RateLimiter::for('api-rate-limit', function (Request $request) { return Limit::perMinute(120)->by($request->ip()); });
More information on how to do this with Laravel 8 can be found here. And also there is a nice explanation about it in Laracasts. It is also possible to set up rate limiting per route, (for example api/images) instead of a route group like api/.
Also to keep in mind is that this is Laravel 8 way of rate limiting. For versions below 8, rate limiting is done differently. But I assume it is possible to rate limit per IP and per route in versions below 8.
Also I think, in general, it is worthwhile to try out IP specific and/or route specific rate limit instead of removing rate limit completely or increasing rate limit to a very high value.
1 reply
Since you can get people on the same IP, you can also change it to use the Bearer token of the user.
This is how twitter API does it.
In laravel version above 7.x php artisan optimize:clear will help you
1 reply
if someone is using Fortify there is a ‘limiters’ of five request per minute. Just comment the ‘login’ it!
/*
|--------------------------------------------------------------------------
| Rate Limiting
|--------------------------------------------------------------------------
|
| By default, Fortify will throttle logins to five requests per minute for
| every email and IP address combination. However, if you would like to
| specify a custom rate limiter to call then you may specify it here.
|
*/
'limiters' => [
// ‘login’ => ‘login’,
‘two-factor’ => ‘two-factor’,
],
protected $middlewareGroups = [
'web' => [
AppHttpMiddlewareEncryptCookies::class,
IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
IlluminateSessionMiddlewareStartSession::class,
// IlluminateSessionMiddlewareAuthenticateSession::class,
IlluminateViewMiddlewareShareErrorsFromSession::class,
AppHttpMiddlewareVerifyCsrfToken::class,
IlluminateRoutingMiddlewareSubstituteBindings::class,
],
'api' => [
// LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful::class,
'throttle:200,1',
IlluminateRoutingMiddlewareSubstituteBindings::class,
],
];
0 replies
I experiences this because it was IP address driven and perhaps the users internet provider reused the IP addresses of their customers making anonymous users appears to be the same person, hitting too many times.
Has anyone else experienced this?
I want to suggest it might be cloudflare related but I think the code accounts for the use of cloudflare’s request headers.
0 replies
@marlboro were you able to resolve this issue? If so, how?
Thanks man!
0 replies
Definig Rate Lminters
`use IlluminateCacheRateLimitingLimit;
use IlluminateHttpRequest;
use IlluminateSupportFacadesRateLimiter;
/**
- Configure the rate limiters for the application.
- @return void
*/
protected function configureRateLimiting()
{
RateLimiter::for(‘global’, function (Request $request) {
return Limit::perMinute(1000);
});
}`
0 replies
@marlboro I have experienced this kind of issue and made me panic. My solution is to change the CACHE_DRIVER to array in your .env file.
CACHE_DRIVER=array
0 replies
Данная ошибка говорит нам о том что мы превысили лимит запросов.
По умолчанию Laravel дает нам 60 запросов в минуту в нашему апи.
Для исправления количества запросов идем в файл
app/Http/Kernel.php
находим строчку
'throttle:6000,1',
и исправляем на нужное нам количество запросов.
Так-же можно прописать необходимый лимит на конкретный роут
['middleware' => ['WriteToDatabaseMiddleware','throttle:500,1']]
*1. The user sent too many requests within the specified time. Used to limit the rate. It can be used as an access restriction module
//Define intermediate routes
Route::middleware('throttle:login')->group(function (){
Route::get('login',[LoginController::class,'login']);
Route::get('logindo',[LoginController::class,'loginDo']);
});
The parameter in the minute is the corresponding access frequency limit
2. Register the middleware and define the middleware in the kernel to be used for middleware interception
Route::group(['prefix'=>'wechat','namespace'=>'Api','middleware'=>'checklogin'],function (){
Route::get('login',[LoginController::class,'login']);
Route::get('logindo',[LoginController::class,'loginDo']);
});
<?php
class Mysql{
private static $mysql=null;
private function __clone()
{
// TODO: Implement __clone() method.
}
private function __construct()
{
}
//entrance
public static function concent(){
if (self::$mysql===null){
try {
self::$mysql=mysqli_connect('Host number','account','password','Library name');
}catch(Exception $e){
return ['connection failed'.$e->getMessage()];
}
}
if (!self::$mysql instanceof self){
try {
self::$mysql=mysqli_connect('Host number','account','password','Library name');
}catch(Exception $e){
return ['connection failed'.$e->getMessage()];
}
}
return self::$mysql;
}
}
var_dump($obj=Mysql::concent('Host number','account','password','Library name'));
I tried everything including the Best Answer but it just didn’t work.
Therefore, not even changing the RateLimiter in the FortifyServiceProvider class.
I’d try to log in and get a 429 error after just one login attempt.
Here what was the issue for me, it was the the config/fortify.php file.
I had to change:
/*
|--------------------------------------------------------------------------
| Rate Limiting
|--------------------------------------------------------------------------
|
| By default, Fortify will throttle logins to five requests per minute for
| every email and IP address combination. However, if you would like to
| specify a custom rate limiter to call then you may specify it here.
|
*/
'limiters' => [
'login' => 'login',
'two-factor' => 'two-factor',
],
to
/*
|--------------------------------------------------------------------------
| Rate Limiting
|--------------------------------------------------------------------------
|
| By default, Fortify will throttle logins to five requests per minute for
| every email and IP address combination. However, if you would like to
| specify a custom rate limiter to call then you may specify it here.
|
*/
'limiters' => [
'login' => 5,
'two-factor' => 5,
],
And funny enough the problem is inherent in the Fortify package itself when you run:
php artisan vendor:publish --provider="LaravelFortifyFortifyServiceProvider" as per their documentation instructions.
This fundamental reason being that code within vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php is not able to correctly parse the limit:
/**
* Resolve the number of attempts if the user is authenticated or not.
*
* @param IlluminateHttpRequest $request
* @param int|string $maxAttempts
* @return int
*/
protected function resolveMaxAttempts($request, $maxAttempts)
{
if (Str::contains($maxAttempts, '|')) {
$maxAttempts = explode('|', $maxAttempts, 2)[$request->user() ? 1 : 0];
}
if (! is_numeric($maxAttempts) && $request->user()) {
$maxAttempts = $request->user()->{$maxAttempts};
}
return (int) $maxAttempts;
}
, which means, 'login' is just parsed as 0 and that’s what it returns.
Now I don’t have to run php artisan cache:clear just to test.
Skip to content
I’m using a load test tool called Artillery to simulate requests on my Laravel application. By default the Laravel application uses the IP to detect whether it should rate limit or not, so in production the varying IP addresses won’t be a problem, but for Artillery this is a problem since the requests are returning 429 errors.
I’ve tried disabling configureRateLimiting in production, but I’m still getting 429 errors.
Artillery is sending at least 3 requests per second to my api endpoint for at least 2 minutes, and then ramps up to roughly 30 a second for 15 minutes.
What am I missing to disable rate limiting here?
<?php
namespace AppProviders;
use IlluminateCacheRateLimitingLimit;
use IlluminateFoundationSupportProvidersRouteServiceProvider as ServiceProvider;
use IlluminateHttpRequest;
use IlluminateSupportFacadesRateLimiter;
use IlluminateSupportFacadesRoute;
class RouteServiceProvider extends ServiceProvider
{
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* @var string
*/
public const HOME = '/home';
/**
* The controller namespace for the application.
*
* When present, controller route declarations will automatically be prefixed with this namespace.
*
* @var string|null
*/
// protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
if (!config('artillery.enabled')) {
$this->configureRateLimiting();
}
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
}
/**
* Configure the rate limiters for the application.
*
* @return void
*/
protected function configureRateLimiting()
{
if (config('artillery.enabled')) {
return;
}
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(300)->by(optional($request->user())->id ?: $request->ip());
});
}
}
My site goes through Cliudflare and I’m sending requests to my production endpoint since this is the most realistic test.
>Solution :
In app/Http/Kernel.php Laravel has a default throttle limit for all api routes.
protected $middlewareGroups = [
...
'api' => [
'throttle:60,1', //comment means it would be no limit
],
];
Comment or increase it.

