Laravel Queue Job: Cara Membuat dan Menjalankan Background Job

Apa Itu Laravel Queue?

Laravel Queue adalah fitur Laravel yang digunakan untuk menjalankan pekerjaan atau task secara asynchronous di background.

Tanpa Queue, misalnya user melakukan request untuk mengirim 100 email:

User
 ↓
Laravel
 ↓
Kirim 100 Email
 ↓
Response

User harus menunggu seluruh proses selesai.

Dengan Queue:

User
 ↓
Laravel
 ↓
Masukkan Job ke Queue
 ↓
Response Cepat
       │
       ↓
    Queue Worker
       ↓
   Proses Job

Dengan pendekatan ini, task yang membutuhkan waktu lama dapat dipindahkan dari request utama ke background.

Contoh pekerjaan yang cocok menggunakan Queue:

  • Mengirim email
  • Memproses gambar
  • Membuat laporan
  • Mengirim notifikasi
  • Memanggil API eksternal
  • Import data
  • Export data
  • Memproses file
  • Menjalankan proses yang membutuhkan waktu lama

Kenapa Laravel Queue Dibutuhkan?

Bayangkan sebuah halaman checkout melakukan beberapa proses:

Checkout
 ↓
Simpan Order
 ↓
Kirim Email
 ↓
Generate Invoice
 ↓
Kirim Notifikasi
 ↓
Update Statistik
 ↓
Response

Jika semua proses dilakukan dalam satu HTTP request, response dapat menjadi lambat.

Dengan Queue, prosesnya dapat dipisahkan:

Checkout
 ↓
Simpan Order
 ↓
Dispatch Jobs
 ↓
Response

Kemudian:

Queue Worker
 ├── SendOrderEmail
 ├── GenerateInvoice
 ├── SendNotification
 └── UpdateStatistics

User tidak perlu menunggu semua pekerjaan tersebut selesai.

Bagaimana Laravel Queue Bekerja?

Laravel Queue menggunakan beberapa komponen utama:

Laravel Application
        ↓
    Dispatch Job
        ↓
    Queue Backend
        ↓
   Queue Worker
        ↓
    Handle Job

Ada tiga bagian penting:

  1. Job — mendefinisikan pekerjaan yang harus dilakukan.
  2. Queue backend — tempat job menunggu untuk diproses.
  3. Queue Worker — proses yang mengambil job dan menjalankannya.

Queue backend dapat menggunakan beberapa driver, seperti database, Redis, Amazon SQS, dan driver lain yang tersedia sesuai versi Laravel.

Apa Itu Laravel Job?

Job adalah class yang berisi pekerjaan yang ingin diproses oleh Queue.

Contohnya kita ingin mengirim email setelah user melakukan registrasi.

Kita dapat membuat Job:

php artisan make:job SendWelcomeEmail

Laravel akan membuat file Job, biasanya di:

app/Jobs/SendWelcomeEmail.php

Struktur sederhananya:

<?php

namespace App\Jobs;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function handle(): void
    {
        // Proses job
    }
}

Struktur trait atau namespace dapat sedikit berbeda tergantung versi Laravel.

Hal yang paling penting adalah Job mengimplementasikan:

ShouldQueue

Dengan begitu Laravel mengetahui bahwa Job tersebut memang dimaksudkan untuk diproses melalui Queue.

Membuat Laravel Queue Job dari Nol

Sebagai contoh, kita akan membuat Job untuk memproses pesanan.

Jalankan:

php artisan make:job ProcessOrder

Kemudian edit:

app/Jobs/ProcessOrder.php

Contoh sederhana:

<?php

namespace App\Jobs;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;

class ProcessOrder implements ShouldQueue
{
    use Queueable;

    public function handle(): void
    {
        // Proses order
    }
}

Sekarang kita memiliki Job yang siap dimasukkan ke Queue.

Menambahkan Data ke dalam Job

Biasanya Job membutuhkan data.

Misalnya kita ingin mengirim Order ke Job.

<?php

namespace App\Jobs;

use App\Models\Order;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;

class ProcessOrder implements ShouldQueue
{
    use Queueable;

    public function __construct(
        public Order $order
    ) {}

    public function handle(): void
    {
        // Proses order
    }
}

Kemudian Job dapat di-dispatch dengan:

ProcessOrder::dispatch($order);

Laravel akan menyimpan informasi yang diperlukan untuk Job tersebut ke queue.

Laravel juga menangani serialisasi model yang diberikan kepada Job.

Namun, hindari memasukkan data yang sangat besar ke dalam Job.

Lebih baik membawa identifier yang diperlukan dan mengambil data kembali ketika Job dijalankan jika memang sesuai dengan kebutuhan aplikasi.

Apa Itu handle() pada Laravel Job?

Method:

public function handle(): void

adalah tempat utama pekerjaan Job dilakukan.

Contohnya:

public function handle(): void
{
    $order = $this->order;

    // Proses order
}

Ketika Queue Worker mengambil Job tersebut, Laravel akan menjalankan handle().

Secara sederhana:

Queue
 ↓
ProcessOrder
 ↓
handle()
 ↓
Selesai

Menjalankan Job dengan dispatch()

Setelah Job dibuat, kita perlu memasukkannya ke Queue.

Contohnya:

ProcessOrder::dispatch($order);

Laravel kemudian memasukkan Job tersebut ke queue backend.

Jika Worker sedang berjalan, Job akan diambil dan diproses.

Dispatch Job dari Controller

Misalnya:

use App\Jobs\ProcessOrder;

public function store()
{
    $order = Order::create([
        // data order
    ]);

    ProcessOrder::dispatch($order);

    return redirect()
        ->route('orders.show', $order)
        ->with('success', 'Order berhasil dibuat.');
}

Dengan Queue, controller tidak perlu menjalankan seluruh proses berat secara langsung.

Contoh Job Mengirim Email

Misalnya kita memiliki Job:

<?php

namespace App\Jobs;

use App\Mail\WelcomeMail;
use App\Models\User;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Mail;

class SendWelcomeEmail implements ShouldQueue
{
    use Queueable;

    public function __construct(
        public User $user
    ) {}

    public function handle(): void
    {
        Mail::to($this->user->email)
            ->send(new WelcomeMail($this->user));
    }
}

Kemudian dispatch:

SendWelcomeEmail::dispatch($user);

User tidak perlu menunggu proses pengiriman email selesai sebelum mendapatkan response.

Queue Driver Laravel

Laravel membutuhkan queue backend untuk menyimpan Job sebelum diproses Worker.

Beberapa driver yang umum digunakan:

DriverCocok Untuk
syncDevelopment atau testing sederhana
databaseAplikasi sederhana
redisAplikasi yang membutuhkan Queue cepat
sqsInfrastruktur cloud
beanstalkdKebutuhan Queue tertentu

Pilihan driver tergantung kebutuhan aplikasi dan infrastruktur.

Untuk aplikasi Laravel yang sudah menggunakan Redis, Redis Queue sering menjadi pilihan yang praktis.

Queue Driver sync

Driver sync menjalankan Job secara langsung dalam request yang sama.

Contohnya:

QUEUE_CONNECTION=sync

Walaupun kita menggunakan:

ProcessOrder::dispatch($order);

Job tetap akan diproses langsung.

Artinya:

Request
 ↓
Dispatch Job
 ↓
handle()
 ↓
Response

Bukan:

Request
 ↓
Dispatch Job
 ↓
Response
       ↓
    Worker

Karena itu, sync tidak memberikan keuntungan background processing.

Driver ini berguna untuk development atau testing sederhana.

Queue dengan Database

Laravel dapat menggunakan database sebagai queue backend.

Contohnya:

QUEUE_CONNECTION=database

Laravel kemudian menyimpan Job ke tabel queue.

Jika tabel queue belum tersedia, migration queue dapat dibuat sesuai versi Laravel yang digunakan.

Pada versi Laravel tertentu, command yang tersedia adalah:

php artisan make:queue-table

Kemudian jalankan:

php artisan migrate

Setelah itu database memiliki tabel untuk menyimpan Job yang menunggu diproses.

Strukturnya secara konsep:

Laravel
   ↓
jobs table
   ↓
Queue Worker
   ↓
handle()

Queue dengan Redis

Jika Redis sudah digunakan dalam aplikasi Laravel, Redis juga dapat digunakan sebagai Queue backend.

.env dapat menggunakan:

QUEUE_CONNECTION=redis

Redis kemudian menjadi tempat Laravel menyimpan Job yang menunggu diproses.

Arsitekturnya:

Laravel
   │
   ├── Cache ──→ Redis
   │
   ├── Session → Redis
   │
   └── Queue ──→ Redis

Penggunaan Redis untuk Queue akan sangat membantu ketika aplikasi memiliki banyak background job.

Namun, cache, session, dan queue memiliki workload berbeda. Untuk aplikasi production yang besar, perhatikan memory, throughput, monitoring, dan isolasi workload Redis.

Menggunakan Redis sebagai Queue Backend

Jika Redis sudah terpasang, konfigurasi sederhana dapat berupa:

QUEUE_CONNECTION=redis

REDIS_HOST=127.0.0.1
REDIS_PORT=6379

Pastikan Redis berjalan:

redis-cli ping

Hasil yang diharapkan:

PONG

Kemudian bersihkan konfigurasi Laravel jika diperlukan:

php artisan config:clear

Menjalankan Queue Worker

Job tidak akan diproses hanya dengan melakukan dispatch.

Kita membutuhkan Queue Worker.

Untuk menjalankan Worker:

php artisan queue:work

Worker akan terus berjalan dan mengambil Job dari Queue.

Secara sederhana:

Queue
 │
 ├── Job A
 ├── Job B
 └── Job C
       ↓
 queue:work
       ↓
   handle()

Ketika Job selesai, Worker akan mengambil Job berikutnya.

Menguji Queue Worker

Misalnya kita memiliki:

ProcessOrder::dispatch($order);

Kemudian jalankan:

php artisan queue:work

Jika Job berhasil diproses, Worker akan menampilkan informasi pada terminal.

Untuk development, kita dapat membiarkan terminal tersebut tetap terbuka.

Jika terminal ditutup, Worker juga berhenti.

Pada production, kita membutuhkan process manager seperti Supervisor atau systemd agar Worker tetap berjalan.

queue:work vs queue:listen

Laravel memiliki beberapa command terkait Worker.

Yang umum digunakan untuk production adalah:

php artisan queue:work

queue:work menjalankan Worker sebagai proses yang terus bekerja.

Untuk development, terdapat command lain yang mungkin ditemui:

php artisan queue:listen

Namun queue:listen memiliki overhead lebih besar karena framework dapat di-boot ulang untuk setiap Job.

Untuk production, queue:work umumnya lebih sesuai karena Worker dirancang untuk berjalan terus.

Menjalankan Worker untuk Queue Tertentu

Jika aplikasi memiliki beberapa queue:

high
default
low

Kita dapat menentukan queue yang ingin diproses:

php artisan queue:work --queue=high

Untuk beberapa queue:

php artisan queue:work --queue=high,default

Urutan tersebut dapat membantu memprioritaskan Job tertentu.

Memberikan Nama Queue pada Job

Kita dapat menentukan queue:

ProcessOrder::dispatch($order)
    ->onQueue('orders');

Kemudian Worker:

php artisan queue:work --queue=orders

Contoh lainnya:

SendWelcomeEmail::dispatch($user)
    ->onQueue('emails');

Kemudian Worker khusus:

php artisan queue:work --queue=emails

Pemisahan queue dapat membantu ketika aplikasi memiliki jenis Job dengan prioritas berbeda.

Queue Priority

Misalnya aplikasi memiliki:

high
default
low

Kita dapat menjalankan:

php artisan queue:work --queue=high,default,low

Worker akan memprioritaskan queue sesuai urutan yang diberikan.

Contohnya:

high
 ↓
default
 ↓
low

Job penting dapat diproses lebih dahulu daripada Job dengan prioritas rendah.

Menentukan Delay pada Job

Tidak semua Job harus langsung diproses.

Kita dapat memberikan delay:

SendWelcomeEmail::dispatch($user)
    ->delay(now()->addMinutes(5));

Artinya Job baru tersedia untuk diproses setelah waktu tersebut.

Contoh penggunaan:

  • Reminder email
  • Notifikasi tertunda
  • Follow-up
  • Scheduled processing

Membatasi Percobaan Job dengan $tries

Job dapat gagal karena berbagai alasan.

Misalnya API eksternal sedang down.

Kita dapat menentukan jumlah percobaan:

class ProcessOrder implements ShouldQueue
{
    public $tries = 3;

    public function handle(): void
    {
        // proses job
    }
}

Artinya Laravel dapat mencoba Job tersebut sampai tiga kali sesuai mekanisme Queue.

Menentukan Timeout Job

Job yang berjalan terlalu lama dapat menyebabkan Worker menunggu terlalu lama.

Kita dapat menentukan timeout:

public $timeout = 120;

Artinya Job memiliki batas waktu sekitar 120 detik.

Nilai yang digunakan harus disesuaikan dengan jenis pekerjaan.

Job mengirim email mungkin hanya membutuhkan beberapa detik.

Job yang melakukan export data besar mungkin membutuhkan waktu lebih lama.

Menangani Job yang Gagal

Tidak semua Job akan berhasil.

Misalnya:

Laravel
 ↓
Job
 ↓
API eksternal
 ↓
Connection Timeout

Laravel memiliki mekanisme untuk menangani failed jobs.

Kita dapat melihat failed jobs menggunakan:

php artisan queue:failed

Kemudian melakukan retry:

php artisan queue:retry <id>

ID tersebut berasal dari daftar failed jobs.

Membuat Failed Jobs

Konfigurasi failed jobs bergantung pada versi Laravel dan queue setup.

Jika migration failed jobs belum tersedia, Laravel menyediakan command yang sesuai dengan versi framework yang digunakan.

Pada versi Laravel tertentu:

php artisan make:queue-failed-table

Kemudian:

php artisan migrate

Pastikan selalu memeriksa command yang tersedia pada versi Laravel project:

php artisan list

Karena command queue dapat berbeda antarversi Laravel.

Method failed()

Kita juga dapat mendefinisikan method:

public function failed(?Throwable $exception): void
{
    // Proses ketika Job benar-benar gagal
}

Contohnya:

public function failed(?Throwable $exception): void
{
    Log::error('ProcessOrder gagal', [
        'order_id' => $this->order->id,
        'error' => $exception?->getMessage(),
    ]);
}

Method ini berguna untuk:

  • Logging
  • Mengirim notifikasi
  • Mengubah status data
  • Menandai proses sebagai gagal

Job Retry dan Idempotency

Salah satu konsep penting dalam Queue adalah idempotency.

Bayangkan Job:

Process Payment

Job gagal setelah payment sebenarnya sudah berhasil diproses, tetapi response dari payment gateway timeout.

Worker kemudian melakukan retry.

Jika Job tidak dirancang dengan baik, pembayaran dapat diproses dua kali.

Karena itu, Job yang memiliki efek samping penting harus dirancang agar aman ketika dijalankan kembali.

Contohnya gunakan unique transaction ID atau payment reference.

Konsepnya:

Job pertama
 ↓
Payment berhasil
 ↓
Response timeout

Retry
 ↓
Cek transaction ID
 ↓
Sudah diproses?
 ↓
Ya → Jangan proses lagi

Ini sangat penting untuk Job seperti:

  • Payment
  • Order
  • Pengiriman email tertentu
  • Sinkronisasi data
  • API integration

Jangan Memasukkan Data Terlalu Besar ke Job

Hindari memasukkan collection besar:

ProcessOrders::dispatch($thousandsOfOrders);

Lebih baik pecah menjadi Job yang lebih kecil.

Contoh:

100.000 Order
      ↓
Batch
      ↓
1.000 Job
      ↓
Queue Worker

Pendekatan ini lebih mudah di-retry dan dimonitor.

Job Batching

Laravel juga menyediakan mekanisme batch untuk menjalankan banyak Job sebagai satu kelompok.

Konsepnya:

Batch
 ├── Job 1
 ├── Job 2
 ├── Job 3
 └── Job 4

Batch berguna untuk proses seperti:

  • Import data
  • Export data
  • Pemrosesan file
  • Sinkronisasi banyak record

Implementasinya tergantung kebutuhan aplikasi dan versi Laravel.

Queue Middleware

Laravel menyediakan Queue middleware untuk kebutuhan tertentu.

Middleware dapat digunakan untuk:

  • Rate limiting
  • Prevent overlapping
  • Kontrol concurrency
  • Logic tertentu sebelum Job diproses

Contohnya berguna ketika API eksternal memiliki rate limit.

Daripada mengirim request terlalu cepat:

Worker
 ↓
API
 ↓
Rate Limit

kita dapat menerapkan kontrol pada Job.

Job yang Membutuhkan Dependency Injection

Laravel dapat melakukan dependency injection pada method handle().

Contohnya:

public function handle(OrderService $orderService): void
{
    $orderService->process($this->order);
}

Laravel akan melakukan resolve dependency tersebut ketika Job dijalankan.

Ini membantu menjaga Job tetap fokus pada pekerjaan yang harus dilakukan.

Contoh Job yang Lebih Realistis

Misalnya kita ingin memproses order:

<?php

namespace App\Jobs;

use App\Models\Order;
use App\Services\OrderService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;

class ProcessOrder implements ShouldQueue
{
    use Queueable;

    public $tries = 3;

    public $timeout = 120;

    public function __construct(
        public Order $order
    ) {}

    public function handle(OrderService $orderService): void
    {
        $orderService->process($this->order);
    }
}

Kemudian:

ProcessOrder::dispatch($order);

Worker:

php artisan queue:work

Alurnya:

Controller
   ↓
dispatch()
   ↓
Redis
   ↓
Queue Worker
   ↓
ProcessOrder
   ↓
OrderService
   ↓
Selesai

Queue untuk Mengirim Email

Email merupakan salah satu use case Queue yang paling umum.

Contohnya:

Mail::to($user->email)
    ->queue(new WelcomeMail($user));

Laravel dapat memasukkan email ke queue tanpa perlu membuat Job secara manual untuk setiap kebutuhan.

Namun, pastikan konfigurasi mail dan queue sudah benar.

Jika menggunakan Queue:

Request
 ↓
Queue Email
 ↓
Response
 ↓
Worker
 ↓
Mail Server

Ini membuat request utama tidak perlu menunggu proses komunikasi dengan mail server.

Queue untuk Import Data

Misalnya user mengupload file CSV dengan 50.000 data.

Jangan memproses semuanya dalam satu HTTP request:

Upload CSV
 ↓
Proses 50.000 row
 ↓
Response

Request dapat timeout.

Lebih baik:

Upload CSV
 ↓
Simpan File
 ↓
Dispatch Import Job
 ↓
Response
       ↓
    Worker
       ↓
 Proses Data

Data dapat dipecah menjadi chunk agar memory dan waktu proses lebih terkontrol.

Queue untuk API Eksternal

Misalnya aplikasi perlu mengirim 10.000 data ke API eksternal.

Tanpa Queue:

HTTP Request
 ↓
10.000 API Calls
 ↓
Response

Ini sangat tidak ideal.

Dengan Queue:

Application
 ↓
10.000 Jobs
 ↓
Queue
 ↓
Workers
 ↓
API

Worker dapat memprosesnya secara bertahap.

Jika API memiliki rate limit, concurrency dan delay juga dapat dikontrol.

Queue Worker di Production

Di development:

php artisan queue:work

sudah cukup untuk testing.

Tetapi jangan menjalankan Worker production dengan mengandalkan terminal SSH.

Jika terminal ditutup:

SSH Disconnect
 ↓
Worker Stop
 ↓
Queue Tidak Diproses

Untuk production, Worker sebaiknya dikelola oleh process manager seperti Supervisor atau systemd.

Laravel Queue dengan Supervisor

Contoh konfigurasi Supervisor secara sederhana:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/example.com/artisan queue:work redis --sleep=3 --tries=3 --timeout=120
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/example.com/storage/logs/worker.log
stopwaitsecs=3600

Path, user, queue connection, timeout, dan jumlah Worker harus disesuaikan dengan server.

Setelah konfigurasi berubah, Supervisor perlu membaca konfigurasi terbaru.

Contohnya:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl restart laravel-worker:*

Queue Worker dan Deployment

Ada satu hal penting ketika melakukan deployment Laravel.

Queue Worker adalah proses jangka panjang.

Jika kode aplikasi berubah, Worker yang sudah berjalan dapat masih menggunakan kode yang sudah dimuat sebelumnya.

Karena itu setelah deployment, Worker perlu direstart secara graceful.

Laravel menyediakan:

php artisan queue:restart

Command tersebut memberi sinyal kepada Worker agar menyelesaikan Job yang sedang berjalan kemudian berhenti.

Process manager seperti Supervisor kemudian dapat menjalankan Worker kembali.

Alurnya:

Deploy
 ↓
Update Code
 ↓
queue:restart
 ↓
Worker Lama Selesai
 ↓
Worker Berhenti
 ↓
Supervisor
 ↓
Worker Baru

Ini merupakan bagian penting dari deployment Laravel yang menggunakan Queue.

Monitoring Queue

Jangan hanya menjalankan Queue tanpa monitoring.

Pada aplikasi Laravel, kita perlu mengetahui:

  • Apakah Worker berjalan?
  • Berapa banyak Job menunggu?
  • Berapa banyak Job gagal?
  • Apakah Job terlalu lama?
  • Apakah Worker sering restart?
  • Apakah Redis kehabisan memory?
  • Apakah API eksternal sering timeout?

Jika menggunakan Redis, Laravel Horizon dapat digunakan untuk monitoring Queue berbasis Redis.

Horizon memberikan informasi seperti:

  • Job diproses
  • Job gagal
  • Throughput
  • Runtime
  • Queue workload

Ini sangat membantu ketika aplikasi sudah menggunakan banyak background Job.

Queue Worker Tidak Berjalan?

Jika Job sudah di-dispatch tetapi tidak diproses, lakukan pengecekan berikut.

Pertama:

php artisan queue:work

Jika Job langsung diproses, berarti sebelumnya Worker belum berjalan.

Jika menggunakan Redis:

redis-cli ping

Pastikan:

PONG

Kemudian periksa konfigurasi:

QUEUE_CONNECTION=redis

Setelah perubahan .env:

php artisan config:clear

Jika menggunakan Supervisor, cek:

sudo supervisorctl status

Pastikan Worker berstatus RUNNING.

Job Berhenti atau Crash

Jika Worker berhenti tiba-tiba, periksa:

storage/logs/laravel.log

Periksa juga log Supervisor jika digunakan.

Beberapa penyebab umum:

  • Memory terlalu kecil
  • Job membutuhkan waktu terlalu lama
  • Timeout
  • Dependency error
  • Redis bermasalah
  • API eksternal timeout
  • Bug pada kode Job

Queue Job Terlalu Lama

Jika Job membutuhkan waktu lama, jangan langsung menaikkan timeout setinggi mungkin.

Cari tahu penyebabnya.

Misalnya Job:

Process 100.000 records

mungkin lebih baik dipecah:

Process 1.000 records
Process 1.000 records
Process 1.000 records
...

Daripada satu Job yang berjalan puluhan menit.

Job yang lebih kecil biasanya lebih mudah:

  • Di-retry
  • Dimonitor
  • Di-scale
  • Di-debug

Kapan Menggunakan Laravel Queue?

Gunakan Queue jika task:

  • Tidak harus selesai sebelum response
  • Membutuhkan waktu lama
  • Melakukan operasi eksternal
  • Mengirim email
  • Mengolah file
  • Memproses banyak data
  • Membutuhkan retry
  • Dapat dijalankan asynchronous

Contoh sederhana:

User Request
     ↓
Simpan Data
     ↓
Dispatch Job
     ↓
Response

Kemudian:

Queue Worker
     ↓
Proses Background Task

Kapan Tidak Perlu Menggunakan Queue?

Tidak semua proses harus masuk Queue.

Misalnya:

$user = User::find($id);

Jika proses hanya membutuhkan beberapa milidetik, memasukkannya ke Queue justru menambah kompleksitas.

Queue cocok ketika ada alasan nyata untuk melakukan asynchronous processing.

Pertimbangkan:

  • Lama proses
  • Dampak terhadap response time
  • Apakah task bisa dijalankan asynchronous
  • Apakah task membutuhkan retry
  • Apakah task memiliki efek samping penting

Best Practice Laravel Queue Job

Beberapa praktik yang sebaiknya diterapkan:

Buat Job dengan Tanggung Jawab yang Jelas

Hindari Job yang melakukan terlalu banyak hal.

Lebih baik:

SendWelcomeEmail
GenerateInvoice
ProcessOrder
SyncProduct

daripada:

DoEverythingJob

Buat Job Idempotent

Job sebaiknya aman ketika dijalankan kembali.

Terutama untuk:

  • Payment
  • Order
  • API synchronization
  • Notification

Gunakan Retry Secara Bijak

Contoh:

public $tries = 3;

Jangan memberikan retry tanpa batas untuk semua jenis error.

Tentukan Timeout

public $timeout = 120;

Sesuaikan dengan pekerjaan.

Pecah Job Besar

Gunakan chunk atau beberapa Job kecil daripada satu Job yang sangat besar.

Monitor Failed Jobs

Gunakan:

php artisan queue:failed

dan lakukan retry setelah penyebab masalah diperbaiki.

Gunakan Process Manager di Production

Jangan mengandalkan:

php artisan queue:work

dari terminal SSH untuk production.

Gunakan Supervisor atau systemd.

Contoh Arsitektur Laravel Queue dengan Redis

Untuk aplikasi Laravel yang menggunakan Redis:

                    User
                      │
                      ↓
                 Laravel App
                      │
             ┌────────┴────────┐
             │                 │
             ↓                 ↓
          Database          Redis
                               │
                    ┌──────────┴──────────┐
                    ↓                     ↓
                  Cache                 Queue
                                          │
                                          ↓
                                    Queue Worker
                                          │
                              ┌───────────┼───────────┐
                              ↓           ↓           ↓
                           Email       API        Processing

Redis dapat menangani beberapa kebutuhan sekaligus.

Tetapi semakin besar aplikasi, semakin penting untuk memperhatikan kapasitas dan workload Redis.

Kesimpulan

Laravel Queue Job memungkinkan aplikasi menjalankan pekerjaan berat atau tidak mendesak di background sehingga response kepada user dapat menjadi lebih cepat.

Konsep dasarnya sederhana:

Dispatch Job
     ↓
Queue Backend
     ↓
Queue Worker
     ↓
handle()
     ↓
Job Selesai

Contoh paling sederhana:

ProcessOrder::dispatch($order);

Kemudian Worker menjalankan:

php artisan queue:work

Untuk aplikasi yang menggunakan Redis, Queue dapat dikonfigurasi dengan:

QUEUE_CONNECTION=redis

Beberapa hal penting yang perlu diingat:

  • Job harus memiliki tanggung jawab yang jelas.
  • Gunakan Queue untuk pekerjaan yang memang cocok diproses asynchronous.
  • Gunakan retry dan timeout dengan tepat.
  • Rancang Job agar aman ketika diulang.
  • Jangan memasukkan data terlalu besar ke Job.
  • Monitor failed jobs.
  • Gunakan Supervisor atau systemd untuk Worker production.
  • Restart Worker setelah deployment.
  • Jika menggunakan Redis secara intensif, pantau kapasitas dan workload-nya.

Setelah memahami dasar Laravel Queue Job, langkah berikutnya adalah memahami Laravel Queue Failed Jobs, Queue Worker dengan Supervisor, dan Laravel Horizon untuk monitoring Queue berbasis Redis.