Queue System Overview¶
The Laravel Evolution API package provides robust queue support for reliable message sending and webhook processing.
Why Use Queues?¶
Queues provide several benefits:
- Faster Responses - API requests return immediately
- Reliability - Failed jobs are automatically retried
- Scalability - Process thousands of messages concurrently
- Rate Limiting - Control message throughput
- Monitoring - Track job status with Laravel Horizon
Architecture¶
flowchart LR
A[Your App] -->|Dispatch Job| B[Queue]
B --> C[Worker 1]
B --> D[Worker 2]
B --> E[Worker N]
C -->|API Call| F[Evolution API]
D -->|API Call| F
E -->|API Call| F
F -->|Webhook| G[Webhook Queue]
G --> H[Webhook Processor]
Configuration¶
Enable queues in your configuration:
// config/evolution-api.php
'queue' => [
// Enable queue processing
'enabled' => env('EVOLUTION_QUEUE_ENABLED', true),
// Queue connection (null = default)
'connection' => env('EVOLUTION_QUEUE_CONNECTION', 'redis'),
// Queue name for jobs
'queue' => env('EVOLUTION_QUEUE_NAME', 'evolution-api'),
// Seconds before retrying failed jobs
'retry_after' => env('EVOLUTION_QUEUE_RETRY_AFTER', 90),
// Maximum retries before job fails
'max_exceptions' => env('EVOLUTION_QUEUE_MAX_EXCEPTIONS', 3),
// Backoff between retries (seconds)
'backoff' => [60, 300, 900], // 1min, 5min, 15min
],
Available Jobs¶
SendMessageJob¶
Sends messages via queue:
use Lynkbyte\EvolutionApi\Jobs\SendMessageJob;
// Queue a text message
SendMessageJob::text(
instanceName: 'my-instance',
number: '5511999999999',
text: 'Hello from queue!'
)->dispatch();
// Queue a media message
SendMessageJob::media(
instanceName: 'my-instance',
number: '5511999999999',
mediatype: 'image',
media: 'https://example.com/image.jpg',
options: ['caption' => 'Check this out!']
)->dispatch();
ProcessWebhookJob¶
Processes webhooks via queue:
use Lynkbyte\EvolutionApi\Jobs\ProcessWebhookJob;
// Dispatch webhook for processing
ProcessWebhookJob::dispatch($payload, $instanceName)
->onQueue('webhooks');
// Or use the static constructor
ProcessWebhookJob::fromWebhook($webhookData)->dispatch();
Running Workers¶
Start queue workers to process jobs:
# Basic worker
php artisan queue:work --queue=evolution-api
# With specific connection
php artisan queue:work redis --queue=evolution-api
# Multiple queues with priority
php artisan queue:work --queue=evolution-api,webhooks
# In production (with Supervisor)
php artisan queue:work redis --queue=evolution-api --sleep=3 --tries=3
Queue Separation¶
Separate queues for different job types:
// config/evolution-api.php
'queue' => [
'queue' => 'evolution-messages', // For sending messages
'webhook_queue' => 'evolution-webhooks', // For webhooks
],
Run separate workers:
# Message worker
php artisan queue:work --queue=evolution-messages
# Webhook worker
php artisan queue:work --queue=evolution-webhooks
Laravel Horizon¶
For production, use Laravel Horizon for queue monitoring:
// config/horizon.php
'environments' => [
'production' => [
'evolution-supervisor' => [
'connection' => 'redis',
'queue' => ['evolution-api', 'evolution-webhooks'],
'balance' => 'auto',
'processes' => 10,
'tries' => 3,
'timeout' => 60,
],
],
],
Job Tags¶
Jobs are automatically tagged for easy filtering in Horizon:
// SendMessageJob tags
[
'evolution-api',
'message',
'instance:my-instance',
'type:text',
]
// ProcessWebhookJob tags
[
'evolution-api',
'webhook',
'instance:my-instance',
'event:MESSAGES_UPSERT',
]
Error Handling¶
Automatic Retries¶
Jobs automatically retry on failure:
Failed Job Handling¶
Handle permanently failed jobs:
// In your job or listener
public function failed(\Throwable $exception): void
{
Log::error('Message job failed', [
'instance' => $this->instanceName,
'message' => $this->message,
'error' => $exception->getMessage(),
]);
// Notify team
Notification::route('slack', config('services.slack.webhook'))
->notify(new MessageJobFailed($this, $exception));
}
Event Handling¶
Listen to job events:
use Lynkbyte\EvolutionApi\Events\MessageSent;
use Lynkbyte\EvolutionApi\Events\MessageFailed;
// Successful message
Event::listen(MessageSent::class, function ($event) {
Log::info("Message sent to {$event->message['number']}");
});
// Failed message
Event::listen(MessageFailed::class, function ($event) {
Log::error("Message failed: {$event->exception->getMessage()}");
});
Synchronous Mode¶
Disable queues for synchronous processing:
Or per-request:
use Lynkbyte\EvolutionApi\Facades\EvolutionApi;
// Force synchronous execution
$response = EvolutionApi::for('my-instance')
->messages()
->sendText('5511999999999', 'Sync message');
Best Practices¶
1. Use Redis for Production¶
2. Set Appropriate Timeouts¶
3. Monitor Queue Health¶
// Check queue size
$size = Queue::size('evolution-api');
// Alert if backlog is too large
if ($size > 1000) {
alert('Queue backlog critical!');
}
4. Use Supervisor in Production¶
; /etc/supervisor/conf.d/evolution-worker.conf
[program:evolution-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/artisan queue:work redis --queue=evolution-api --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
numprocs=8
redirect_stderr=true
stdout_logfile=/var/www/storage/logs/worker.log
Next Steps¶
- SendMessageJob - Detailed job documentation
- ProcessWebhookJob - Webhook job documentation
- Error Handling - Error handling strategies