Laravel Queue dan Job: Memahami Alur Dispatch, Worker, Retry, dan Failure
5 Oktober 2026 · 7 menit baca
Artikel ini dibuat secara otomatis dengan bantuan AI dan telah ditinjau oleh Arya Anjar Ginantara.

Laravel queue berguna ketika sebuah pekerjaan tidak perlu selesai di dalam request yang sedang dilayani. Contohnya, setelah pengguna mengirim laporan, aplikasi dapat menjadwalkan pembuatan versi ringkasnya sebagai job. Request cukup mencatat bahwa pekerjaan perlu diproses; worker kemudian mengambil job tersebut dari queue.
Pola ini bukan jaminan bahwa aplikasi otomatis lebih cepat, lebih andal, atau bebas dari pekerjaan yang terduplikasi. Queue hanya memindahkan batas waktu pengerjaan. Anda tetap perlu menentukan apa yang terjadi jika job gagal, dicoba ulang, berjalan terlalu lama, atau membaca data yang sudah berubah.
Artikel ini memakai satu alur kecil: membuat job ProcessReport, mengirimnya ke queue, menjalankan worker, lalu menyiapkan batas retry dan failure. Contoh bersifat dokumentasi-guided dan belum dieksekusi pada project nyata.
Bedakan job, queue, connection, dan worker
Job adalah unit pekerjaan yang dapat diproses. Queue adalah antrean tempat job menunggu. Connection adalah konfigurasi koneksi ke backend queue. Worker adalah proses yang mengambil job dari queue lalu menjalankan logikanya.
Laravel menyediakan API queue yang sama untuk beberapa backend, tetapi prasyarat dan perilaku operasional backend tetap berbeda. Karena itu, artikel ini tidak memilih Redis, database, SQS, atau backend lain untuk semua aplikasi.
Jika job tidak menentukan queue tertentu, Laravel menggunakan queue default pada connection yang dipakai. Pembagian ke beberapa queue bisa membantu memisahkan jenis pekerjaan atau prioritas, tetapi aturan prioritas worker dan kapasitas backend merupakan keputusan operasional tersendiri.
1. Bentuk job yang akan diproses
Laravel menyediakan Artisan command untuk membuat class job:
php artisan make:job ProcessReport
Contoh bentuk minimalnya:
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class ProcessReport implements ShouldQueue
{
use Queueable;
public function __construct(
public int $reportId,
) {}
public function handle(): void
{
// Ambil report berdasarkan $this->reportId,
// lalu kerjakan pemrosesan yang diperlukan.
}
}
ShouldQueue memberi tahu Laravel bahwa class tersebut ditujukan untuk diproses melalui queue. handle adalah titik ketika worker menjalankan pekerjaan. Dependency yang diperlukan dapat diinjeksi ke method handle, sesuai mekanisme service container Laravel.
Contoh ini mengirim ID report, bukan menganggap seluruh objek dan keadaan saat request harus dibekukan. Apa yang harus dibaca ulang ketika job berjalan bergantung pada kebutuhan aplikasi. Jika job menerima model Eloquent, Laravel memiliki aturan serialisasi model dan relasi yang perlu Anda pahami sebelum menjadikannya payload job.
2. Dispatch: memasukkan job ke alur asynchronous
Setelah request menyelesaikan bagian yang memang harus segera dijawab, job dapat di-dispatch:
use App\Jobs\ProcessReport;
ProcessReport::dispatch($report->id);
Secara konsep, alurnya menjadi:
- Aplikasi membuat representasi job.
- Job dikirim ke connection dan queue yang dipilih.
- Worker mengambil job yang tersedia.
- Worker memanggil
handle. - Job dianggap selesai jika pemrosesan berakhir tanpa exception yang tidak tertangani.
dispatch tidak sama dengan eksekusi langsung di request. Laravel juga mendokumentasikan dispatch tertunda dan dispatch synchronous, tetapi pilihan itu mengubah kapan pekerjaan dijalankan. Jangan menyimpulkan bahwa semua pemanggilan dispatch pasti diproses di background tanpa memeriksa connection dan mode yang digunakan aplikasi.
Ada satu batas penting jika dispatch berhubungan dengan transaksi database. Jika job berjalan sebelum perubahan transaksi tersedia bagi worker, job dapat membaca keadaan yang belum sesuai harapan. Gunakan mekanisme dispatch-after-commit yang didokumentasikan Laravel atau atur konfigurasi dan timing-nya sesuai kebutuhan aplikasi. Ini hanya aturan timing; ia bukan bukti bahwa seluruh efek eksternal ikut menjadi atomic.
3. Worker mengambil dan menjalankan job
Worker dapat dijalankan dengan command Laravel berikut:
php artisan queue:work
Batas percobaan dan waktu dapat dinyatakan ketika worker atau job dikonfigurasi, misalnya:
php artisan queue:work --tries=3 --timeout=90
Angka 3 dan 90 di atas adalah contoh kebijakan, bukan rekomendasi universal. Nilainya perlu disesuaikan dengan pekerjaan, driver, batas waktu proses, dan cara aplikasi menangani kegagalan. Dokumentasi Laravel juga menyediakan cara menentukan jumlah attempt dan timeout pada level job.
--timeout membatasi durasi kerja yang diperbolehkan dalam satu pemrosesan. Timeout bukan cara untuk menghentikan semua efek samping yang sudah telanjur dilakukan. Jika job mengirim email, menulis file, memanggil layanan eksternal, atau mengubah status sebelum berhenti, desain job harus mempertimbangkan kemungkinan pekerjaan dijalankan lagi.
Inilah alasan idempotency tidak boleh diasumsikan dari penggunaan queue. Sebuah job disebut idempotent hanya jika logika aplikasi memang dirancang dan diverifikasi agar pengulangan input yang sama tidak menimbulkan akibat yang tidak diinginkan. Laravel menyediakan mekanisme queue, bukan bukti bahwa contoh bisnis tertentu sudah idempotent.
4. Ketika job gagal: retry bukan jawaban otomatis
Exception yang tidak tertangani dapat membuat job gagal. Laravel mendokumentasikan pengaturan attempt, backoff, penyimpanan failed jobs, dan command untuk menangani atau mencoba kembali job yang gagal. Secara umum, alurnya dapat dipikirkan seperti ini:
- kegagalan sementara mungkin layak dicoba ulang;
- kegagalan karena data tidak valid mungkin perlu dihentikan dan diperiksa;
- kegagalan berulang dapat dipindahkan ke daftar failed jobs;
- operator atau logika aplikasi menentukan apakah retry aman.
Konfigurasi retry tidak mengubah kegagalan permanen menjadi sukses. Sebelum mengaktifkan retry, tanyakan:
- Apakah operasi dapat dijalankan dua kali tanpa membuat duplikasi?
- Apakah data yang dirujuk masih ada ketika retry berjalan?
- Apakah layanan eksternal memiliki batas atau efek samping yang berbeda?
- Kapan job harus ditandai gagal dan memerlukan pemeriksaan manusia?
Laravel juga mendokumentasikan method failed untuk pekerjaan setelah kegagalan. Isi method tersebut harus diperlakukan sebagai bagian dari desain aplikasi, bukan jaminan bahwa semua proses pemulihan akan selesai.
5. Tiga batas yang perlu dipisahkan
Queue bukan database transaksi. Dispatch setelah commit dapat mencegah worker membaca data terlalu dini, tetapi tidak membuat email, request eksternal, atau operasi file ikut rollback bersama transaksi database.
Retry bukan exactly-once delivery. Pengaturan attempt membantu mengendalikan berapa kali Laravel mencoba memproses job. Itu tidak membuktikan bahwa job hanya pernah dijalankan sekali atau bahwa tidak ada efek samping parsial.
Worker bukan deployment plan. Menjalankan queue:work pada terminal menunjukkan bentuk proses worker secara konseptual. Menjaga worker tetap berjalan, memantau kegagalan, mengatur restart, dan memilih backend memerlukan keputusan infrastruktur yang berada di luar artikel ini.
Cara memilih batas job yang masuk akal
Mulai dari pekerjaan yang jelas dan tidak kritis terhadap respons langsung, misalnya membuat ringkasan report atau mengirim notifikasi setelah data utama tersimpan. Letakkan input minimum yang dapat dibaca ulang oleh job, tentukan kondisi sukses, lalu tulis kondisi gagal yang dapat ditindaklanjuti.
Untuk setiap job, dokumentasikan setidaknya:
- pemicu dan data yang dikirim;
- queue dan connection yang dipakai;
- durasi yang masuk akal serta jumlah attempt;
- operasi yang aman untuk diulang dan yang tidak;
- status atau log yang membantu pemeriksaan;
- keputusan ketika retry terakhir gagal.
Jika pekerjaan membutuhkan hasil segera, tidak boleh tertunda, atau memiliki efek samping yang belum dapat dibuat aman untuk pengulangan, queue mungkin bukan batas yang tepat—atau perlu desain tambahan sebelum dipindahkan ke background.
Ringkasan
Alur Laravel queue yang paling sederhana adalah dispatch → queue → worker → handle → sukses atau gagal. ShouldQueue menandai job untuk pemrosesan asynchronous, queue:work menjalankan worker, dan pengaturan attempt/timeout membantu membatasi cara job diproses. Namun, retry tidak membuktikan idempotency atau exactly-once delivery, dan dispatch tidak otomatis mencakup transaction atau efek eksternal.
Gunakan queue ketika pekerjaan memang boleh dipisahkan dari request. Sebelum mengandalkannya, pastikan batas job, timing transaksi, perilaku saat gagal, dan keamanan pengulangan sudah ditentukan untuk aplikasi Anda. Periksa kembali dokumentasi Laravel 13.x dan konfigurasi driver yang benar sebelum menerapkan contoh ini.
Catatan versi dan batas artikel
Contoh dan istilah di sini mengikuti dokumentasi Laravel 13.x yang diambil pada 4 Oktober 2026 UTC. Sintaks, opsi worker, konfigurasi driver, dan perilaku versi perlu diperiksa ulang saat akan diterapkan. Artikel ini tidak menjalankan command, tidak membuat worker, tidak menguji retry atau timeout, tidak mengukur performa, dan tidak menilai kesiapan produksi aplikasi tertentu.