Optimasi deploy
Sebelum berburu query lambat, pastikan hal-hal gratis sudah benar. Aplikasi Laravel yang belum di-cache dan tanpa OPcache berjalan jauh di bawah kemampuannya — dan perbaikannya adalah pekerjaan satu sore.
Intisari
php artisan optimizemeng-cache konfigurasi, rute, view, dan event sekaligus.- OPcache wajib menyala di produksi. Tanpa itu, PHP mengurai ulang setiap berkas pada setiap permintaan.
composer install --no-dev --optimize-autoloader— bukan opsi kosmetik.route:cachegagal kalau ada closure di berkas rute. Pindahkan ke controller.- Setiap perintah cache harus dijalankan ulang di setiap deploy, atau kodemu tidak berubah.
Urutan yang dijalankan saat deploy
composer install --no-dev --optimize-autoloader --no-interaction
php artisan optimize # config + route + view + event, sekaligus
php artisan migrate --force
php artisan queue:restart # supaya worker memuat kode baru
| Perintah | Menghilangkan biaya |
|---|---|
config:cache | Membaca dan menggabungkan puluhan berkas config tiap permintaan |
route:cache | Mengevaluasi seluruh berkas rute tiap permintaan |
view:cache | Mengompilasi Blade saat pertama kali diminta |
event:cache | Memindai folder listener untuk menemukan pendengarnya |
--optimize-autoloader | Mencari berkas kelas lewat filesystem |
Setelah config:cache, berkas .env tidak dibaca lagi. Itu sebabnya
env() di luar folder config/ mengembalikan null di produksi — dan itu
sebabnya materi konfigurasi di Fase 0 begitu keras soal aturan ini. Di kontainer, urutannya penting: variabel
environment harus sudah ada sebelum config:cache dijalankan.
OPcache — setelan dengan dampak terbesar
; php.ini produksi
opcache.enable=1
opcache.enable_cli=1 ; wajib untuk RoadRunner & queue worker
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0 ; JANGAN cek perubahan berkas — image bersifat tetap
opcache.jit=tracing
opcache.jit_buffer_size=64M
| Setelan | Kenapa |
|---|---|
validate_timestamps=0 | Menghapus satu stat() per berkas per permintaan. Aman di kontainer karena berkasnya tidak pernah berubah — deploy berarti kontainer baru. |
max_accelerated_files | Aplikasi Laravel biasa punya belasan ribu berkas. Kalau batasnya terlampaui, sebagian tidak ter-cache dan performanya jatuh diam-diam. |
enable_cli=1 | Worker antrean dan RoadRunner berjalan lewat CLI — tanpa ini, keduanya berjalan tanpa OPcache sama sekali. |
jit=tracing | Membantu beban kerja yang berat di CPU. Untuk aplikasi web biasa yang didominasi I/O, dampaknya kecil — ukur, jangan asumsikan. |
validate_timestamps=0 dengan deploy berbasis berkas itu berbahaya. Kalau kamu men-deploy
dengan git pull ke server yang sama, PHP akan terus menjalankan kode lama sampai OPcache
dibersihkan atau proses di-restart. Di deploy berbasis kontainer, masalah ini tidak ada — kontainer baru
berarti proses baru.
Preloading
opcache.preload=/app/preload.php
opcache.preload_user=www-data
Preloading memuat kelas yang paling sering dipakai ke memori sekali saat PHP menyala, sehingga tidak perlu dicari lagi. Manfaatnya nyata di PHP-FPM. Di worker mode (Fase 8), sebagian besar manfaatnya sudah didapat dari fakta bahwa aplikasi tidak dibangun ulang tiap permintaan — jadi jangan berharap perbaikan besar dari menggabungkan keduanya.
Masalah yang muncul saat cache dinyalakan
| Gejala | Penyebab | Perbaikan |
|---|---|---|
route:cache melempar error serialisasi | Ada Route::get('/x', function () {...}) | Pindahkan closure ke controller |
| Kredensial jadi kosong di produksi | env() dipanggil di luar config/ | grep -rn "env(" app/ routes/ |
| Perubahan kode tidak muncul | Cache lama belum diperbarui | Jalankan optimize di setiap deploy |
| Worker antrean memakai kode lama | Proses lama masih hidup | queue:restart, atau ganti task-nya |
Anggaran performa yang layak dipegang
| Metrik | Target yang sehat |
|---|---|
| Waktu respons server (p50) | < 100 ms |
| Waktu respons server (p95) | < 400 ms |
| Query per permintaan | < 15, dan tidak bertambah seiring jumlah baris |
| Waktu di database per permintaan | < 50 ms |
| Memori per permintaan | < 64 MB |
Ukur p95, bukan rata-rata. Rata-rata menyembunyikan halaman yang lambat: sembilan permintaan 50 ms dan satu permintaan 3 detik menghasilkan rata-rata 345 ms yang terlihat "baik-baik saja", padahal satu dari sepuluh penggunamu menunggu tiga detik. Persentil 95 dan 99 yang menceritakan pengalaman sebenarnya.
Latihan: ukur waktu respons satu halaman sebelum dan sesudah php artisan optimize, lalu
sekali lagi setelah OPcache dinyalakan. Pakai curl -w "%{time_total}\n" -o /dev/null -s sepuluh
kali dan bandingkan mediannya.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.