How to Set API Rate Limiting in Laravel

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 , thus, 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:

  1. > iptables -I INPUT -p tcp —dport 80 -i eth0 -m state —state NEW -m recent \
  2. —set
  3. > iptables -I INPUT -p tcp —dport 80 -i eth0 -m state —state NEW -m recent \
  4. —update —seconds 60 —hitcount 10 -j DROP

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

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.

FAQ’s

Q1 How to implement the Laravel Throttle Request middleware in Laravel 5.5?
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:

  1. /**
  2. * Increment the counter for a given key for a given decay time.
  3. *
  4. * @param string $key
  5. * @param float|int $decayMinutes
  6. * @return int
  7. */
  8. public function hit($key, $decayMinutes = 1)
  9. {
  10. $this->cache->add(
  11. $key.‘:timer’, $this->availableAt($decayMinutes * 60), $decayMinutes
  12. );
  13. $added = $this->cache->add($key, 0, $decayMinutes);
  14. $hits = (int) $this->cache->increment($key);
  15. if (! $added && $hits == 1) {
  16. $this->cache->put($key, 1, $decayMinutes);
  17. }
  18. return $hits;
  19. }

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

Q2 How to setup 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 conflicts with each middleware group. You can also modify the middleware by including second parameter that will define how long the waiting period would be until the next request could arrive. (e.g. throttle:60,1)

Q3 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 default throttle limit defined by Laravel for all api routes. Just comment out that code to disable it completely.

  1. protected $middlewareGroups = [
  2. ‘api’ => [
  3. ‘throttle:60,1’,
  4. ],
  5. ];