Throttling to limit customer requests

Video thumbnail

We'll learn how to clean up the number of requests a client can make and not just caching results in Laravel, which is particularly useful for a Rest API when making queries to it or to our web application. With this, we can ensure there are no abuses where a user can make multiple requests in a short period of time, for example:

Route::middleware('throttle:60,1')->group(function () { // Your routes Here });

With the code above, we are indicating with parameters 60 and 1 that the user can send 60 requests within a 1-minute period.

What is throttling in Laravel and what is it for?

When we talk about throttling in Laravel, we are referring to the process of limiting the number of requests a client can make in a determined period of time.
It is a control measure that prevents abuse, protects resources, and improves the stability of your application.

In my case, I learned that controlling requests is not just a matter of security: it also improves the end user experience, avoiding blockages or crashes due to excessive traffic.

Laravel simplifies this task thanks to its integrated ThrottleRequests middleware, which allows you to easily define how many requests are allowed and how often.

Why limiting requests improves performance and security

Using rate limiting is an essential practice in modern APIs.

It reduces the risk of brute-force attacks, bots, or users trying to saturate your resources.

When I tested this middleware on an online raffle, I noticed that some users were trying to send automatic requests to increase their chances of winning.

By simply applying a request limit, the system stabilized and the server stopped receiving abusive traffic.

Furthermore, if you offer payment plans or subscription services, you can assign different limits based on the contracted plan, maintaining fairness among users.

How to use the ThrottleRequests middleware on your routes

Laravel allows you to apply the middleware directly to your routes.
For example:

Route::middleware('throttle:60,1')->group(function () {
 // Your routes Here
});

With this code, we indicate that a user can make up to 60 requests per minute.

This value is usually sufficient for most standard APIs.

Understanding the parameters (60,1)

The first number (60) represents the maximum number of requests.

The second (1) indicates the time interval in minutes.

Thus, throttle:60,1 means “60 requests per minute.”

You can adjust both values according to your application's needs.

What this basically means is that we are indicating how many requests the client can make in a certain time, and this certain time is expressed in minutes. Therefore, in this example, it would be 60 requests in a period of one minute, and that's practically all there is to it.

What happens when the limit is exceeded (419 and 429 errors)

If the client exceeds the allowed number of requests, Laravel returns an error response, usually:

429 Too Many Requests

In previous versions, a 419 Page Expired may be displayed.

Using RateLimiter and configureRateLimiting for custom limits

Starting with Laravel 8, you can define your own dynamic limits with RateLimiter.
This is configured in the RouteServiceProvider file:

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
public function configureRateLimiting()
{
   RateLimiter::for('api', function ($request) {
       return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
   });
}

Limit by user, IP, or subscription plan

One advantage I take advantage of in my projects is assigning different limits according to the user type.
For example, a client with a free plan can have 30 requests per minute, while a premium one has 200.

Integrating throttling with RouteServiceProvider

From there, you can combine it with middlewares or authentication policies, ensuring that each group of users receives the appropriate treatment.

  1. Real-world use cases
    Example 1: preventing abuse in online sweepstakes or raffles
    1. A small web raffle system: the more requests you can send, the higher your chances of winning, and therefore, an attacking client can send multiple requests in a short time; in a short time using a robot that they just implemented or something similar simply to improve their chances of winning the prize.
      Thanks to throttling, the system automatically blocked those attempts and kept the competition fair.
  2. Example 2: limiting requests based on the payment plan
    1. I also apply it to services with subscription plans.
      Each plan has a maximum number of monthly requests, which helps maintain a stable and predictable infrastructure; for example, 30 requests a month or 100 requests in a month was what they paid for, so you can also limit it that way so that, again, they can only make those 30 requests to a protected resource in that month. You can place this on any type of route, whether it's the routes we have defined at the web level or at the API level.
  3. Example 3: protecting sensitive resources in public APIs
    1. If you offer public endpoints (for example, for external integrators), applying limits prevents third parties from excessively consuming your API or causing downtime.

Best practices and common mistakes

Adjust your limits according to the type of endpoint (critical queries vs. light endpoints).

Use headers like Retry-After to indicate to the client when they can try again.

If you perform load tests, don't forget to exclude your IPs or admin users.

Avoid using the same limit for all routes: customize.

In my tests, I discovered that if the limit is too low, the system generates false alerts; and if it's too high, it ceases to fulfill its purpose.

Conclusion

Throttling in Laravel is a powerful tool for maintaining the balance between performance, security, and user experience.
With a few adjustments, you can protect your API, optimize the server, and ensure fair use of your resources.

Whether with the ThrottleRequests middleware or with custom rules in RateLimiter, the key is to adapt the limits to the context of your application.

Frequently Asked Questions (FAQ)

Are ThrottleRequests and RateLimiter the same?

No. ThrottleRequests applies fixed limits from the routes; RateLimiter allows you to customize them dynamically by user, IP, or plan.

How to adjust the request limit per route?

You can do it directly on the route, for example:
Route::middleware('throttle:10,1') limits that specific route to 10 requests per minute.

What to do if I receive a "Too Many Requests" error?

It means you have exceeded the configured limit.
Check the middleware, adjust the values, or wait the time indicated in the Retry-After header.

The next step is to learn how to send emails in Laravel.

Discover how to implement throttling in Laravel to limit requests to your APIs, protect resources, and improve performance. Includes examples, real-world use cases, and best practices with ThrottleRequests and RateLimiter.

I agree to receive announcements of interest about this Blog.

Andrés Cruz

ES En español