Keep-Alive WordPress: Dari `.htaccess` ke `fastcgi_keep_conn`, Kenapa Connection Header Tidak Bisa Diaktifkan Manual

8 menit baca
Keep-Alive WordPress: Dari `.htaccess` ke `fastcgi_keep_conn`, Kenapa Connection Header Tidak Bisa Diaktifkan Manual

Laporan PageSpeed memintamu menyalakan keep-alive, kamu menempel Header set Connection keep-alive di .htaccess, lalu curl menunjukkan respons yang sama. Panduan keep-alive wordpress ini menjelaskan kenapa baris itu tidak mengubah apa pun, di lapis mana koneksi benar-benar dipegang, dan kapan menahan koneksi justru membebani pool PHP-FPM sampai 502.

Laporan PageSpeed Menyuruh Nyalakan Keep-Alive, Header-nya Tidak Berubah

Skor PageSpeed atau GTmetrix menulis "enable keep-alive" dan tutorial menjawabnya dengan satu baris Header set di .htaccess. Kamu menyimpannya, memuat ulang, mengecek header respons, dan nilai Connection tetap sama. Wajar kalau server terasa bandel, padahal yang salah lapis tempat saklar ditempel.

Artikel ini memberi tiga hal: alasan header itu bukan saklar, peta dua lapis pemegang soket, dan batas kapasitas yang membuat direktif benar pun terlihat mati. Urutannya penting: mengubah konfigurasi sebelum tahu siapa yang menutup koneksi hanya menambah variabel.

Apa Itu Keep-Alive dan Bagaimana Koneksi TCP Dipakai Ulang

Keep-alive berarti satu koneksi TCP dipakai untuk lebih dari satu request HTTP/1.1 selama tak ada Connection: close dan batas idle atau jumlah request belum tercapai. Pada HTTPS, persistent connection ini juga menghemat handshake TLS, karena salaman kriptografi cukup sekali lalu request berikutnya menumpang soket yang sama.

Istilah wordpress keep-alive sering dibaca seolah WordPress punya modul koneksi sendiri, padahal tidak ada. Ini perilaku server web dan backend PHP, bukan plugin atau setelan wp-config. WordPress hanya menerima manfaatnya: halaman, gambar, CSS, dan JS yang tadinya butuh salaman baru tiap berkas kini antre di soket terbuka.

Batasnya dua pagar: soket yang menganggur terlalu lama ditutup, dan soket yang sudah melayani sekian request ditutup walau masih sibuk. Diagram berikut membandingkan tiga request tanpa pakai ulang melawan tiga request di atas satu salaman.

Diagram dua lajur keep-alive, kiri tiap request mengulang handshake lalu ditutup, kanan satu handshake lalu tiga request dipakai ulang pada soket sama sampai pagar idle dan jumlah request

Mengapa Header .htaccess Tidak Mengubah Keep-Alive di Nginx

Resep Header set Connection keep-alive berasal dari Apache mod_headers dan hanya bermakna di server yang membaca .htaccess. Nginx tidak membaca berkas itu, jadi barisnya tidak pernah dievaluasi. Artikel Nginx vs OpenLiteSpeed menegaskan artikel ini berbicara dari sisi Nginx.

HTTP/1.1 sudah persisten secara default, sehingga tidak ada yang perlu dinyalakan. Yang mematikan persistensi adalah respons yang membawa Connection: close, bukan ketiadaan baris Header set. Connection adalah header hop-by-hop: ia hanya berlaku satu lompatan, sehingga intermediary boleh menutup koneksi walau origin mempertahankannya.

Keep-alive HTTP/1.1 sudah menyala kecuali ada yang menutupnya. Menempel header Connection di .htaccess tidak menyalakan apa pun di Nginx, dan di HTTP/2 header itu justru dilarang.

Di Apache kenop yang benar adalah KeepAlive, MaxKeepAliveRequests, dan KeepAliveTimeout di konfigurasi server; selebihnya artikel ini memakai direktif Nginx dan FastCGI.

Keep-Alive Pengunjung ke Nginx, dan Keep-Alive Nginx ke PHP-FPM

Lapis pertama mengatur soket pengunjung ke Nginx: keepalive_timeout menahan soket menganggur (default 75 detik), keepalive_requests membatasi request per koneksi (default 1000), dan keepalive_time memagari umur total sejak Nginx 1.19.10. Ini lapis klien dalam pola nginx keepalive php-fpm upstream.

Lapis kedua, koneksi Nginx ke PHP-FPM, defaultnya mati: fastcgi_keep_conn on menahan koneksi FastCGI agar dipakai ulang, dan hanya berguna bersama keepalive di blok upstream tujuan fastcgi_pass. Inilah fastcgi_keep_conn wordpress.

Jangan tertukar dengan fastcgi_socket_keepalive, opsi TCP SO_KEEPALIVE. Hop reverse proxy dibahas artikel Reverse Proxy vs Load Balancer.

LapisYang dipegangDirektif yang benarYang bukan saklarnya
Pengunjung ke NginxSoket HTTP klien, batas idle dan jumlah requestkeepalive_timeout, keepalive_requests, keepalive_time di konteks http, server, locationHeader set Connection keep-alive di .htaccess
Nginx ke PHP-FPMKoneksi FastCGI yang dipakai ulangkeepalive di upstream, fastcgi_pass ke sana, fastcgi_keep_conn onfastcgi_socket_keepalive (itu SO_KEEPALIVE TCP, bukan reuse FastCGI), bukan pasangan keepalive_* lapis klien
Diagram tiga kotak browser ke Nginx ke pool PHP-FPM, panah pertama berlabel keepalive_timeout dan keepalive_requests, panah kedua berlabel fastcgi_keep_conn on dan keepalive upstream, cabang putus-putus Connection close dari CDN memutus lapis pertama

Tradeoff: Handshake yang Hilang, Worker yang Tertahan

Manfaatnya terasa pada request kedua dan seterusnya: berkas berikutnya tidak mengulang salaman TCP dan TLS. Pada halaman WordPress dengan puluhan aset, penghematan salaman ini menumpuk walau tidak ada angka produk yang diklaim di sini.

Biayanya adalah soket diam yang tetap memegang file descriptor di Nginx, dan bila fastcgi_keep_conn on, koneksi FastCGI diam yang menempati jalur menuju pool PHP-FPM. Di pool kecil, koneksi persisten tanpa kapasitas tambahan hanya memindah antrean dari salaman ke slot eksekusi. Ujungnya 502 saat trafik naik karena slot PHP-FPM habis tertahan.

Gejalanya terbaca sebagai latensi sebelum menjadi error. Lapis gejalanya milik artikel TTFB WordPress tanpa mengulang cara mengukurnya di sini.

Keep-Alive HTTP/1.1 dan Multiplexing HTTP/2 serta HTTP/3

Di HTTP/1.1 satu koneksi melayani satu respons pada satu waktu, maka browser membuka beberapa koneksi paralel dan keep-alive menghemat salaman di tiap jalurnya. Batas jumlah request per koneksi menjadi rem pola antre ini.

HTTP/2 dan HTTP/3 mengubah aritmetikanya lewat multiplexing: banyak stream menumpang satu koneksi, sehingga salaman per berkas bukan lagi masalah utama. Contoh keep-alive http2 multiplexing yang sehat: biarkan satu koneksi multiplex hidup wajar, bukan menyalin angka kecil resep HTTP/1.1. Detail protokolnya milik artikel HTTP/2 vs HTTP/3.

Risikonya konkret: keepalive_requests yang terlalu kecil menutup seluruh koneksi multiplex sekaligus, sehingga puluhan stream ikut terputus dan bersalaman dari nol. Di listener HTTP/2, angka warisan HTTP/1.1 adalah kandidat pertama yang diperiksa.

Tiga Batas yang Membuat Koneksi Persisten Terlihat Mati

Batas pertama adalah file descriptor: worker_connections per worker dan worker_rlimit_nofile untuk berkas terbuka. Tiap koneksi menganggur memakan satu slot, jadi menaikkan timeout tanpa menaikkan plafon mempercepat kehabisan slot.

Batas kedua adalah backlog kernel: somaxconn dan antrean listen menentukan berapa banyak jabat tangan boleh antre. CPU rendah bukan bukti kapasitas ada, karena penolakan terjadi di antrean.

Batas ketiga adalah slot PHP-FPM: pm.max_children adalah langit-langit proses penahan koneksi FastCGI. Rumus slotnya milik artikel PHP Worker WordPress.

Yang terlihatBatas yang lebih dulu diperiksaBukan kesimpulannya
curl menunjukkan koneksi ditutup setiap requestHeader Connection origin versus hostname publik, lalu keepalive_timeout lapis klienSitus belum menyalakan keep-alive lewat .htaccess
Setelah fastcgi_keep_conn on, muncul 502 saat trafik naikpm.max_children terhadap angka keepalive di upstreamDirektif FastCGI-nya salah ketik
Nginx menolak koneksi baru meski CPU rendahworker_connections, worker_rlimit_nofile, dan somaxconnPerlu menaikkan keepalive_requests setinggi mungkin

Cara Memeriksa dan Mengonfigurasi Keep-Alive pada Server WordPress

Urutannya wajib periksa dulu, baru setel lapis klien, baru lapis upstream. Mengubah upstream sebelum curl membuktikan siapa yang menutup koneksi hanya menambah variabel. Tiga langkah di bawah mulai dari perintah baca saja, lalu dua cuplikan ilustrasi yang disesuaikan dengan versi dan trafik. Jangan menaikkan angka timeout atau menyalakan reuse FastCGI sebelum bukti curl menunjukkan siapa yang menutup koneksi di dua lapis terlebih dahulu, karena setiap perubahan buta menambah variabel diagnosis.

Periksa Header dan Siapa yang Menutup Koneksi

Langkah pertama membandingkan origin melawan hostname publik. Jalankan curl -vI ke IP origin lalu ke domain publik, dan perhatikan ada tidaknya Connection: close pada masing-masing. Ulangi dengan dua URL berurutan atau flag --next agar terlihat apakah request kedua memakai ulang soket yang sama. Bila origin memakai ulang tetapi hostname publik menutup, pemutusnya adalah lapisan depan seperti CDN atau WAF, dan mengubah nginx.conf tidak akan mengubah hasil. Catat temuanmu sebelum lanjut, karena seluruh keputusan dua langkah berikutnya bergantung pada siapa yang terbukti menutup koneksi.

curl -vI https://contoh.test/ 2>&1 | grep -i '^< connection'
curl -v https://contoh.test/satu https://contoh.test/dua 2>&1 | grep -i 'connection\|reuse\|connected'

Setel Batas Idle dan Jumlah Request di Nginx

Langkah kedua menyetel lapis klien di konteks http atau server. keepalive_timeout menahan soket menganggur, keepalive_requests membatasi request per koneksi, dan keepalive_time memagari umur total pada Nginx yang cukup baru. Nilai di bawah ilustrasi belaka: sesuaikan dengan versi dan trafik, bukan rekomendasi universal. Ingat pasangan bernama sama di dalam blok upstream adalah lapis backend yang berbeda dan tidak ikut berubah di sini. Setelah reload, uji ulang dengan perintah langkah pertama dan pastikan reuse muncul sebelum menyentuh lapis FastCGI. Catat angka awalnya, karena perbandingan sebelum dan sesudah inilah bukti perubahan bekerja.

http {
    keepalive_timeout 65;
    keepalive_requests 500;
    keepalive_time 1h;
}

Aktifkan fastcgi_keep_conn pada Upstream PHP-FPM

Langkah ketiga menyalakan reuse FastCGI dengan pola nginx keepalive php-fpm upstream yang lengkap. Buat blok upstream berisi server PHP-FPM dengan angka keepalive kecil dan dokumentasi Nginx memberi contoh 8 sebagai titik mulai, bukan batas wajib, arahkan fastcgi_pass ke nama upstream itu, lalu tambah fastcgi_keep_conn on. Pola fastcgi_keep_conn wordpress ini hanya valid sebagai satu paket, dan angka keepalive yang lebih besar dari kapasitas pool menggeser 502 saat trafik naik. Setelah reload, ulang curl dari langkah pertama dan pastikan tidak ada 502 sebelum menaikkan angka apa pun.

upstream php_backend {
    server 127.0.0.1:9000;
    keepalive 8;
}
location ~ \.php$ {
    fastcgi_pass php_backend;
    fastcgi_keep_conn on;
}

Rekomendasi Infrastruktur untuk Koneksi Persisten yang Stabil

Mayoritas situs cukup di Cloud Hosting Mordenhost: lingkungan server yang dikonfigurasi dan dipantau sysadmin internal, plus dukungan teknis yang memisahkan penyebab plugin dari penyebab server. Jalur ini cocok selama kebutuhanmu diagnosis yang benar tanpa menyentuh nginx.conf.

Situs yang perlu mengubah upstream PHP-FPM dan memeriksa tiga batas di atas cocok di Managed VPS Mordenhost: akses konfigurasi Nginx dan pool PHP-FPM, eksekusi perintah langsung, serta bantuan membaca hasil curl sebelum dan sesudah reload, mulai Rp950.000 per bulan. Verifikasi harga di halaman produk sebelum memesan.

Yang menentukan bukan header di .htaccess, melainkan lapis yang memegang soket dan batas yang menahannya. Kalau fondasi server masih kabur, baca dulu memahami cara kerja hosting sebelum mengubah konfigurasi apa pun di situs produksi.

Pertanyaan yang Sering Ditanya

Empat jawaban singkat soal berkas htaccess, beda dua direktif, relevansi HTTP/2, dan koneksi yang tetap tertutup.

Apakah keep-alive harus dihidupkan lewat file .htaccess?

Tidak di Nginx, karena berkas itu tidak dibaca sama sekali. Pada HTTP/1.1 koneksi persisten sudah perilaku default, jadi yang perlu diperiksa adalah siapa yang mengirim Connection: close lalu batas idle di konfigurasi server.

Apa beda keepalive_timeout dengan fastcgi_keep_conn?

keepalive_timeout membatasi berapa lama Nginx menahan koneksi dari pengunjung yang menganggur. fastcgi_keep_conn memberi tahu PHP-FPM agar koneksi dari Nginx tidak ditutup setelah satu respons, dan hanya bekerja bersama keepalive di blok upstream.

Apakah keep-alive masih penting kalau situs sudah HTTP/2?

Perannya menyusut karena keep-alive wordpress bukan lagi tuas utama di koneksi multiplex. HTTP/2 sudah menumpuk request dalam satu koneksi, jadi menyalin batas jumlah request dari resep lama malah bisa menutup seluruh koneksi itu.

Kenapa koneksi tetap tertutup padahal direktif sudah benar?

Tiga tempat paling sering: file descriptor atau worker_connections penuh, backlog somaxconn terlalu kecil, atau pm.max_children tidak cukup untuk koneksi FastCGI yang ditahan. Bisa juga lapisan depan yang mengirim penutup.

Butuh bantuan membaca hasil curl atau memilih paket yang pas? Hubungi WhatsApp Mordenhost dan tim kami membantu memetakan langkah berikutnya.

TM
Tim Mordenhost
Editorial