When two Laravel applications need to exchange data, the reflex is to build an HTTP API between them. There is a lighter option: point both applications at one shared Redis instance and let Laravel's queue system carry the messages. One side dispatches a job, the other processes it — retries, backoff and monitoring come for free with the queue worker.
This guide configures a dedicated Redis connection in both applications, defines a matching job class on each side, and starts the worker that processes synchronization jobs. A custom key prefix keeps the shared queue isolated from each application's default queues.
1. Configuring the Redis connection
In both applications, open config/database.php and add a connection named sync under the redis array. The prefix option is the important part: Laravel prefixes Redis keys per application by default, so two applications would read and write different keys even on the same server. Setting the same explicit prefix on both sides makes them see the same queue.
'connections' => [
// Other connections...
'sync' => [
'url' => env('SYNC_REDIS_URL'),
'host' => env('SYNC_REDIS_HOST', '127.0.0.1'),
'port' => env('SYNC_REDIS_PORT', '6379'),
'password' => env('SYNC_REDIS_PASSWORD', null),
'database' => env('SYNC_REDIS_DB', '1'),
'options' => [
'prefix' => env('SYNC_REDIS_PREFIX', 'app_sync_')
],
],
],Point SYNC_REDIS_HOST, SYNC_REDIS_PORT and SYNC_REDIS_PASSWORD at the Redis server both applications share.
2. The synchronization job
Source application
The source application only dispatches — it never runs the job. Its job class therefore needs the right name, the same public properties as the destination's class, and the sync connection. The handle method stays empty:
class SynchronizeItem implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(public array $data)
{
$this->onConnection('sync');
}
public function handle(): void
{
// Definition only — processing happens in the destination application.
}
}Destination application
The destination application defines the same class — same name, same constructor signature — and implements handle to actually process the payload:
class SynchronizeItem implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(public array $data)
{
$this->onConnection('sync');
}
public function handle(): void
{
// Route the payload by type — e.g. dispatch a domain event.
match($this->data['type']) {
SynchronizationType::Transaction->value => $this->processTransaction(),
};
}
protected function processTransaction(): void
{
TransactionSynchronized::dispatch($this->data);
}
}The class names and property shapes must match exactly — the queue serializes the job by class name, so a mismatch surfaces as a failed job on the destination side.
3. Dispatching
From the source application, dispatch the job like any other Laravel job. It lands on the shared Redis queue instead of the local one:
SynchronizeItem::dispatch([
'type' => 'Transaction',
'item' => [
'currency' => 'EUR',
'amountInCents' => 150_000,
],
]);4. The queue worker
On the destination side, register the sync queue connection in config/queue.php so a worker can listen to it:
'connections' => [
// Other connections...
'sync' => [
'driver' => 'redis',
'connection' => 'sync', // Connection defined in database.php
'queue' => env('SYNC_REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
'after_commit' => false,
],
]Then start the worker (under Supervisor or systemd in production):
php artisan queue:work syncThe worker listens to the default queue on the sync connection and processes every job the source application dispatches.
Conclusion
Two Laravel applications now exchange data through one Redis instance with nothing but the queue primitives Laravel already ships: a shared connection, a matching job class on each side, and a worker. The custom key prefix keeps the synchronization queue isolated from each application's own jobs, and failed-job handling, retries and horizon-style monitoring all apply as usual.
Designing reliable integrations between systems — queues, APIs, webhooks, sync jobs — is everyday work in our API and system integration services. If your applications still exchange data by CSV export, talk to us.
