<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
class RouteServiceProvider extends ServiceProvider
{
protected function configureRateLimiting(): void
{
// Default API rate limit
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
// Custom rate limit for login
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)->by($request->ip());
});
// Different rates for authenticated vs guest
RateLimiter::for('posts', function (Request $request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});
// Multiple limits - whichever is hit first
RateLimiter::for('strict', function (Request $request) {
return [
Limit::perMinute(10),
Limit::perHour(100),
];
});
// Custom response
RateLimiter::for('uploads', function (Request $request) {
return Limit::perMinute(5)
->by($request->user()->id)
->response(function (Request $request, array $headers) {
return response('Too many uploads', 429, $headers);
});
});
}
}
<?php
use Illuminate\Support\Facades\Route;
// Apply default API rate limit
Route::middleware(['throttle:api'])->group(function () {
Route::get('/posts', [PostController::class, 'index']);
});
// Custom rate limiter
Route::middleware(['throttle:posts'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
});
// Login with strict limit
Route::post('/login', [AuthController::class, 'login'])
->middleware('throttle:login');
// Manual rate limiting in controller
Route::post('/upload', function (Request $request) {
if (RateLimiter::tooManyAttempts('upload:' . $request->user()->id, 5)) {
$seconds = RateLimiter::availableIn('upload:' . $request->user()->id);
return response('Too many requests', 429, [
'Retry-After' => $seconds,
]);
}
RateLimiter::hit('upload:' . $request->user()->id, 60);
// Process upload...
});
Rate limiting prevents API abuse by restricting request frequency per user or IP. Laravel's RateLimiter facade defines limits in RouteServiceProvider. I apply limiters via middleware—throttle:api for the default API limiter. Custom limiters use closures returning Limit objects with max attempts and decay time. Named limiters enable different rates for different endpoints. The for() method creates per-user limits, while static limits apply globally. Headers like X-RateLimit-Remaining inform clients of remaining attempts. Exceeded limits return 429 responses. For advanced scenarios, I integrate Redis for distributed rate limiting across servers. This protection is essential for public APIs and prevents resource exhaustion attacks.