Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

A job middleware to rate limit jobs

Original – by Freek Van der Herten – 3 minute read

Recently we released a new small package called laravel-rate-limited-job-middleware. As the name implies, this package can be used to limit how many times a job may be executed in a given amount of time.

In this short blog post, I'd like to introduce the package to you.

A possible use case

I'm currently working on a new package to send out emails to a list of subscribers. Mails are being sent out using the many email sending services Laravel supports. All emails will also be sent via a queue.

The email sending services often have a limit on how many emails you are allowed to send in a short amount of time. So I needed a way to rate-limit the number of jobs there are sent within a given amount of time.

In Laravel 6, job middleware was introduced. The example in the Laravel docs showed how to throttle jobs using Redis. This was precisely what I needed, so I decided to package up that example code. I added some methods to customize the behavior.

Introducing laravel-rate-limited-job-middleware

The package can be installed via Composer (no surprises there).

composer require spatie/laravel-rate-limited-job-middleware

You can use the RateLimited middleware by letting the middleware method of your job return it.

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Spatie\RateLimitedMiddleware\RateLimited;

class TestJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable;

    public function handle()
    {
        // your job logic
    }

    public function middleware()
    {
        return [new RateLimited()];
    }
}

By default, this will rate limit your job: only five jobs are allowed to execute per second.

Of course, you can modify that behavior. Here's an example where only 30 jobs are allowed in a timeframe of 60 seconds. The surplus of jobs will be released (which is a fancy word for rescheduled) to be rerun in 90 seconds.

// in your job

public function middleware()
{
    $rateLimitedMiddleware = (new RateLimited())
        ->allow(30)
        ->everySeconds(60)
        ->releaseAfterSeconds(90);

    return [$rateLimitedMiddleware];

When using rate limiting, the number of attempts of your job may be hard to predict. Instead of using a fixed amount of attempts, it's better to use time-based attempts.

In closing

The package contains a few other interesting methods. To know about them, head over to the docs on GitHub.

Be sure to also check out this big list of packages my team and I have previously made.

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

What are your thoughts on "A job middleware to rate limit jobs"?

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.