Home » Laravel » How to Fix 429 Too Many Requests in Laravel

How to Fix 429 Too Many Requests in Laravel

If you make too many requests to the Laravel API, you may see an error with the “429 Too Many Requests” message. By default, Laravel has a limit on the number of requests per minute for all API endpoints. This is done to protect the API from excessive load.

However, sometimes it is still necessary to slightly increase this limit. Therefore, in this short article, we will look at how to fix the 429 too many requests in Laravel.

Fixing 429 Too Many Requests Exception in Laravel

As mentioned before, the number of requests is limited for all API routes. If you make more than 60 HTTP requests per minute, you will see the following error message with a 429 status code:

This is configured in app/Http/Kernel.php for the api route group. You can find the throttle:api or \Illuminate\Routing\Middleware\ThrottleRequests::class.’:api’. line in the $middlewareGroups variable there:

Here throttle – is the name of the middleware, and api is the name of the rate limiter which is used for applying the limit. The full class name of the middleware is \Illuminate\Routing\Middleware\ThrottleRequests, but it has short alias throttle, which is configured below in the same file. The api part is the rate limiter name. This middleware can accept not only a rate limiter but also just limits as two arguments. We’ll look at this in detail later.

Let’s take a look at the rate limiter. Its definition is located in the app/Providers/RouteServiceProvider.php file.

Here, you can see that the default throttle limit is 60 requests per second, and it is configured using the perMinute() method. You can customize the value here, and it will be applied to the entire project. For example, let’s set 90 requests:

app/Providers/RouteServiceProvider.phpreturn Limit::perMinute(90)->by($request->user()?->id ?: $request->ip());

You can also make a custom rate limiter with different names and apply api limits for specific routes or a whole project. If you don’t want to modify the RateLimiter configuration, you can modify middleware arguments directly in app/Http/Kernel.php. Moreover, you can delete this middleware from the api group to completely turn off rate limiting, but it is not recommended. You can replace the api string with two parameters: the first parameter is the number of requests per second and the number of minutes to wait after the limit is exceeded. For example, 90 requests per second and wait 1 minute:


All modifications described above apply globally to the entire project. If you need to remove the limit only for a particular route or group of routers, you should use the withoutMiddleware() method to remove the default middleware. For example:

routes/api.phpRoute::get("/request/first", function () { return response()->json(["success" => true]); })->withoutMiddleware("throttle:api");

The best way to ensure the middleware was removed is by printing all middleware applied to your route. For example:

routes/api.phpRoute::get("/middleware", function (Illuminate\Http\Request $request, \Illuminate\Routing\Router $router) { return response()->json($router->resolveMiddleware( $request->route()->gatherMiddleware(), $request->route()->excludedMiddleware() )); })->withoutMiddleware("throttle:api");

It is not enough to print a middleware list using the gatherMiddleware() method because it does not expand middleware from groups, and you will see only the group name.

Pay attention that in most cases, you must pass to withoutMiddleware() not only middleware name or alias but also arguments which were specified in app/Http/Kernel.php. The name can be a full or alias. It does not matter because Illuminate\Routing\Router converts all aliases in class names automatically in the resolveMiddleware() method:

You can re-add throttle middleware with required parameters after calling withoutMiddleware() to change limits. For example, let’s allow only 300 requests per minute:

routes/api.phpRoute::get("/request/second", function () { return response()->json(["success" => true]); }) ->withoutMiddleware("throttle:api") ->middleware("throttle:300:1");

If you use Laravel 10, you can specify limits through named parameters in the with() static method. It will make your code more readable and understandable:

routes/api.phpRoute::get("/request/second", function () { return response()->json(["success" => true]); }) ->withoutMiddleware("throttle:api") ->middleware( \Illuminate\Routing\Middleware\ThrottleRequests::with( maxAttempts: 300, decayMinutes: 1 ) );

As you can see on the screenshot above, Laravel adds to response headers X-RateLimit-Limit and X-RateLimit-Remaining when the rate limited is applied to a route. You can use them to ensure that your changes work. The following screenshot shows headers for a route with the rate-limiting feature disabled:

Wrapping Up

In this article, I have shown how to turn off api limits for the entire project or a specific route and fix the 429 too many requests in Laravel. If you often have issues with a large number of requests in a short period of time, consider using web sockets. This will reduce the load on the server, while clients will receive information about updates faster.

2 thoughts on “How to Fix 429 Too Many Requests in Laravel”

  1. In Laravel 10 in Kernel.php they declare it like this:
    IlluminateRoutingMiddlewareThrottleRequests::class . ‘:api’,
    How am I supposed to insert it into my Route?
    withoutMiddleware(“throttle:api”) didn’t seem to work
    neither do
    ->withoutMiddleware(IlluminateRoutingMiddlewareThrottleRequests::class . ‘:api’)

    • Both ways that you provided will work in Laravel 10. Code for middleware filtering is located in Illuminate\Routing\Router::resolveMiddleware(). It automatically converts all aliases into class names. Important only middleware parameters, they should be the same as in definition. You can use the following code to check what exactly middleware is applied to the current route:

      Route::get("/middleware", function (Illuminate\Http\Request $request, \Illuminate\Routing\Router $router) {


Leave a Comment

Exit mobile version