Laravel Rate Limiting — Explained with Real-Life Examples

Imagine this — your app is running smoothly, then suddenly it gets hit with a wave of requests. Some from real users, others from bots...

Karan Datwani
Karan Datwani
Share:

Imagine this — your app is running smoothly, then suddenly it gets hit with a wave of requests. Some from real users, others from bots or people refreshing nonstop. Without proper rate limiting, your server could slow to a crawl or even go down.

Laravel’s built-in rate limiting helps prevent that. Think of it like a check-in line at a theme park — without regulation, it’s chaos. With a system in place, everything flows.

In this article, I’ll cover:

  • What is rate limiting
  • Why it matters
  • 4 effective strategies to implement it in Laravel

What Is Rate Limiting?

Rate limiting controls how many times someone can access a route or API in a certain time frame. It's like setting a speed limit for users or bots. Laravel’s rate limiting protects your app from rowdy bots and abusive users. 😉

Controlled entry = smooth experience 😄

Why Does It Matter?

  1. Prevents Overload – Avoids server crashes from too many requests.
  2. Improves API Stability – Keeps responses fast and consistent.
  3. Boosts Security – Blocks bots, scripts, brute force, or DDoS attempts from hammering your app with fake requests.
  4. Ensures Fair Access – Keeps resource hogs from ruining the experience for others.
  5. Saves Costs – Reduces bandwidth and infra waste.
  6. Keeps It Smooth – Your app stays fast and responsive, even under load.
  7. Prevents Abuse – No more spamming login attempts or checkout submissions. 😅

Laravel's Built-in Rate Limiting (Recommended)

To prevent abuse (e.g., brute-force login attempts), Laravel lets you define custom rate limiters using RateLimiter::for(). In this example, we create a login limiter that allows 5 requests per minute per IP.

// Path: App\Providers\AppServiceProvider.php

use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;

public function boot(): void
{
    RateLimiter::for('login', function (Request $request) {
        return Limit::perMinute(5)
            ->by($request->ip())
            ->response(function () {
                return response()->json([
                    'message' => 'Too many attempts. Try again later.'
                ], 429);
            });
    });
}

Apply the limiter to your route using throttle:{name} middleware:

// Path: routes/web.php or routes/api.php

Route::middleware('throttle:login')->post('/login', [AuthController::class, 'login']);

👍 Best for most apps. Use Laravel’s built-in RateLimiter::for() for simple, clean throttling. Want more control? Let’s explore custom strategies. 🚀

Strategy 1: Role-Based Rate Limiting

Different users deserve different access. Free users may get 60 requests/min, while premium users get 200/min.

Example: SaaS app with tiered plans. Give more access to paying customers, without hurting free-tier users.

// Path: App\Http\Middleware\RateLimitByRole.php

public function handle(Request $request, Closure $next){
    $role = $request->user()?->role ?? 'guest';
    $limits = ['admin' => 100, 'premium' => 200, 'free' => 60, 'guest' => 20];
    $maxAttempts = $limits[$role] ?? 20;
    $key = "rate:{$role}:" . ($request->user()?->id ?? $request->ip());

    if (RateLimiter::tooManyAttempts($key, $maxAttempts)) {
        return response()->json(['message' => 'Too many requests.'], 429);
    }

    RateLimiter::hit($key, 60);

    return $next($request);
}

Useful for apps with tiered user roles (e.g., admin, staff, guest).

Strategy 2: IP-Based Rate Limiting

Limit requests based on IP to block specific bots or noisy users.

Example: During a sale, one IP spams checkout API. Block it without hurting others.

// Path: App\Http\Middleware\RateLimitByIP.php

public function handle(Request $request, Closure $next)
{
    $ip = $request->ip();
    $key = 'rate_limit:ip:' . $ip;

    if (RateLimiter::tooManyAttempts($key, 60)) {
        return response()->json(['message' => "You're doing that too much."], 429);
    }

    RateLimiter::hit($key, 60);

    return $next($request);
}

Great for anonymous endpoints or rate-limiting crawlers.

Strategy 3: Burst Handling & Graceful Degradation

When traffic surges, don’t crash — degrade. Politely pause extra requests, or give fallback data.

Example: Flash sale causes a traffic spike. Rather than failing, the app slows down politely.

// Path: App\Http\Middleware\BurstLimit.php

public function handle(Request $request, Closure $next)
{
    $key = 'burst:' . $request->ip();

    if (RateLimiter::tooManyAttempts($key, 30)) {
        return response()->json(['message' => 'Whoa there! Slow down.'], 429);
    }

    RateLimiter::hit($key, 30);

    return $next($request);
}

😎 Perfect when you want flexibility with protection.

Strategy 4: API Token-Based Limiting

Limit users based on their API token tier (free/paid/unknown).

Example: A weather API that limits based on token type.

// Path: App\Http\Middleware\RateLimitByToken.php

public function handle(Request $request, Closure $next)
{
    $token = $request->bearerToken();
    $key = 'rate_limit:token:' . ($token ?? $request->ip());

    if (RateLimiter::tooManyAttempts($key, 100)) {
        return response()->json(['message' => 'Rate limit exceeded'], 429);
    }

    RateLimiter::hit($key, 60);

    return $next($request);
}

Ideal for public APIs with developer access.

Registering Your Middleware

In bootstrap/app.php

use App\Http\Middleware\RateLimitByRole;
use App\Http\Middleware\RateLimitByIP;
use App\Http\Middleware\BurstLimit;
use App\Http\Middleware\RateLimitByToken;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
    )
    ->withMiddleware(function ($middleware) {
        $middleware->alias([
            'role.throttle' => RateLimitByRole::class,
            'ip.throttle' => RateLimitByIP::class,
            'burst.throttle' => BurstLimit::class,
            'token.throttle' => RateLimitByToken::class,
        ]);
    })
    ->create();

Summary Table

Strategy Keyed By Example Limit
Role-Based role:ip Admin: 100/min, User: 10/min
IP-Based ip 60/min
Token-Based api_token 100/min
Graceful Bursting ip 30/min (short bursts allowed)

Final Thoughts

What is rate limiting? It’s your app’s speed governor.

It isn’t just about blocking — it’s about protecting performance while being fair to your users. It improves the experience for everyone. Implement it early, tweak it as you grow and keep things running smooth.

Key Takeaways

  • Rate limiting prevents abuse, spam, and overload.
  • Use RateLimiter::for() for simple setups.
  • Use middleware for advanced control.
  • Choose a strategy that fits your app’s traffic & user base.

Start small, scale smart — Happy coding! 😄

Want to receive more articles like this?

Subscribe to our "Article Digest". We'll send you a list of the new articles, every week, month or quarter - your choice.

Reactions & Comments

What do you think about this?

Latest Articles

Wondering what our community has been up to?