9

How to set the rate limiter per second in Laravel 8. I need to set the rate limiter per second instead of per minute.

Rate Limiter (Laravel 8) - https://laravel.com/docs/8.x/routing#rate-limiting

Right now I'm able to use Laravel's rate limiter for minutes, hours, etc. But I'm trying to achieve a rate limiter for a second. I want to limit 25 requests per sec. (Exported Limit class from "Illuminate\Cache\RateLimiting\Limit")

Please check the following code which I have used

RateLimiter::for('api', function (Request $request) {
        return [
            // Rate limiter based on Client IP Address
            Limit::perMinute(env('IP_ADDR_RATE_LIMITER_PER_MINUTE', 60))->by($request->ip())->response(function () {
                ....
            }),
            // Rate limiter based on API key/User
            Limit::perMinute(env('API_KEY_RATE_LIMITER_PER_MINUTE', 60))->by($request->input('key'))->response(function () {
                ...
            })
        ];
    });

Is there any way to rate-limit 25 requests per second?

Note: also tried adding/changing functions in Illuminate\Cache\RateLimiting\Limit, where I tried altering the per minute function. Thanks in Advance.

Mahe Krish
  • 141
  • 1
  • 7
  • 1
    Not sure why you were downvoted. I'm having the same issue. Did you find a solution yet? – Jan Aug 26 '21 at 02:06
  • I'm also looking for the same solution. I'm not convinced (having done a few tests) that putting the (rate you want * 60) as the Limit::perMinute will do the same as having an actually rate limit per second. Did you find a solution? – PilotSnipes Sep 21 '21 at 09:32
  • Did you find a solution yet? – Arlong Oct 05 '22 at 21:34

3 Answers3

3

pass the max seconds in the fourth position

$executed = RateLimiter::attempt(
    'send-message:'.$user->id,
    $perMinute = 5,
    function() {
        // Send message...
    },  1 // this would be one second
);

this would be 5 attempts per second

1
<?php

namespace App\Http\Cache;

class Limit extends \Illuminate\Cache\RateLimiting\Limit
{
    
    /**
     * Create a new limit instance.
     *
     * @param  mixed|string  $key
     * @param  int  $maxAttempts
     * @param  int|float  $decayMinutes
     * @return void
     */
    public function __construct($key = '', int $maxAttempts = 60, $decayMinutes = 1)
    {
        $this->key = $key;
        $this->maxAttempts = $maxAttempts;
        $this->decayMinutes = $decayMinutes;
    }

    /**
     * Create a new rate limit using seconds as decay time.
     *
     * @param  int  $decaySeconds
     * @param  int  $maxAttempts
     * @return static
     */
    public static function perSeconds($decaySeconds, $maxAttempts)
    {
        return new static('', $maxAttempts, $decaySeconds/60.0);
    }
   
}

You can redefine the Limit class

  • 3
    This doesn't seem to work as the internal function that is being returned from here accepts only integer type and not the float type. I get the same result as using a minute rate limiter. – Mahe Krish Nov 30 '21 at 10:40
0

1- Configure Rate Limiter in RouteServiceProvider

2- Open App\Providers\RouteServiceProvider::class and add the following changes:

/** * 
Configure the rate limiters for the application. 
* 
*
@return void 
*/

protected function configureRateLimiting() 
{ 
     // ALLOW 1500/60 = 25 Request/Sec 
     RateLimiter::for('api', function (Request $request) {
      return Limit::perMinute(1500); }); 
      // ALLOW 1000/60 = 16.66 Request/Sec 
      RateLimiter::for('api', function (Request $request) { 
       return Limit::perMinute(1000)->response(function () { 
        return response('Too many request...', 429); 
     });  
   });  
  }
NIKUNJ PATEL
  • 2,034
  • 1
  • 7
  • 22
  • 1
    1500 requests per minute does not equate to 25 requests per second. You can get all 1500 requests in 10 seconds and that would be 150 requests per second. This is more obvious when working with queues and you don't want more than a set number of jobs processed per each second. – impeto Jan 28 '23 at 13:36