Introduction
Laravel includes a simple to use rate limiting abstraction which, in conjunction with your application's cache, provides an easy way to limit any action during a specified window of time.
Tip!! If you are interested in rate limiting incoming HTTP requests, please consult the rate limiter middleware documentation.
Cache Configuration
Typically, the rate limiter utilizes your default application cache
as defined by the default
key within your application's
cache
configuration file. However, you may specify which
cache driver the rate limiter should use by defining a
limiter
key within your application's cache
configuration file:
'default' => 'memcached',
'limiter' => 'redis',
Basic Usage
The Illuminate\Support\Facades\RateLimiter
facade may be
used to interact with the rate limiter. The simplest method offered by
the rate limiter is the attempt
method, which rate limits a
given callback for a given number of seconds.
The attempt
method returns false
when the
callback has no remaining attempts available; otherwise, the
attempt
method will return the callback's result or
true
. The first argument accepted by the
attempt
method is a rate limiter "key", which may be any
string of your choosing that represents the action being rate
limited:
use Illuminate\Support\Facades\RateLimiter;
$executed = RateLimiter::attempt(
'send-message:'.$user->id,
$perMinute = 5,
function() {
// Send message...
}
);
if (! $executed) {
return 'Too many messages sent!';
}
Manually Incrementing Attempts
If you would like to manually interact with the rate limiter, a
variety of other methods are available. For example, you may invoke the
tooManyAttempts
method to determine if a given rate limiter
key has exceeded its maximum number of allowed attempts per minute:
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
return 'Too many attempts!';
}
Alternatively, you may use the remaining
method to
retrieve the number of attempts remaining for a given key. If a given
key has retries remaining, you may invoke the hit
method to
increment the number of total attempts:
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
RateLimiter::hit('send-message:'.$user->id);
// Send message...
}
Determining Limiter Availability
When a key has no more attempts left, the availableIn
method returns the number of seconds remaining until more attempts will
be available:
use Illuminate\Support\Facades\RateLimiter;
if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
$seconds = RateLimiter::availableIn('send-message:'.$user->id);
return 'You may try again in '.$seconds.' seconds.';
}
Clearing Attempts
You may reset the number of attempts for a given rate limiter key
using the clear
method. For example, you may reset the
number of attempts when a given message is read by the receiver:
use App\Models\Message;
use Illuminate\Support\Facades\RateLimiter;
/**
* Mark the message as read.
*
* @param \App\Models\Message $message
* @return \App\Models\Message
*/
public function read(Message $message)
{
$message->markAsRead();
RateLimiter::clear('send-message:'.$message->user_id);
return $message;
}