Bali, Indonesia
Insights

Kenapa Admin WordPress Lemot Setelah Pindah Server Gara-Gara DNS Resolver Timeout

October 24, 2026
0:00
Setelah situs WordPress dipindah ke server baru, ada keluhan yang cukup sering muncul. Halaman depan terbuka normal, tapi begitu masuk wp-admin, tiap klik menggantung beberapa detik. Dashboard lambat, halaman Plugins lebih lambat lagi, kadang sampai keluar error timeout. Padahal spesifikasi server baru lebih besar. Di banyak kasus seperti ini, penyebabnya bukan PHP atau database. Server sedang menunggu DNS resolver yang tidak menjawab.
Frontend dan admin WordPress bekerja dengan cara yang berbeda. Frontend biasanya dilayani dari page cache atau cukup query ke database lokal. Admin justru sering menghubungi server lain di internet. WordPress mengecek versi core, plugin, dan tema ke api.wordpress.org. Widget berita di Dashboard mengambil feed dari luar. Plugin premium sering memvalidasi lisensi atau mengambil notifikasi dari server vendornya. Semua request ini lewat WordPress HTTP API, yaitu fungsi seperti wp_remote_get() dan wp_remote_post(). Sebagian besar berjalan secara blocking, artinya PHP menunggu jawaban dulu sebelum lanjut menyusun halaman. Sebelum bisa membuka koneksi ke api.wordpress.org, server harus menerjemahkan nama itu ke alamat IP. Di Linux, tugas ini biasanya dikerjakan resolver bawaan glibc, yang membaca daftar nameserver dari /etc/resolv.conf. Kalau nameserver pertama di daftar itu tidak menjawab, resolver tidak langsung pindah ke nameserver berikutnya. Secara default ia menunggu sekitar 5 detik per percobaan dan bisa mengulang sebelum menyerah. Detailnya ada di man resolv.conf, pada opsi timeout dan attempts. Kalau satu halaman admin memicu beberapa request keluar ke hostname yang berbeda, waktu tunggu ini menumpuk. Halaman baru selesai setelah jauh lebih lama dari seharusnya. Masalah ini membingungkan karena tidak ada error yang mencolok. Log PHP sering bersih, CPU santai, MySQL tidak sibuk. Server hanya diam menunggu jawaban.
Saat admin lambat setelah migrasi, yang pertama dicurigai biasanya memory_limit, OPcache, atau database yang belum dioptimasi. Semua itu tetap layak dicek, tapi ada ciri yang membedakannya dari masalah DNS. Masalah resource cenderung membuat semua halaman lambat, termasuk frontend yang tidak ter-cache. Gejalanya juga terlihat di CPU, iowait, atau slow query log. Masalah DNS muncul sebagai waktu tunggu yang konsisten, sering mendekati angka bulat seperti 5 atau 10 detik, sementara resource server hampir idle. Dari sisi WordPress, ada dua cara cepat untuk memisahkan keduanya. Pertama, pakai plugin Query Monitor. Plugin ini punya panel untuk HTTP API calls yang menampilkan tiap request keluar beserta durasi dan error-nya. Arahnya sudah jelas kalau kamu melihat request ke api.wordpress.org atau domain vendor plugin yang makan waktu lama, atau gagal dengan pesan seperti cURL error 28 (timeout) atau Could not resolve host. Kedua, sebagai tes sementara, tambahkan define( 'WP_HTTP_BLOCK_EXTERNAL', true ); di wp-config.php. Konstanta ini memblokir semua request HTTP keluar dari WordPress. Kalau admin mendadak cepat, masalahnya ada di jalur keluar. Hapus lagi konstanta ini setelah tes, karena selama terpasang, update dan validasi lisensi plugin ikut terblokir. Di meja support, tes ini berguna karena hasilnya mudah dijelaskan ke pemilik situs. WordPress-nya tidak berat. Ada sesuatu di luar yang sedang ditunggu.
Tes di level WordPress baru membuktikan bahwa request keluar lambat. Itu belum tentu DNS. Bisa juga firewall memblokir koneksi keluar ke port 443, atau route IPv6 di server baru rusak. Untuk memisahkan tahap resolusi nama dari tahap koneksi, jalankan perintah berikut dari server itu sendiri:
BASH
# Waktu resolusi lewat jalur yang sama dengan aplikasi (glibc/NSS)
time getent ahosts api.wordpress.org

# Rincian waktu tiap tahap koneksi
curl -o /dev/null -s -w 'dns: %{time_namelookup}s  connect: %{time_connect}s  total: %{time_total}s
' https://api.wordpress.org/
getent dipakai karena jalurnya sama dengan aplikasi biasa: membaca /etc/nsswitch.conf, lalu /etc/hosts, lalu resolver. dig dan nslookup langsung bertanya ke DNS server tanpa lewat jalur itu, jadi hasilnya bisa berbeda dari yang dialami PHP. Untuk PHP sendiri, ekstensi cURL biasanya memakai resolver sistem, tapi itu tergantung cara libcurl di server di-build. Pada output curl, perhatikan nilai time_namelookup. Kira-kira seperti ini kalau resolver bermasalah (contoh format output, bukan hasil nyata):
TEXT
dns: 5.012s  connect: 5.180s  total: 5.640s
Nilai DNS yang hampir pas 5 detik adalah tanda kuat. Nameserver pertama timeout, lalu resolver pindah ke nameserver berikutnya dan berhasil. Sebaliknya, kalau time_namelookup hampir nol tapi time_connect besar atau koneksinya gagal, masalahnya ada di jaringan atau firewall, bukan DNS. Jalankan tes ini beberapa kali. Kalau server punya cache DNS lokal seperti systemd-resolved atau nscd, percobaan kedua bisa terlihat cepat karena jawabannya diambil dari cache. Gejala di admin baru muncul lagi setelah cache kedaluwarsa.
Setelah DNS terbukti jadi penyebab, cari tahu nameserver mana yang bermasalah. Tes tiap nameserver di /etc/resolv.conf secara terpisah dengan timeout pendek:
BASH
cat /etc/resolv.conf

# Tanya tiap nameserver secara terpisah, timeout dibuat pendek
for ns in (awk '/^nameserver/ {print2}' /etc/resolv.conf); do
  echo "== $ns"
  dig @$ns api.wordpress.org +time=2 +tries=1 +short
done
Nameserver yang sehat langsung mengembalikan alamat IP. Nameserver yang bermasalah berakhir dengan pesan timeout atau tidak bisa dihubungi. Setelah migrasi, ada beberapa pola penyebab yang sering muncul. Yang paling umum, /etc/resolv.conf ikut terbawa dari server lama. Ini bisa terjadi karena seluruh /etc di-rsync atau server dibuat dari image template. Isinya menunjuk ke resolver internal milik jaringan lama, yang biasanya hanya melayani IP dari jaringannya sendiri. Dari jaringan baru, query ke resolver itu dibuang tanpa jawaban, jadi resolver di server menunggu sampai timeout. Pola kedua, isinya nameserver 127.0.0.1, padahal resolver lokal seperti BIND atau unbound tidak terpasang atau tidak berjalan di server baru. Kalau isinya 127.0.0.53, server memakai stub systemd-resolved. Jalankan resolvectl status untuk melihat server upstream yang sebenarnya dipakai, lalu tes upstream itu dengan dig. Kemungkinan lain ada di jaringan. Firewall outbound di server baru atau di jaringan provider bisa memblokir port 53. Bisa juga daftar nameserver berisi alamat IPv6, padahal server belum punya konektivitas IPv6. Ada juga kasus yang lebih halus. Semua nameserver menjawab, tapi resolusi tetap selalu telat sekitar 5 detik. Ini kadang terkait query A dan AAAA yang dikirim bersamaan, lalu salah satu jawabannya dibuang oleh perangkat di jaringan. Opsi single-request di resolv.conf dibuat untuk situasi ini, tapi pakai hanya kalau gejalanya memang cocok.
Perbaikannya biasanya sederhana: ganti nameserver yang mati dengan yang responsif dan dekat secara jaringan. Pilihannya bisa resolver dari provider jaringan server baru, atau resolver caching lokal yang benar-benar berjalan. Memakai resolver publik juga bisa, tapi ada trade-off soal latensi dan packet loss. Bagian itu dibahas di Why Using Public Resolvers in resolv.conf Stalls Apache Workers. Sebelum mengedit, cek dulu siapa yang mengelola file itu. Jalankan ls -l /etc/resolv.conf. Kalau hasilnya symlink ke direktori systemd, file itu dibuat ulang oleh systemd-resolved. Di distro dan image lain, pengelolanya bisa netplan, NetworkManager, atau cloud-init. Di server cPanel, nameserver resolver biasanya diatur lewat WHM. Kalau kamu mengedit langsung file yang dikelola layanan lain, perubahannya bisa hilang saat reboot. Masalahnya kemudian kembali tanpa ada yang ingat penyebabnya. Menurunkan timeout dengan options timeout:2 attempts:2 memang bisa memperpendek waktu tunggu kalau nameserver pertama gagal. Tapi itu cuma tambalan. Server tetap membuang waktu di setiap query ke nameserver yang mati, jadi tetap perbaiki daftarnya. Setelah konfigurasi diubah, reload PHP-FPM atau web server. Worker yang sudah lama berjalan belum tentu langsung membaca konfigurasi resolver yang baru, tergantung versi glibc, jadi reload adalah cara aman. Lalu ulangi pengecekan. Jalankan getent dan curl lagi dan pastikan time_namelookup sudah turun ke milidetik. Buka wp-admin dan cek panel HTTP di Query Monitor. Terakhir, pastikan WP_HTTP_BLOCK_EXTERNAL sudah dihapus dari wp-config.php. Kalau admin WordPress lambat setelah pindah server sementara frontend normal dan resource server santai, cek DNS resolver sebelum menyentuh setting PHP atau MySQL. Satu baris curl dengan time_namelookup sudah cukup untuk menunjukkan apakah waktu habis untuk menunggu DNS. Dari situ, tes nameserver satu per satu dan perbaiki di layanan yang benar-benar mengelola resolv.conf. Untuk ke depannya, masukkan cat /etc/resolv.conf dan satu tes getent ke checklist setelah migrasi. Cek itu cuma butuh beberapa detik.