Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

asoftware's avatar

Spatie Multi Tenant Setup with Queues

I have a scheduled queue job that runs daily for each of the tenants in my application. I am using Spatie's Multi Tenant package. I tried to use their tenant aware queues, but I was not able to loop over each tenant and set the current tenant. It seemed like it would only set the tenant to the last tenant.

I was curious if anybody knew of a way to run tenant defined queues on a schedule that obey the $tenant->makeCurrent().

Basically what I want is this scheduled clean up queue job to run for each tenant. I can get it to work if I set the queue job to not tenant aware and then manually set the tenant in the queue job. But, then when it fails, it will not write to the tenant database failed jobs table... it instead tries to write to the landlord database.

Any suggestions?

0 likes
1 reply
LaryAI's avatar
Level 58

To solve the issue of running a scheduled queue job for each tenant using Spatie's Multi Tenant package, you can follow these steps to ensure that each job is tenant-aware and writes to the correct tenant's database, including handling failed jobs properly.

Step-by-Step Solution

  1. Iterate Over Tenants: You need to iterate over each tenant and dispatch a job for each one. This ensures that each job is aware of the tenant context.

  2. Use Tenant-Aware Jobs: Make sure your job implements the Spatie\Multitenancy\Jobs\TenantAware interface. This will ensure that the job is executed within the context of the tenant.

  3. Dispatch Jobs in a Loop: In your scheduled task, loop over each tenant and dispatch the job. Use the makeCurrent() method to set the tenant context before dispatching the job.

  4. Handle Failed Jobs: Ensure that your queue configuration is set up to handle tenant-specific databases for failed jobs.

Here's an example of how you might set this up:

use App\Jobs\YourTenantAwareJob;
use Spatie\Multitenancy\Models\Tenant;
use Illuminate\Support\Facades\Bus;

// In your console kernel or wherever you define your scheduled tasks
$schedule->call(function () {
    Tenant::all()->each(function (Tenant $tenant) {
        // Set the tenant as the current tenant
        $tenant->makeCurrent();

        // Dispatch the job for the current tenant
        YourTenantAwareJob::dispatch();

        // Optionally, you can use a batch if you have multiple jobs
        // Bus::batch([
        //     new YourTenantAwareJob(),
        //     // Add more jobs if needed
        // ])->dispatch();

        // Forget the current tenant to avoid any side effects
        Tenant::forgetCurrent();
    });
})->daily();

Key Points:

  • Tenant Context: By calling $tenant->makeCurrent(), you ensure that the job is aware of the tenant context when it is dispatched.
  • Tenant-Aware Interface: Implementing TenantAware ensures that the job will automatically switch to the correct tenant when it runs.
  • Failed Jobs: Ensure your queue configuration is set to use tenant-specific connections if needed. This might involve setting up different queue connections for each tenant or dynamically setting the database connection in your job.

By following these steps, you should be able to run tenant-specific scheduled jobs that correctly handle tenant contexts and failed jobs.

Please or to participate in this conversation.