Shared Jobs: Cross-Application Communication for Laravel

When you have multiple Laravel applications that need to talk to each other, the usual options are REST APIs, message brokers, or event buses. Shared Jobs offers a simpler alternative: dispatch jobs between apps using a shared database and Laravel's native queue system.

The Use Case

You have two Laravel apps — say an Admin panel and an API — connected to the same database. When the admin triggers a refund, the API app needs to process it. Shared Jobs makes this a one-liner.

Fire-and-Forget

The simplest pattern is async dispatch:

use Laratusk\SharedJobs\Facades\SharedJob;

// In App 1 (Admin)
SharedJob::dispatch('refund', [
    'account_id' => 5,
    'amount' => 2500,
]);

App 2 picks this up from the shared queue and handles it:

use Laratusk\SharedJobs\Listeners\SharedJobListener;
use Laratusk\SharedJobs\Events\SharedJobReceived;

class HandleRefund extends SharedJobListener
{
    protected string $jobName = 'refund';

    public function process(array $payload, SharedJobReceived $event): void
    {
        $account = Account::find($payload['account_id']);
        $account->refund($payload['amount']);
    }
}

Synchronous Communication

Need a response back? Use dispatchAndWait:

$result = SharedJob::dispatchAndWait('refund', [
    'account_id' => 5,
], timeout: 30);

// $result = ['success' => true, 'refund_id' => 123]

The consumer responds via the event:

public function process(array $payload, SharedJobReceived $event): void
{
    $refund = $this->processRefund($payload);
    $event->respond(['success' => true, 'refund_id' => $refund->id]);
}

Role-Based Configuration

Each app declares its role — dispatcher, consumer, or both:

SHARED_JOBS_ROLE=dispatcher    # App 1
SHARED_JOBS_ROLE=consumer      # App 2

Configuration is straightforward with sensible defaults for connection, queue name, retries, and timeouts.

Built-in Testing

Shared Jobs ships with a complete fake for testing:

SharedJob::fake();

// ... your code ...

SharedJob::assertDispatched('refund', function ($name, $payload) {
    return $payload['account_id'] === 5;
});

SharedJob::assertNotDispatched('suspend-account');

No External Dependencies

No Redis, no RabbitMQ, no Kafka. Just a shared database table and Laravel's queue worker. If your apps already share a database, Shared Jobs works out of the box with zero infrastructure overhead.

Explore the full documentation on GitHub.

View on GitHubStar the repo, explore the source code, and get started.
Go to Repository
Share this post
Back to Blog