本文へ移動
Laravel Tips

回数の制限(レート制限)

「1分間に5回まで」のように、ある操作の回数を制限するレート制限の使い方を、attempt・increment・remaining・clear などの例で説明します。

レート制限は、ある操作ができる回数に、上限を決めるしくみです。たとえば「メッセージは1分間に5回まで」と決めておけば、連続で送りつけられるのを防げます。駅の自動改札で、同じ人が短い時間に何度も通れないようにするようなものです。

Laravel には、使いやすいレート制限の道具があります。アプリのキャッシュ(一度作った結果を取っておき、次から速く返すしくみ)と組み合わせて、決めた時間のあいだの回数を数えます。

補足

届いた HTTP のリクエストの回数を制限したいときは、ルーティングのページにある、レート制限のミドルウェア(リクエストが処理に届く前に、間に入って確かめる処理)を見てください。

キャッシュの設定#

レート制限は、ふつう、アプリの cache 設定ファイルの default で決めた、いつものキャッシュを使います。レート制限だけ別のキャッシュドライバー(キャッシュの保存先の種類)を使いたいときは、cache 設定ファイルに limiter というキーを書いて決めます。

php
'default' => env('CACHE_STORE', 'database'),

'limiter' => 'redis', // この行を足す

基本の使い方#

レート制限は、Illuminate\Support\Facades\RateLimiter ファサード(Route::get() のように、クラス名と :: で機能を呼べる窓口)で使います。いちばんかんたんなのは attempt メソッドです。決めた秒数のあいだ、渡した関数を動かせる回数を制限します。

attempt は、残りの回数がなくなると false を返します。残りがあれば、関数の結果か true を返します。1つ目の引数は、レート制限の「キー」です。何の操作を制限するかを表す、好きな文字を使えます。

php
use Illuminate\Support\Facades\RateLimiter;

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

if (! $executed) {
    return 'Too many messages sent!';
}

4つ目の引数に、「回復までの秒数」(decay rate)を渡せます。使える回数が、元に戻るまでの秒数です。たとえば、2分間に5回まで、にするには、次のように書きます。

php
$executed = RateLimiter::attempt(
    'send-message:'.$user->id,
    $perTwoMinutes = 5,
    function() {
        // Send message...
    },
    $decayRate = 120,
);

回数を自分で増やす#

レート制限を自分で扱いたいときは、ほかにもメソッドがあります。たとえば、tooManyAttempts で、そのキーが、1分あたりの上限を超えたかを調べられます。

php
use Illuminate\Support\Facades\RateLimiter;

if (RateLimiter::tooManyAttempts('send-message:'.$user->id, $perMinute = 5)) {
    return 'Too many attempts!';
}

RateLimiter::increment('send-message:'.$user->id);

// Send message...

同時にたくさんのリクエストが来る窓口では、tooManyAttempts と increment を別々に呼ばずに、increment が返す値を調べるとよいです。redis・memcached・database のキャッシュでは、数を増やす処理が、とちゅうで割りこまれない1回の操作として動きます。そのため、同時に来たリクエストにも、それぞれちがう数が返ります。

php
use Illuminate\Support\Facades\RateLimiter;

$perMinute = 5;

if (RateLimiter::increment('send-message:'.$user->id) > $perMinute) {
    return 'Too many attempts!';
}

// Send message...

remaining メソッドで、そのキーの残りの回数を調べることもできます。残りがあれば、increment で回数を増やします。

php
use Illuminate\Support\Facades\RateLimiter;

if (RateLimiter::remaining('send-message:'.$user->id, $perMinute = 5)) {
    RateLimiter::increment('send-message:'.$user->id);

    // Send message...
}

1回で、2以上増やしたいときは、increment に数を渡します。

php
RateLimiter::increment('send-message:'.$user->id, amount: 5);

また使えるまでの時間#

そのキーの残りの回数がなくなったとき、availableIn メソッドで、また使えるようになるまでの秒数が分かります。

php
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.';
}

RateLimiter::increment('send-message:'.$user->id);

// Send message...

回数を元に戻す#

clear メソッドで、そのキーの回数を元に戻せます。たとえば、送ったメッセージを、相手が読んだときに、回数を戻せます。

php
use App\Models\Message;
use Illuminate\Support\Facades\RateLimiter;

/**
 * Mark the message as read.
 */
public function read(Message $message): Message
{
    $message->markAsRead();

    RateLimiter::clear('send-message:'.$message->user_id);

    return $message;
}

メソッドの一覧#

このページに出てきた RateLimiter のメソッドをまとめます。

メソッド 説明
attempt 決めた秒数のあいだ、関数を動かせる回数を制限する。回数がなければ false
tooManyAttempts そのキーが、上限を超えたかを調べる
increment そのキーの回数を増やす(数を渡すと、その数だけ増やす)。増やしたあとの値を返す
remaining そのキーの、残りの回数を調べる
availableIn また使えるようになるまでの秒数を返す
clear そのキーの回数を元に戻す

関連するページ#

公式ドキュメント(英語)

2026年10月5日時点の内容をもとに、日本語でまとめています。

ページの一覧