Laravel-Throttle and the case for making your own rate limiter
A rate limiter for Laravel
At a glance
- What is it?
- Laravel-Throttle is a rate limiter for Laravel that treats throttling as a strategy you implement rather than a setting you toggle, with a throttler interface, a factory and a cache-backed counter. It is deliberately small, and the README's description of the check method ends mid-sentence.
- Who is it for?
- Laravel-Throttle is a good fit for a Laravel application that needs a rate limiter with custom semantics, such as a limit keyed on something other than the request IP, because the throttler interface and the factory make that a matter of implementing an interface rather than fighting a config file.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 170 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A rate limiter as an interface, not a middleware
Laravel-Throttle was created by, and is maintained by, Graham Campbell, and it is a rate limiter for Laravel. The description is short, and the design is more interesting than the description suggests, because the throttling is not applied as middleware and not configured per route.
The central class is Throttle, bound to the IoC container as 'throttle' and reachable through the Facades\Throttle facade. The README calls it the class of most interest and says it has six public methods of interest.
The first is 'get', and it is where the design shows. The 'get' method creates a new throttler class, one implementing Throttler\ThrottlerInterface, from the one to three parameters you pass. The first parameter is required and must be either an instance of \Illuminate\Http\Request, or an associative array with two keys, where 'ip' is the address of the user you wish to throttle and 'route' is the full URL you wish to throttle, though for advanced usage it may be any unique key you choose.
That last clause is the interesting one. The key that identifies what is being throttled does not have to be an IP and a URL. It can be any string you want, which is how you throttle a user account, an API key or a tenant instead of an address.
Under the hood, 'get' calls the make method on a throttler factory class implementing Factories\FactoryInterface, so the throttler implementation is itself pluggable.
Six methods, and the one the README does not finish
The other five methods all accept the same parameters as 'get', and the pattern is consistent. A throttler class is dynamically created, or an already created instance is reused automatically, and then the method is called on it with no parameters. The five are 'attempt', 'hit', 'clear', 'count' and 'check'.
The semantics are simple and worth stating precisely, because the return types drive how you use them.
'attempt' hits the throttle, incrementing the hit count, and returns a boolean saying whether or not the hit limit has been exceeded. That is the method you want in a controller: call it, and if it returns false, refuse the request.
'hit' increments the hit count and returns $this, so you can chain another call. 'clear' sets the hit count to zero and also returns $this. 'count' returns the number of hits so far. 'check' is where the README stops: the text reads that the 'check' method wi, and the document ends there.
That truncation matters more than a formatting quirk. Five of the six methods are fully described, and the sixth, which by its name is the one you would use to ask whether a request is currently allowed, is exactly the one whose contract you cannot read here. Anyone adopting this package will need to look at the source or the API docs for that method rather than rely on the README.
Installing with Composer and registering the provider
Installation is a single Composer command, and the constraint is explicit:
$ composer require "graham-campbell/throttle:^11.0"The version requirement is worth reading alongside the compatibility table. This version requires PHP 8.1-8.4 and supports Laravel 10-12. The table maps each package version against the Laravel versions it works with, and the 11.0 row of the table shows support for Laravel 10, 11 and 12.
After installation there is one conditional step. If you are not using automatic package discovery, you need to register the GrahamCampbell\Throttle\ThrottleServiceProvider service provider in your config/app.php. With automatic discovery on, which is the default in modern Laravel, there is nothing to do.
You can also optionally alias the facade, which adds a Throttle entry to the aliases array:
'Throttle' => GrahamCampbell\Throttle\Facades\Throttle::class,The facade works by dynamically passing static method calls to the 'throttle' object in the IoC container, which by default is the Throttle class. So the facade and the container binding are two views of the same object, and you can use whichever fits your code.
One configuration option, and the cache driver underneath it
Laravel Throttle supports optional configuration, and there is exactly one option.
To get started you publish the vendor assets:
$ php artisan vendor:publishThat creates a config/throttle.php file in your app, and the README also advises checking for changes to the original config file in the package between releases. That is a real maintenance point for a package with a single config key, because a change in the shipped defaults will not reach your published copy until you republish and merge.
The one option is the cache driver, named 'driver'. It may be the name of any driver set in config/cache.php, and setting it to null uses the default driver from config/cache.php. The default value is null, which means the package does nothing special about storage unless you tell it to.
That design has an implication. The hit counter lives in your cache, so the throttle is only as durable and as shared as the cache you point it at. A file cache means the limit applies per machine, which is wrong behind more than one web server. A shared cache such as Redis is what makes the limit global. The package does not warn about this, and the README does not say which drivers are safe for multi-node deployments, so the choice of cache driver is yours to reason about.
What the package is not, and how it differs from framework throttling
It is worth being clear about the boundary of this package, because the name suggests a route middleware and it is not one.
Laravel-Throttle does not ship a throttle middleware, does not declare limits in a route definition, and does not return a 429 response for you. The README describes no such thing, and the repository layout agrees: src for the code, config for the single config file, tests with a phpunit.xml.dist, and composer.json at the root. There is no middleware directory, no exception class and no response handling in the description.
The difference in approach is that this package is a counting mechanism with a pluggable backend, and you write the policy. Framework-provided throttling is the opposite: you declare a limit and the framework enforces it, with the key derived from the request and the response produced for you. That is more convenient and less flexible.
So the choice is between convenience and control. If you want a limit of 60 requests a minute per IP on a specific route and the framework already offers that, this package adds nothing. If you want a limit keyed on a user account, a limit that counts across several identifiers, or a throttler whose counting rule you implement yourself, the throttler interface and the factory are the reason to take it.
Maintenance, branch naming and the version matrix
The repository is not archived, and the default branch is named 11.0 rather than main or master, which tells you the project is developed on the current major version line.
The last push was on 2026-05-06. The tagged releases are v11.0.0 from 2025-03-03, v10.3.0 from 2025-03-02 and v10.2.0 from 2024-03-17. So the last two releases landed within a day of each other in March 2025, and there has been no release since, against pushes continuing into May 2026.
That is a pattern worth noting rather than worrying about. A rate limiter is a small, well-understood piece of code, and a maintainer can leave it stable for a long time and then make a release when a new Laravel version needs support. The compatibility table in the README is the tool for reading this: it shows exactly which package version supports which Laravel version, and it shows that the 11.0 line covers Laravel 10, 11 and 12 while the 10.3 line stopped at Laravel 11.
The licence is MIT. The project also publishes a change log, a security policy, a code of conduct and contribution guidelines, and the topics list includes hacktoberfest, which explains the periodic bursts of outside contributions.
Editorial conclusion
Laravel-Throttle is a good fit for a Laravel application that needs a rate limiter with custom semantics, such as a limit keyed on something other than the request IP, because the throttler interface and the factory make that a matter of implementing an interface rather than fighting a config file. It is a poor fit if you want a limit declared in a route middleware, since that is not what this package does, and a poor fit for a project that has already settled on a framework-provided throttling approach. Before adopting, read the check method, because the README's description of it is cut off mid-sentence, and confirm that your Laravel version falls in the supported 10 to 12 range, since the compatibility table shows the 11.0 line covers Laravel 10 to 12.
Frequently asked questions
How do I install Laravel-Throttle?
Require the package with Composer using composer require "graham-campbell/throttle:^11.0". If you are not using automatic package discovery, register the GrahamCampbell\Throttle\ThrottleServiceProvider service provider in your config/app.php.
What Laravel and PHP versions does Laravel-Throttle support?
This version requires PHP 8.1-8.4 and supports Laravel 10-12. The README includes a compatibility table mapping each package version to the Laravel versions it works with.
What configuration options does Laravel-Throttle have?
One. The 'driver' option in config/throttle.php names the cache driver to use, it may be any driver set in config/cache.php, and setting it to null uses your default driver. You publish the config file with php artisan vendor:publish.
How do I throttle a user account instead of an IP address?
The first parameter of the get method can be an associative array with an 'ip' key and a 'route' key, and the README notes that for advanced usage the route key may be any unique key you choose. So you can key the throttle on a user identifier rather than an address.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/grahamcampbell-laravel-throttle)Was this useful?