This website uses cookies

Our website, platform and/or any sub domains use cookies to understand how you use our services, and to improve both your experience and our marketing relevance.

📣 Try the fastest hosting platform with pay-as-you-go pricing & 24/7 expert support! MIGRATE NOW →

How to Set API Rate Limiting in Laravel

Updated on December 28, 2021

6 Min Read
laravel throttle

We are going to continue our discussion on Laravel and website security and introduce an API endpoint. I will also explore Laravel’s rate-limiting functionality. To set things in proper context, I will use the to-do app developed in the previous article.

Laravel throttle incorporates an easy-to-use, rate restricting abstraction, which, in conjunction with your application’s cache, gives an easy way to constrain any activity during an indicated window of time. Experience the dynamic efficiency of this feature amplified by top-tier Laravel hosting solutions.

Throttling something in Laravel isn’t rocket science. You usually need to limit an action based on a number of attempts inside a time window, like when the client makes an Ask. The throttle middleware does that for you, and the default LoginController automatically throttles logins.

Managed Laravel Hosting: Your Laravel Performance Boost!

Elevate Your Laravel Experience with Cloudways’ Laravel Managed Hosting – Where Expertise Meets Exceptional Performance.

What is rate limiting?

Rate-limiting is the control of the number of requests per unit time. It can be applied to ports, IPs, routes, etc. When used correctly, it can efficiently block out malicious bots. In the case of our API, it can mitigate DOS attacks, making our API accessible without downtime for legitimate users.

Note, rate limiting can also be done via a firewall. For example using IPTables on Debian based systems:

> iptables -I INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent \
--set

> iptables -I INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent \
--update --seconds 60 --hitcount 10 -j DROP

This will limit hits to port 80, 10 times per minute. However, this approach makes it difficult, if not impossible, to only apply rate limiting to the API routes and not the entire site. Fortunately, Laravel (versions 5.2 and above) has built-in API Throttling Middleware for this exact purpose.

Read More About:Working With Middleware in Laravel

Laravel Rate Limiting

First, let’s create the API.

The idea is to be able to add a task by using an API route. This should be simple enough. We just add two routes (to list tasks and add tasks) and instead of returning a template, we return a JSON response.

Route::group(['prefix' => 'api/v1'], function () {

Route::get('/getTasks', function () {

return Task::all();

});

Route::post('/addTask', function (Request $request) {

$validator = Validator::make($request->all(), [

'names' => 'required|max:255',

]);

if ($validator->fails()) {

return response()->json(['error' => $validator->messages()],

200);

}

$task = new Task;

$task->names = $request->names;

$task->save();

return response()->json(['response' => "Added {$request->names} to tasks."],

200);

});

});

Read More About:Create Rest API in Laravel With Authentication Using Passport

Now, we can use curl to add and list the tasks.

> curl -X POST -H "Content-Type: application/json" --data '{"names": "Make a cake" }' http://10.10.0.10:8880/api/v1/addTask

{"response":"Added Make a cake to tasks."}

> curl http://10.10.0.10:8880/api/v1/getTasks

[{"id":7,"names":"Grocery shopping","created_at":"2016-05-12 06:18:46","updated_at":"2016-05-12 06:18:46"},{"id":8,"names":"Dry cleaning","created_at":"2016-05-12 06:18:52","updated_at":"2016-05-12 06:18:52"},{"id":13,"names":"Car wash","created_at":"2016-05-12 09:51:01","updated_at":"2016-05-12 09:51:01"},{"id":23,"names":"Make a cake","created_at":"2016-06-24 07:13:21","updated_at":"2016-06-24 07:13:21"}]

Task “Make a cake” has been added. Now, let’s add 10 more in quick succession…

> for i in `seq 1 10`; do curl -X POST -H "Content-Type: application/json" --data '{"names": "Make a cake" }' http://10.10.0.10:8880/api/v1/addTask; done;

This allows us to add 10 tasks within milliseconds (638 ms to be exact). Without rate limiting, this makes the app vulnerable to a very basic DOS attack.

Now let’s use the built in Laravel rate limiting which limits the actions/responses per minute. Change the API wrapper for the use of Throttling Middleware

Route::group(['prefix' => 'api', 'middleware' => 'throttle:3,10'], function () {

...

});

This will cap requests made by an IP to 3 every 10 minutes. Next time the user hits the API from the same IP, the following response will be returned:

...

< X-RateLimit-Limit: 3

< X-RateLimit-Remaining: 0

< Retry-After: 599

...

Too Many Attempts.

The key to rate limiting is finding the right balance. In our sample “To-do tasks” app, if 3 tasks every ten minutes seems too restrictive, we could change it to 3 tasks per minute with the following (omitting the second number, since by default it is set to 1 minute , i.e. ‘middleware’ => ‘throttle’, will limit 10 requests per minute).

Stop Wasting Time on Servers

Cloudways handle server management for you so you can focus on creating great apps and keeping your clients happy.

Route::group(['prefix' => 'api', 'middleware' => 'throttle:3'], function () {

...

});

Using fields other than IP to throttle

Many institutions and ISP’s use NAT’d solutions. Hence, it is not advisable to limit an entire group of people just because one of them is abusing the API. If we want to throttle by something unit other than IP, all we have to do is extend the base ThrottleRequests class and override the resolveRequestSignature function:

protected function resolveRequestSignature($request)

{

if (! $request->route()) {

throw new RuntimeException('Unable to generate fingerprint. Route unavailable.');

}

return sha1(

implode('|', $request->route()->methods()).

'|'.$request->route()->domain().

'|'.$request->route()->uri().

'|'.$request->ip() // Replace this line

);

}

Replace the $request->ip() field with some other field. For example, to throttle using the session id as the unique key, add:

$request->session()

Or if you want to throttle by using the user_id passed into the request,

$request->input('user_id')

Or even the API Key

$request->header(‘API-KEY’)

The only requirement here is that the field in question be unique between users. But that’s about it. We have our API rate limiting in place.If you need further clarification or wish to share your opinion, do leave a comment below.

Read More About:Creating a REST API in Lumen

Dynamic Rate Limiting

With Laravel, you can specify the maximum number of requests based on the attribute of authenticated User’s model, using the feature of dynamic rate limiting.

Prerequisites

For the purpose of this tutorial, I assume that you have a Laravel application installed on a web server. My setup is:

  • Laravel 5.5
  • PHP 7.1
  • MySQL
  • Node.js with NPM

In my experience, server management issues could be a serious roadblock for developers. I avoid these roadblocks by opting for Cloudways. Cloudways offers a great development stack (known as ThunderStack) to host Laravel projects and takes care of all server level problems. You can try out Cloudways for free by signing for an account.

Laravel simplifies the process of limiting the number of requests a client could make for a particular action. Consider the following snippet from the Laravel Docs:

Route::middleware('auth:api', 'throttle:60,1')->group(function () {
Route::get('/user', function () {
//
});
});

In the above snippet, the authenticated user can only hit the mentioned routes 60 times (and more!). This is handled by the throttle middleware. While this is great in some cases, this is not enough in most. Usually, dynamic rate limiting is an essential requirement of the project.

Here is another case from the Laravel Docs:

Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
Route::get('/user', function () {
//
});
});

In the above snippet, the middleware is used once again. But the request is not defined there. Rather, the attribute name is passed. In the context of the snippet, rate_limit is a field in the user’s table that records the number of requests as an integer. Using this process, developers could easily define and control the number of requests for individual users. A popular used case that comes to mind is limiting access to particular resources based on the user-opted subscription plans.

Enable/Disable Rate Limiting:

The API rate limiting middleware is enabled and applied to all the Container Endpoints by default. To disable it, set API_RATE_LIMIT_ENABLED to false in the .env file.

Laravel Throttle Package

Created by Graham Campbell, Laravel Throttle is an exclusively built package that performs rate limiting in Laravel. It requires a PHP 7.x version for its proper functioning and supports optional configuration. To start working, you need to publish all vendor assets by executing the PHP artisan command which will create the throttle.php file inside your app.

Unlock Laravel’s Potential with Cloudways’ Laravel Hosting

Laravel Hosting Taken to the Next Level – Cloudways’ Managed Hosting Offers Unbeatable Speed and Reliability.

Conclusion

Rate limiting is an important option that completely changes the project structure (for the better). Developers could easily set up and control the frequency of access to resources through a simple in-code process. Let me know if you need further clarification about Laravel rate limiting.

Laravel utilizes throttle middleware to limit the amount of traffic for a given route or gather of routes. The throttle middleware accepts two parameters that decide the maximum number of requests that can be made in a given number of minutes

Q. How to implement the Laravel Throttle Request middleware in Laravel ?

A: Throttle Request refers to a process in which an authenticated user is allowed to hit the application maximum time. After that, the user’s session is either expired or is denied access to the application. Throttle Request could be implemented in Laravel as shown below:
Look at RateLimit::hit() code. It’s pretty clear:

/**
* Increment the counter for a given key for a given decay time.
*
* @param string $key
* @param float|int $decayMinutes
* @return int
*/
public function hit($key, $decayMinutes = 1)
{
$this->cache->add(
$key.':timer', $this->availableAt($decayMinutes * 60), $decayMinutes
);
$added = $this->cache->add($key, 0, $decayMinutes);
$hits = (int) $this->cache->increment($key);
if (! $added && $hits == 1) {
$this->cache->put($key, 1, $decayMinutes);
}
return $hits;
}

If you want to limit some activity by 10 hits per 5 minutes, than decay Minutes must be 5

Q. How to set up different rate limits for different paths ?

A: First edit the Kernel.php file and comment out its default line 40 so that it doesn’t conflict with each middleware group. You can also modify the middleware by including a second parameter that will define how long the waiting period would be until the next request could arrive. (e.g. throttle:60,1)

Q. How to disable rate limiter in Laravel ?

A: For disabling the rate limiter in Laravel, first go to the app/Http/Kernel.php. There you will find the default throttle limit defined by Laravel for all api routes. Just comment out that code to disable it completely.

	protected $middlewareGroups = [
	...
	'api' => [
	'throttle:60,1',
	],
	];

Share your opinion in the comment section. COMMENT NOW

Share This Article

Shahzeb Ahmed

Shahzeb is a Digital Marketer with a Software Engineering background, works as a Community Manager — PHP Community at Cloudways. He is growth ambitious and aims to learn & share information about PHP & Laravel Development through practice and experimentation. He loves to travel and explore new ideas whenever he finds time. Get in touch with him at [email protected]

×

Get Our Newsletter
Be the first to get the latest updates and tutorials.

Thankyou for Subscribing Us!

×

Webinar: How to Get 100% Scores on Core Web Vitals

Join Joe Williams & Aleksandar Savkovic on 29th of March, 2021.

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

Want to Experience the Cloudways Platform in Its Full Glory?

Take a FREE guided tour of Cloudways and see for yourself how easily you can manage your server & apps on the leading cloud-hosting platform.

Start my tour

CYBER WEEK SAVINGS

  • 0

    Days

  • 0

    Hours

  • 0

    Mints

  • 0

    Sec

GET OFFER

For 4 Months &
40 Free Migrations

For 4 Months &
40 Free Migrations

Upgrade Now