★ A job middleware to rate limit jobs
Tags: laravel, php
Published: 2020-01-02 23:38:53

---
title: ★ A job middleware to rate limit jobs
published: true
date: 2019-10-08 18:06:04 UTC
tags: laravel, php
canonical_url: https://freek.dev/1475-a-job-middleware-to-rate-limit-jobs
---

Recently [we](https://spatie.be) released a new small package called [laravel-rate-limited-job-middleware](https://github.com/spatie/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](https://docs.spatie.be/laravel-email-campaigns/v1/introduction/) to send out emails to a list of subscribers. Mails are being sent out using [the many email sending services](https://laravel.com/docs/6.0/mail#driver-prerequisites) 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](https://laravel.com/docs/master/queues#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.

```php
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.

```php
// 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](https://laravel.com/docs/master/queues#time-based-attempts).

## In closing #

The package contains a few other interesting methods. To know about them, head over to [the docs on GitHub](https://github.com/spatie/laravel-rate-limited-job-middleware).

Be sure to also check out this [big list of packages](https://spatie.be/open-source/packages) my team and I have previously made.