Laravel menyediakan dua metode powerful untuk menangani data dalam jumlah besar: chunk()
dan cursor()
. Keduanya sering jadi pilihan utama saat kita ingin memproses ribuan hingga jutaan record tanpa membebani memori server. Tapi, kapan sebaiknya kamu memilih chunk, dan kapan cursor? Yuk, kita bahas secara mendalam, lengkap dengan contoh kode, best practices, dan tips troubleshooting!
Prasyarat & Setup
- Laravel 10.x atau terbaru
- Database MySQL/PostgreSQL
- Pastikan environment sudah siap (composer, artisan, dsb)
Konsep Dasar: chunk() vs cursor()
chunk()
memproses data dalam batch (kelompok), sedangkan cursor()
mengambil data satu per satu menggunakan generator. Analogi sederhananya: chunk seperti mengambil sekotak donat sekaligus, cursor seperti mengambil satu per satu donat dari rak.
Implementasi chunk()
// Proses user dalam batch 200 record
tuse App\Models\User;
User::chunk(200, function ($users) {
foreach ($users as $user) {
// Proses setiap user
}
});
- Setiap batch akan di-load ke memori, diproses, lalu batch berikutnya diambil.
- Cocok untuk proses yang butuh kecepatan dan server punya memori cukup.
Implementasi cursor()
// Proses user satu per satu (sangat hemat memori)
use App\Models\User;
foreach (User::cursor() as $user) {
// Proses setiap user
}
- Hanya satu record yang di-load ke memori pada satu waktu.
- Cocok untuk data sangat besar atau server dengan memori terbatas.
Perbandingan Teknis
Fitur | chunk() | cursor() |
---|---|---|
Memory | Batch (lebih besar) | Satu record (sangat kecil) |
Kecepatan | Lebih cepat (batch) | Lebih lambat (iteratif) |
Kemudahan | Perlu callback | Sangat simpel |
Use Case | Data besar, memori cukup | Data sangat besar, memori terbatas |
Best Practices & Tips
- Selalu tentukan ukuran chunk yang optimal (misal 200-500 record per batch)
- Untuk proses berat (misal export, migrasi), gunakan cursor agar server tetap stabil
- Hindari perubahan data di tengah proses chunk/cursor (bisa menyebabkan data loncat/terlewat)
- Tambahkan error handling di callback chunk/cursor
Error Handling
User::chunk(200, function ($users) {
foreach ($users as $user) {
try {
// Proses user
} catch (\Exception $e) {
\Log::error('Gagal proses user: ' . $e->getMessage());
}
}
});
Edge Cases & Pitfalls
- Jika data berubah (misal dihapus) saat proses chunk, batch berikutnya bisa skip/duplikat data
- cursor() tidak bisa digunakan untuk query dengan eager loading yang kompleks
- chunk() lebih boros memori jika batch terlalu besar
Testing & Debugging
- Uji dengan dataset dummy minimal 10.000 record
- Monitor memory usage dengan tools seperti Laravel Telescope atau debugbar
- Logging setiap batch/record untuk trace error
Next Steps & Resources
Dengan memahami perbedaan chunk dan cursor, kamu bisa memilih strategi paling efisien untuk kebutuhan aplikasi. Jangan lupa, selalu test di environment development sebelum deploy ke production!