Gratis update & dukungan instalasi

Panduan 09 Oct 2026

Cara Kirim Email Otomatis di Laravel dengan Queue: Notifikasi Order, Invoice & Reset Password (Panduan 2026)

R Oleh renz mobellgnd
Cara Kirim Email Otomatis di Laravel dengan Queue: Notifikasi Order, Invoice & Reset Password (Panduan 2026)

Cara Kirim Email Otomatis di Laravel dengan Queue: Notifikasi Order, Invoice & Reset Password (Panduan 2026)

Cara kirim email otomatis di Laravel adalah dengan membuat kelas Mailable atau Notification yang mengimplementasikan ShouldQueue, lalu memicu pengirimannya lewat dispatch() atau Mail::send(). Email tidak dikirim langsung saat request berjalan, melainkan masuk antrean dan diproses di background oleh php artisan queue:work — sehingga halaman website tetap cepat meskipun SMTP lambat.

Kalau kamu baru saja membeli source code Laravel dari KiosKoding — misalnya aplikasi kasir, toko online, atau sistem informasi — email otomatis adalah fitur yang hampir selalu dibutuhkan: notifikasi order baru ke admin, invoice ke pembeli, link reset password, sampai pengingat pembayaran yang belum lunas. Artikel ini membahasnya dari sudut pandang praktis: setup sampai siap produksi, lengkap dengan jebakan yang jarang dibahas tutorial lain.

Kapan Email Otomatis Dibutuhkan di Aplikasi Laravel?

Tidak semua aplikasi butuh email otomatis, tapi untuk aplikasi bisnis, ini daftar kasus yang paling umum:

Kasus Pemicu Penerima
Notifikasi order baruPembeli checkoutAdmin/owner toko
Invoice & bukti pembayaranPembayaran terverifikasiPembeli
Reset passwordUser klik "lupa password"User yang meminta
Pengingat pembayaranInvoice melewati H-1 jatuh tempoPembeli
Laporan harianScheduler tiap jam 06:00Owner/admin

Catatan jujur: queue email Laravel cocok untuk email transaksional (satu per satu, dipicu aksi user). Untuk newsletter ke 10.000 subscriber sekaligus, jangan pakai cara ini — pakai layanan email marketing seperti Mailchimp atau Amazon SES dengan rate limit yang benar. Bahasan batasannya ada di bagian akhir artikel.

Kenapa Harus Pakai Queue, Bukan Kirim Langsung?

Kirim email langsung di controller (Mail::to(...)->send(...) tanpa queue) berarti PHP menunggu koneksi SMTP selesai — biasanya 2–8 detik per email. Kalau dalam satu request kamu kirim 3 email (ke pembeli, admin, dan kurir), user bisa menunggu 15 detik hanya untuk melihat halaman "pesanan berhasil". Di shared hosting dengan SMTP lambat, angkanya bisa lebih parah dan request bisa timeout.

Dengan queue, alurnya berubah:

  1. Request masuk → validasi → simpan ke database
  2. Tugas kirim email didorong ke tabel jobs (hitungan milidetik)
  3. Response langsung dikembalikan ke user (200–300 ms)
  4. Worker di background mengambil job dan mengirim email tanpa mengganggu user

Hasilnya: halaman tetap cepat, email tetap terkirim 100%.

Langkah 1: Konfigurasi SMTP dan Queue di .env

Buka file .env dan isi kredensial SMTP. Untuk development, pakai Mailtrap (gratis) agar email tidak benar-benar terkirim:

MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=isi-username-mailtrap
MAIL_PASSWORD=isi-password-mailtrap
MAIL_FROM_ADDRESS="noreply@tokomu.com"
MAIL_FROM_NAME="Toko Kamu"

QUEUE_CONNECTION=database

QUEUE_CONNECTION=database artinya job disimpan di database — pilihan paling praktis untuk aplikasi kecil-menengah dan shared hosting karena tidak butuh Redis. Kalau traffic-mu besar, Redis lebih cepat, tapi butuh server yang mendukungnya.

Langkah 2: Siapkan Tabel Queue

Laravel 11+ menyediakan perintah untuk membuat migrasi tabel queue:

php artisan queue:table
php artisan queue:failed-table
php artisan migrate

Ini membuat tabel jobs, job_batches, dan failed_jobs. Tabel failed_jobs penting: semua job yang gagal setelah batas retry tercatat di sini, bukan hilang begitu saja.

Langkah 3: Buat Mailable untuk Isi Email

Misalnya email invoice setelah pembayaran terverifikasi:

php artisan make:mail InvoicePaid

Edit app/Mail/InvoicePaid.php agar mengimplementasikan ShouldQueue:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class InvoicePaid extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;

public function __construct(public $order) {}

public function build()
{
return $this->subject('Pembayaran Diterima — Invoice #' . $this->order->invoice_no)
->view('emails.invoice-paid');
}
}

Kunci utamanya: implements ShouldQueue. Tanpa itu, email dikirim sinkron meskipun QUEUE_CONNECTION sudah diset ke database.

Langkah 4: Kirim Email dari Controller

Di controller setelah pembayaran terverifikasi:

use App\Mail\InvoicePaid;
use Illuminate\Support\Facades\Mail;

public function verifyPayment(Order $order)
{
$order->update(['status' => 'paid']);

// Masuk antrean, request tidak menunggu SMTP
Mail::to($order->customer_email)->send(new InvoicePaid($order));

return redirect()->back()->with('success', 'Pembayaran diverifikasi.');
}

Karena InvoicePaid mengimplementasikan ShouldQueue, pemanggilan send() otomatis mendorong job ke antrean.

Alternatif: Pakai Notification

Untuk notifikasi multi-channel (email + database + WhatsApp nantinya), kelas Notification lebih fleksibel:

php artisan make:notification OrderCreated
class OrderCreated extends Notification implements ShouldQueue
{
use Queueable;

public function via($notifiable): array
{
return ['mail', 'database'];
}

public function toMail($notifiable)
{
return (new MailMessage)
->subject('Order Baru #' . $this->order->invoice_no)
->line('Ada order baru senilai Rp ' . number_format($this->order->total))
->action('Lihat Order', url('/admin/orders/' . $this->order->id));
}
}
Mailable Notification
Cocok untukEmail dengan template HTML kompleks (invoice, laporan)Notifikasi singkat multi-channel
TemplateBlade view penuhMailMessage sederhana
ContohInvoice, struk, laporan harianOrder baru, reset password, pengingat

Langkah 5: Jalankan Queue Worker

Di development, jalankan di terminal:

php artisan queue:work --sleep=3

Parameter --sleep=3 berarti worker mengecek antrean tiap 3 detik saat kosong. Selama worker berjalan, setiap job yang masuk langsung diproses dan email terkirim.

Di production, jangan jalankan manual. Worker harus jalan 24/7 dan otomatis restart kalau crash. Di VPS, pakai Supervisor:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/tokomu/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=2
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/tokomu/storage/logs/worker.log

Lalu sudo supervisorctl reread && sudo supervisorctl update. Kalau kamu baru naik kelas dari shared hosting ke VPS, panduan lengkapnya ada di artikel Cara Deploy Laravel ke VPS Ubuntu.

Di shared hosting (tanpa akses Supervisor), triknya: jalankan worker lewat cron tiap menit dengan flag --stop-when-empty:

* * * * * cd /home/username/public_html && php artisan queue:work --stop-when-empty --tries=3 >> /dev/null 2>&1

Worker memproses semua job yang ada lalu berhenti sendiri. Delay maksimal 1 menit — masih wajar untuk notifikasi order.

Menangani Job yang Gagal

Email gagal terkirim karena SMTP timeout atau kredensial salah adalah hal biasa. Laravel otomatis me-retry job yang gagal (sesuai --tries=3), dan kalau tetap gagal, job masuk tabel failed_jobs. Cek dan proses ulang:

php artisan queue:failed # lihat daftar job gagal
php artisan queue:retry all # coba ulang semuanya
php artisan queue:flush # hapus semua job gagal

Tips praktis: pasang notifikasi ke dirimu sendiri saat ada failed job (misalnya via Slack atau email admin), supaya kamu tahu sebelum user komplain. Dan setiap deploy kode baru, jalankan php artisan queue:restart agar worker memuat kode terbaru — worker yang sudah lama jalan tidak otomatis reload.

Kalau email gagal total dan kamu curiga masalahnya di server, bukan kode, cek dulu checklist error 500 setelah upload — seringnya akar masalahnya sama: permission folder, .env yang tidak terbaca, atau ekstensi PHP yang belum aktif.

Jangan Lupa Deliverability: Email Masuk Inbox, Bukan Spam

Email terkirim dari queue belum tentu sampai ke inbox. Tiga hal yang wajib disiapkan di DNS domain-mu:

  1. SPF — TXT record yang menyatakan server mana boleh mengirim atas nama domainmu
  2. DKIM — tanda tangan digital di header email
  3. DMARC — kebijakan apa yang dilakukan penerima kalau SPF/DKIM gagal

Tanpa ketiganya, Gmail dan Outlook makin agresif menandai email sebagai spam — terutama kalau kamu kirim dari shared hosting yang IP-nya dipakai ratusan website lain. Untuk email transaksional penting (invoice, reset password), pertimbangkan SMTP khusus seperti Mailgun, Postmark, atau Amazon SES; biayanya kecil dibanding invoice yang tidak sampai ke pembeli.

Kapan Cara Ini Tidak Cocok?

Jujur saja, queue email Laravel bukan solusi untuk semua kebutuhan email:

  1. Newsletter massal (ribuan penerima sekaligus) — Gmail membatasi ~500 email/hari untuk akun biasa; pakai layanan email marketing dengan fitur unsubscribe dan bounce handling.
  2. Email yang harus realtime < 5 detik — queue database + cron 1 menit punya delay; pakai worker persisten (Supervisor) atau layanan push notification.
  3. Lampiran besar — lampirkan file di job berarti file diserialisasi ke tabel jobs; simpan file di storage dan kirim link download saja.

Checklist Sebelum Go-Live

  1. Test semua template email di Mailtrap, cek tampilan di mobile
  2. QUEUE_CONNECTION production sudah database (atau redis), bukan sync
  3. Worker jalan persisten (Supervisor di VPS / cron di shared hosting)
  4. failed_jobs terpantau — ada notifikasi saat job gagal
  5. php artisan queue:restart masuk dalam skrip deploy
  6. SPF, DKIM, DMARC terpasang di DNS domain
  7. Test kirim email sungguhan di production (order dummy)
  8. Backup database otomatis sudah jalan — tabel jobs ikut ter-backup (panduan backup Laravel)

Queue juga salah satu cara termurah mempercepat aplikasi: memindahkan kerja berat ke background. Teknik lain yang sejalan dibahas di 10 cara mempercepat website Laravel.

FAQ

Apakah email queue tetap terkirim kalau user menutup browser? Ya. Job sudah tersimpan di tabel jobs di database dan diproses worker di server, independen dari browser user.

Berapa lama delay email dengan queue database + cron 1 menit? Maksimal sekitar 1 menit (menunggu cron berikutnya) plus waktu pengiriman SMTP. Untuk notifikasi order dan invoice, ini umumnya masih wajar.

Kenapa email saya tidak terkirim padahal job sukses? Cek tiga hal: kredensial SMTP di .env production, folder storage/logs/laravel.log untuk error detail, dan folder spam penerima. Seringnya masalah ada di autentikasi SMTP atau IP server yang diblokir.

Apakah perlu Redis untuk queue? Tidak wajib. Driver database cukup untuk ratusan–ribuan job per hari. Redis baru terasa manfaatnya saat throughput tinggi (puluhan ribu job/hari) atau butuh fitur lanjutan seperti rate limiting dan job batching.

Bagaimana kalau saya beli source code yang belum pakai queue? Tambahkan implements ShouldQueue ke Mailable/Notification yang ada, set QUEUE_CONNECTION=database, jalankan migrasi queue, dan aktifkan worker. Perubahannya kecil — biasanya di bawah 20 baris kode — tapi dampak kecepatannya besar.

Apakah queue:work perlu dijalankan ulang setelah deploy? Ya, jalankan php artisan queue:restart. Worker yang sedang berjalan memegang kode lama di memori dan tidak otomatis reload.

Bolehkah pakai akun Gmail pribadi sebagai SMTP production? Bisa untuk testing, tapi tidak disarankan untuk production: ada batas ~500 email/hari, butuh App Password (bukan password biasa), dan reputasi pengirimnya buruk untuk email bisnis. Pakai SMTP transactional khusus.