Skip to main content

Queues & Jobs

Background jobs handle all work that should not block an HTTP response — PDF generation, search index updates, notifications, and ERP exports. Laravel Horizon manages workers and provides visibility into queue health.


Queue Priority Configuration

// config/horizon.php
'environments' => [
'production' => [
'billing-worker' => [
'connection' => 'redis',
'queue' => ['billing', 'default'],
'balance' => 'auto',
'minProcesses' => 2,
'maxProcesses' => 5,
],
'default-worker' => [
'connection' => 'redis',
'queue' => ['default', 'notifications', 'sync'],
'balance' => 'simple',
'processes' => 3,
],
],
],
QueuePriorityJobs
billingHighInvoice PDF generation, ERP export flush
defaultNormalDocument processing, search indexing
notificationsLowEmail and push notifications
syncLowMeilisearch index sync

Job Inventory

GenerateInvoicePdfJob

Queue: billing Calls InvoiceGeneratorService::generatePdf(Invoice $invoice), renders the Blade template via spatie/laravel-pdf, uploads the PDF to S3 via Media Library, stores the S3 key on the invoice record, dispatches InvoicePdfReadyNotification.

Retry: 3 attempts with exponential backoff. Financial jobs must never silently fail — failed jobs are preserved in failed_jobs for manual inspection.

FlushErpExportQueueJob

Queue: billing Reads pending rows from erp_export_queue, maps them through ErpPostingRules, posts to the ERP endpoint, marks rows as exported. Runs on a scheduled basis (daily).

SyncMeilisearchIndexJob

Queue: sync Re-indexes a model class (e.g., Matter, Client) in Meilisearch after bulk changes. Dispatched after mass updates or imports.

SendNotificationJob

Queue: notifications Wraps a Laravel Notification and dispatches it to the appropriate channel (database, mail, Reverb broadcast). Decouples notification delivery from the triggering request.

ProcessDocumentJob

Queue: default After a document is uploaded to S3 (via presigned URL), this job verifies the upload exists, updates document status from PENDING_UPLOAD to DRAFT, and triggers search indexing.


Failed Job Handling

# View failed jobs
php artisan queue:failed

# Retry a specific failed job
php artisan queue:retry {id}

# Retry all failed billing jobs
php artisan queue:retry --queue=billing

Financial jobs (GenerateInvoicePdfJob, FlushErpExportQueueJob) must never be retried blindly — inspect the failure reason first to avoid duplicate invoice creation.