Masalah dan Cakupan
Sebuah platform pemesanan yang menggunakan PostgreSQL menjalankan 100 instance API stateless dan 20 background worker. Database memiliki max_connections yang disetel ke 500. Migrasi, respons insiden, dan alat operasional memerlukan cadangan 50 koneksi, menyisakan anggaran seluruh aplikasi sebesar 450 koneksi. Lalu lintas puncak adalah 6.000 permintaan per detik, sekitar 70% permintaan mengakses database, dan tracing aplikasi menunjukkan bahwa operasi database menahan koneksi rata-rata selama 40 milidetik. Target p99 end-to-end untuk permintaan API adalah 800 milidetik.
Setiap proses saat ini memiliki pool berukuran 10, sehingga deployment secara teoretis dapat membuat 100 × 10 + 20 × 10 = 1,200 sesi database. Akuisisi koneksi mulai mengalami timeout pada jam sibuk. Terkadang CPU database hanya 55%; di lain waktu, antrean kunci (lock wait) dan latensi kueri juga meningkat. Rancang alokasi pool awal, kebijakan timeout, dan siklus hidup koneksi. Jelaskan cara membedakan pool lokal yang terlalu kecil, kebocoran koneksi (connection leak), transaksi yang panjang, penskalaan replika yang melebihi anggaran, dan overload di dalam database.
Jumlah instance, throughput, waktu penahanan (hold time) 40 milidetik, dan batas 500 koneksi adalah asumsi wawancara, bukan klaim performa universal untuk PostgreSQL, HikariCP, atau PgBouncer. Panduan wawancara backend saat ini masih mengevaluasi pertimbangan performa, keandalan, dan operasional dalam perancangan sistem, dan pertanyaan khusus perancangan connection pool database diterbitkan pada tahun 2026. Keterampilan intinya adalah mengelola konkurensi database dan kepemilikan sumber daya di seluruh replika aplikasi, sehingga kategorinya adalah backend.
Apa yang Dievaluasi oleh Pewawancara
Sinyal pertama adalah memperlakukan pool sebagai kontrol penerimaan konkurensi (concurrency admission control), bukan berasumsi bahwa lebih banyak koneksi menghasilkan lebih banyak throughput. max_connections milik PostgreSQL berlaku untuk seluruh database, dan meningkatkannya akan menambah alokasi sumber daya. Angka yang dikonfigurasi secara independen pada satu instance harus dikalikan dengan replika API, worker, scheduled jobs, dan replika sementara selama rolling release.
Sinyal kedua adalah menggunakan Hukum Little untuk pemeriksaan tingkat besaran (order-of-magnitude) tanpa menyajikan nilai rata-rata sebagai jawaban kapasitas mutlak. Laju kedatangan rata-rata ke database adalah 6,000 × 70% = 4,200 operasi per detik. Okupansi koneksi rata-rata adalah sekitar 4,200 × 0.04 = 168. Hal ini hanya menggambarkan konkurensi rata-rata pada kondisi stabil (steady-state). Lonjakan beban (burst), hold time p99, lock wait, retry transaksi, dan ketidakseimbangan beban antar replika tetap memerlukan pengukuran dan uji beban (load test).
Sinyal ketiga adalah menemukan lokasi antrean dengan bukti dari kedua sisi. Aplikasi harus mengekspos jumlah koneksi aktif, idle, dan pending, latensi akuisisi serta timeout, dan connection hold time. Database harus mengekspos status pg_stat_activity, wait_event, kueri aktif, transaksi idle, dan asal koneksi. Menaikkan pool hanya karena "connection acquisition timed out" bisa jadi hanya memindahkan antrean dari aplikasi ke dalam database.
Terakhir, jawaban harus menetapkan batasan kegagalan (failure boundaries). Desain yang kuat mencakup deadline permintaan, kebocoran koneksi, transaksi panjang, rolling release, autoscaling, restart database, koneksi usang (stale), dan perbedaan antara session pooling dan transaction pooling pada PgBouncer. Jawaban tersebut juga menyebutkan fitur-fitur scoped sesi yang mungkin tidak aman digunakan dengan transaction pooling.
Pertanyaan Klarifikasi Sebelum Menjawab
- Apakah batas 500 koneksi berlaku untuk satu primary atau kluster yang lebih besar? Read replica, target failover, dan akses
operasional mungkin memiliki anggaran yang berbeda. Hitung pool secara terpisah untuk database yang benar-benar melayani masing-masing beban kerja.
- Berapa jumlah replika maksimum? Apakah 100 instance API merupakan kondisi normal atau batas maksimum autoscaling? Rolling release dapat
menjalankan replika lama dan baru secara bersamaan untuk sementara waktu. Konfigurasi yang hanya didasarkan pada replika kondisi stabil dapat melebihi anggaran selama rilis atau insiden.
- Bagaimana distribusi connection hold time? Rata-rata 40 milidetik tidak memperlihatkan p95, p99, panggilan
jaringan di dalam transaksi, atau lock wait. Ekor panjang (long tail) mengendalikan antrean dan timeout, jadi segmentasikan berdasarkan rute, tugas, dan label transaksi.
- Bisakah background work mengantre atau membatasi konkurensi? Batch job yang panjang tidak boleh bersaing bebas dengan permintaan
API yang pendek. Pool terpisah sangat berguna, tetapi setiap pool tetap berbagi anggaran global yang sama yaitu 450.
- Retry apa yang terjadi setelah timeout? Retry langsung tanpa backoff akan meningkatkan laju kedatangan tepat saat
database melambat. Timeout akuisisi harus berada di dalam batas waktu (deadline) permintaan dan bekerja sama dengan admission control, backoff, atau respons kegagalan yang terdefinisi.
- Fitur session-scoped apa yang digunakan aplikasi? Temporary table,
LISTEN, session advisory lock,
status SET lintas transaksi, dan perilaku prepared-statement memengaruhi apakah transaction pooling PgBouncer aman digunakan.
- Di mana proxy koneksi akan dijalankan? Satu instance PgBouncer menciptakan batas kapasitas dan ketersediaan.
Sidecar per node, tier proxy khusus, dan managed proxy memiliki mode kegagalan yang berbeda.
Kerangka Jawaban 30 Detik
"Saya akan mulai dengan anggaran global. Mencadangkan 50 dari 500 koneksi menyisakan 450 untuk aplikasi; batas per proses saat ini jika ditotal mencapai 1.200. Konkurensi rata-rata sebesar 168 hanyalah pemeriksaan skala awal. Alokasi awal dapat memberikan 2 koneksi untuk setiap instance API dan 4 untuk setiap worker, dengan total 280 dan menyisakan ruang bebas (headroom) 170, kemudian disesuaikan di bawah beban puncak. Timeout akuisisi harus berada di dalam batas waktu permintaan 800 milidetik. Saya akan membandingkan pending count pool, latensi akuisisi, dan hold time dengan pg_stat_activity serta wait event. Jika pool mengantre sementara database memiliki kapasitas lebih, periksa ketimpangan (skew), kebocoran, dan batas lokal. Jika kueri atau lock sudah menurun performanya, jangan memperbesar pool. Autoscaling harus menghitung ulang anggaran, dan transaction pooling PgBouncer memerlukan audit session-state."
Pembahasan Mendalam Langkah demi Langkah
Menetapkan Anggaran Koneksi Global
Tulis anggaran sebagai invarian eksplisit:
application_connection_cap
= max_connections
- operations_reserve
= 500 - 50
= 450Jumlah total batas pool API, worker, migrasi, administrasi, dan rolling release harus tetap pada atau di bawah 450. Jika aplikasi lain menggunakan database yang sama, kurangi juga anggarannya. Cadangan operasional bukanlah throughput cadangan untuk lalu lintas normal. Ini menjaga kemampuan untuk terhubung, mengamati, dan memperbaiki database selama insiden.
Pemeriksaan konkurensi rata-rata adalah:
database_arrival_rate = 6,000 × 70% = 4,200 operations/second
average_in_flight = 4,200 × 0.04 seconds = 168Hal ini secara cepat menunjukkan bahwa 1.200 koneksi tidak beralasan untuk beban kerja rata-rata dan bahwa total 20 koneksi mungkin terlalu sedikit. Ini tidak menghasilkan ukuran pool final karena nilai rata-rata menyembunyikan lonjakan beban, p99 hold time, retry transaksi, dan umpan balik antrean. Angka akhir harus menggabungkan SLO layanan, konkurensi aktif database yang berkelanjutan, dan hasil uji beban.
Mengusulkan Alokasi Awal yang Dapat Diuji
Titik awal yang konservatif adalah 2 koneksi per instance API dan 4 per worker:
API cap = 100 × 2 = 200
worker cap = 20 × 4 = 80
allocated = 280
app headroom = 450 - 280 = 170Alokasi worker sebesar 4 hanyalah batas isolasi awal, bukan nilai yang secara langsung ditarik dari "tugas yang lebih lama." Nilai sebenarnya harus mengikuti distribusi hold time, laju kedatangan, dan batas konkurensi dari masing-masing beban kerja. Dua ratus delapan puluh adalah kandidat yang mematuhi anggaran global dan dapat diuji beban; sisa 170 tidak boleh dialokasikan secara otomatis. Jika replika API bertambah menjadi 200, mempertahankan 2 per replika akan menghabiskan 400, dan 80 dari worker akan mendorong total melebihi 450. Penskalaan harus mengurangi batas per instance, membatasi replika maksimum, atau menggunakan proxy untuk menegakkan anggaran koneksi server yang lebih terpusat.
Jangan menyetel minimumIdle yang besar hanya agar setiap proses selalu memiliki koneksi cadangan. Sesi idle tetap menghabiskan batas global. Pool dapat tumbuh sesuai permintaan hingga batas maksimum absolut (hard maximum). Apakah pool perlu mempertahankan jumlah minimum koneksi idle harus dijustifikasi oleh biaya pembentukan koneksi yang terukur dan latensi saat lonjakan trafik.
Mengatur Acquisition Timeout dan Masa Pakai Koneksi
Timeout akuisisi harus lebih pendek dari sisa deadline permintaan. Dengan target p99 800 milidetik, sebuah thread tidak boleh menunggu koneksi selama 30 detik. Pengujian pertama dapat menetapkan akuisisi antara 100 hingga 200 milidetik dan menyesuaikannya berdasarkan distribusi antrean yang terukur. Rentang tersebut adalah pilihan desain skenario, bukan rekomendasi pustaka universal. Setelah timeout, kembalikan error overload yang jelas dan gunakan upstream admission control atau jittered backoff. Jangan mencoba ulang (retry) seketika tanpa batas.
Masa pakai maksimum koneksi (maximum connection lifetime) harus lebih pendek daripada masa pakai paksa apa pun yang diberlakukan oleh database, proxy, atau jaringan, dan harus menyertakan jitter sehingga banyak koneksi tidak kedaluwarsa secara bersamaan. Keepalive ditujukan untuk koneksi idle yang harus tetap valid dan harus berjalan lebih sering daripada masa pakai maksimum. Menguji setiap koneksi sebelum dipinjam (borrow) menambah round trip dan memerlukan pengukuran. Yang lebih penting, tangani operasi pertama yang gagal setelah restart atau failover database dengan benar dan ulangi hanya operasi bisnis yang idempotent.
Menentukan Apakah Pool Aplikasi Merupakan Bottleneck
Setiap pool harus mengekspos setidaknya metrik-metrik berikut dengan label layanan, instance, dan beban kerja:
- batas maksimum yang dikonfigurasi, aktif, idle, dan pending;
- latensi akuisisi p50, p95, dan p99 serta jumlah timeout;
- connection hold time yang ditandai berdasarkan rute, tugas, atau transaksi;
- laju pembuatan, penutupan, validasi gagal, dan pembuatan ulang koneksi;
- total batas teoretis: maksimum pool yang dikonfigurasi dikalikan dengan jumlah replika saat ini.
Interpretasikan kombinasi metrik, bukan nilai yang terisolasi. Meningkatnya pending count dan latensi akuisisi dengan koneksi aktif tertahan di batas maksimum, sementara database masih memiliki kapasitas koneksi aktif dan CPU yang memadai, dapat mengindikasikan pool lokal yang kecil, lalu lintas yang timpang, atau beberapa operasi yang menahan koneksi terlalu lama. Jika pinjaman aktif tidak pernah turun setelah permintaan selesai, atau stack trace tertahan di kode aplikasi, koneksi mungkin tidak dikembalikan. Lonjakan tiba-tiba dalam pembuatan dan penutupan koneksi dapat mengindikasikan ketidakcocokan masa pakai, timeout proxy, atau masalah jaringan.
Gunakan connection scope yang terstruktur sehingga jalur sukses, error, pembatalan, dan early-return semuanya melepaskan koneksi. Ambang batas deteksi kebocoran (leak detection threshold) dapat membantu menemukan jalur kode yang bermasalah, tetapi tidak menggantikan analisis distribusi hold time dan code review. Ambang batas yang terlalu pendek akan melabeli transaksi panjang yang sah sebagai kebocoran.
Menggunakan Bukti PostgreSQL untuk Memisahkan Overload Database
PostgreSQL mengekspos satu baris pg_stat_activity per proses server. Kelompokkan berdasarkan application_name, alamat klien, status (state), dan wait event. Mulailah dengan:
SELECT application_name, state, wait_event_type, wait_event, count(*)
FROM pg_stat_activity
WHERE datname = current_database()
GROUP BY application_name, state, wait_event_type, wait_event
ORDER BY count(*) DESC;Kemudian temukan sesi yang tetap idle di dalam transaksi:
SELECT pid, application_name, xact_start, state_change, wait_event_type, wait_event
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY xact_start;Jika sesi aktif, latensi kueri, lock wait, atau I/O memburuk saat jumlah koneksi meningkat, bottleneck berada pada kueri, transaksi, atau sumber daya database. Memperbesar pool justru meningkatkan pertikaian sumber daya (contention). Jika database mendekati 500 sesi tetapi banyak di antaranya adalah sesi aplikasi yang idle, pool idle per-instance telah menghabiskan anggaran; perkecil ukurannya atau terapkan multipleksing. Jika idle in transaction terus berlanjut, perbaiki batas-batas transaksi karena sesi tersebut menghabiskan koneksi dan dapat menahan kunci atau menghalangi proses vacuum.
Total sesi tidak sama dengan eksekusi paralel. Sesi idle dan sesi yang menunggu kunci membutuhkan penjelasan yang berbeda. CPU pada 55% tidak membuktikan adanya sisa kapasitas database: perebutan kunci, latensi penyimpanan, satu partisi panas (hot partition), atau jalur eksekusi serial dapat memblokir pekerjaan pada penggunaan CPU agregat yang rendah.
Mengisolasi Beban Kerja dan Memperhitungkan Penskalaan
Ketika permintaan API yang pendek dan worker yang panjang berbagi satu pool, beberapa batch job dapat menyebabkan head-of-line blocking. Berikan pool terpisah dan antrean konkurensi terpisah, seperti pembagian 200/80 dalam skenario ini. Isolasi melindungi latensi; ini tidak menciptakan anggaran yang lebih besar. Pool worker harus diizinkan menyusut saat idle, dan tugas-tugas itu sendiri memerlukan batas konkurensi.
Autoscaler harus mengetahui anggaran database. Kendala pasti (hard constraint) yang paling sederhana adalah:
max_replicas × pool_size_per_replica + other_pool_caps <= 450Sertakan lonjakan rolling deployment maxSurge. Jika jumlah replika berubah drastis, batas tetap per-instance membuang kapasitas saat replika sedikit dan melebihi anggaran saat replika banyak. Gunakan pool tetap yang kecil ditambah antrean permintaan, atau gunakan PgBouncer untuk memultipleks banyak sesi klien ke sejumlah koneksi server yang terkontrol. Apa pun pilihannya, tetap batasi konkurensi aktif di dalam database.
Memutuskan Apakah Akan Menggunakan PgBouncer
Session pooling pada PgBouncer mempertahankan koneksi server yang sama hingga sesi klien berakhir. Ini mendukung perilaku sesi PostgreSQL dengan baik tetapi memberikan lebih sedikit multipleksing. Transaction pooling menetapkan koneksi server hanya selama durasi transaksi. Ini dapat mencegah klien yang idle menahan koneksi server, tetapi menghapus asumsi bahwa transaksi berikutnya akan menggunakan sesi server yang sama.
Sebelum menggunakan transaction pooling, lakukan audit terhadap SET/RESET lintas transaksi, LISTEN, session advisory lock, temporary table, dan state sesi lainnya. Jika aplikasi memerlukan semantik tersebut, pertahankan session pooling, berikan pool langsung terpisah untuk jalur-jalur tertentu, atau pindahkan state tersebut ke dalam transaksi. Jumlah koneksi yang lebih rendah saja tidak membuktikan keberhasilan. Uji antrean proxy, kegagalan proxy, autentikasi, pembuatan ulang koneksi, dan failover database.
Menutup Loop Kapasitas dengan Uji Kegagalan
Mulailah dengan beban bertahap (stepped load), tingkatkan menuju 6.000 permintaan per detik, lalu tambahkan burst dan autoscaling. Pada setiap langkah catat p95/p99 end-to-end, latensi akuisisi, pending count, hold time, sesi aktif database, lock wait, latensi kueri, CPU, dan I/O. Bandingkan beberapa kandidat alokasi di sekitar pembagian awal 200/80 dan temukan di mana throughput berhenti tumbuh atau latensi database dan antrean mulai memburuk.
Uji adversarial harus mencakup jalur yang sengaja disisipkan untuk tidak mengembalikan koneksi, beberapa transaksi yang menahan koneksi selama beberapa detik, lock contention, replika lama dan baru yang berjalan bersamaan selama rolling release, restart database, proxy yang memutuskan koneksi server yang ada, dan lonjakan backlog worker. Lulus uji bukan berarti "tidak ada error sama sekali." Di bawah anggaran koneksi global, sistem harus mengalami fail fast atau melakukan load shedding, metrik harus dapat mengidentifikasi antrean, dan pemulihan tidak boleh memicu connection storm.
Contoh Jawaban Berkualitas Tinggi
"Saya akan membagi 500 koneksi database ke dalam anggaran tertentu sebelum memilih angka per-instance. Mencadangkan 50 untuk operasional menyisakan 450 untuk aplikasi. 120 proses saat ini dengan masing-masing 10 koneksi menghasilkan batas teoretis 1.200, sehingga rolling release dan lonjakan beban dapat melampaui batas database.
Deskripsi soal menyebutkan 4.200 operasi database per detik dan rata-rata hold time 40 milidetik. Hukum Little menghasilkan sekitar 168 operasi konkuren rata-rata. Saya akan menggunakan angka tersebut hanya sebagai pemeriksaan skala, bukan kapasitas p99. Alokasi awal dapat memberikan 2 koneksi untuk masing-masing dari 100 replika API dan 4 untuk masing-masing dari 20 worker, dengan total 280 dan menyisakan 170 koneksi sebagai headroom aplikasi. Saya akan menguji beban kandidat di sekitar 280 dengan distribusi hold time yang sebenarnya, burst, dan lock contention. Batas maksimum autoscaling dan replika rolling release harus dimasukkan ke dalam formula; jika tidak, 200 replika API ditambah pool worker akan melebihi 450.
Timeout akuisisi harus berada di dalam batas waktu permintaan 800 milidetik. Saya akan mulai dengan menguji 100 hingga 200 milidetik. Di sisi aplikasi, saya akan memantau koneksi aktif, idle, pending, latensi akuisisi, jumlah timeout, hold time, dan pembuatan ulang koneksi. Di PostgreSQL, saya akan mengelompokkan pg_stat_activity berdasarkan application_name dan memeriksa sesi aktif, idle, idle in transaction, serta wait event. Jika pool mengantre sementara database memiliki headroom yang aman, periksa skew replika, batas lokal, dan koneksi yang tidak dilepaskan. Jika kueri, lock, atau I/O sudah menurun performanya, pool yang lebih besar hanya akan meningkatkan konkurensi database. Jika sebagian besar sesi mendekati max_connections berada dalam kondisi idle, perkecil pool idle per-instance atau multipleks koneksi tersebut melalui proxy.
Saya akan mengisolasi API pendek dan worker panjang dengan pool dan batas konkurensi terpisah, sambil menjaga total penjumlahannya di bawah
- Jika PgBouncer diperlukan, saya akan memilih modenya secara terukur: session pooling mempertahankan kompatibilitas lebih baik;
transaction pooling memultipleks lebih agresif tetapi memerlukan audit terhadap LISTEN, session advisory lock, temporary table, dan SET lintas transaksi. Terakhir, saya akan memvalidasi p99, antrean, total koneksi, dan pemulihan dengan beban bertahap, burst, simulasi kebocoran, transaksi panjang, lock contention, rolling deployment, restart database, dan pemutusan koneksi proxy."
Kesalahan Umum
- Menetapkan 20 koneksi untuk setiap instance → total sesi menjadi tidak terkendali saat jumlah replika berubah →
tentukan anggaran seluruh database terlebih dahulu dan bagikan ke semua pool serta replika maksimum.
- Mengonfigurasi tepat 168 koneksi dari nilai rata-rata → mengabaikan burst, p99 hold time, lock wait, dan granularitas
alokasi → gunakan Hukum Little sebagai pemeriksaan skala, lalu putuskan dengan distribusi data dan uji beban.
- Meningkatkan ukuran pool setiap kali akuisisi timeout → antrean aplikasi dapat berpindah ke lock database, I/O, atau antrean
CPU → periksa pending count pool bersamaan dengan sesi aktif database, wait event, dan latensi kueri.
- Hanya melihat CPU database → lock, latensi penyimpanan, dan hot spot dapat memblokir koneksi pada penggunaan CPU yang rendah →
interpretasikan sesi berdasarkan status (state) dan wait event.
- Mengabaikan koneksi idle → pool idle di banyak replika dapat menghabiskan
max_connectionsterlebih dahulu →
pantau batas pool dikalikan jumlah replika dan kendalikan batas minimum idle.
- Memperlakukan idle-in-transaction seperti idle biasa → transaksi dapat menahan kunci, mempertahankan snapshot lama, dan menghambat
proses pembersihan (cleanup) → temukan awal transaksi dan batasan kode serta terapkan timeout yang sesuai.
- Menyatukan semua beban kerja dalam satu pool → worker yang panjang menempati koneksi yang dibutuhkan oleh API yang pendek →
isolasikan pool dan antrean berdasarkan profil latensi tanpa melebihi anggaran global.
- Mengadopsi PgBouncer dan langsung menggunakan transaction pooling secara default → state sesi dapat hilang antar transaksi atau berpindah
ke koneksi server lain → audit kompatibilitas sebelum memilih mode pooling.
- Mencoba ulang (retry) semua error koneksi seketika → pemulihan database akan menghadapi connection storm dan laju kedatangan yang jauh lebih tinggi →
batasi retry, tambahkan jittered backoff, dan ulangi hanya operasi yang bersifat idempotent.
- Hanya menguji kondisi stabil (steady state) → rolling release, penskalaan, transaksi panjang, dan restart database sering kali menyingkap kegagalan anggaran dan
siklus hidup koneksi → sertakan skenario-skenario ini dalam matriks penerimaan.
Pertanyaan Lanjutan
Pertanyaan Lanjutan 1: Mengapa Lebih Banyak Koneksi Dapat Membuat Sistem Menjadi Lebih Lambat?
CPU, cache, lock, dan bandwidth penyimpanan database bersifat terbatas. Di luar konkurensi aktif yang dapat ditangani secara optimal, penambahan koneksi akan meningkatkan context switching, perebutan cache, dan lock wait. Setiap kueri menjadi lebih lambat, yang memperpanjang connection hold time dan menciptakan lingkaran umpan balik positif (kondisi semakin memburuk). Pool yang kecil menyediakan antrean terbatas di aplikasi, yang biasanya lebih mudah dikendalikan daripada membiarkan setiap permintaan masuk ke database. Namun, pool tidak boleh terlalu kecil hingga kapasitas database yang aman menjadi tidak terpakai.
Pertanyaan Lanjutan 2: Apa yang Berubah Jika API Berskala Menjadi 200 Instance?
Mempertahankan 2 koneksi per instance akan menghasilkan 400 koneksi API; 80 koneksi dari worker akan mendorong total melebihi 450. Kurangi setiap pool API menjadi 1 dan alokasikan ulang anggaran worker, batasi replika maksimum dan lonjakan rolling release, atau multipleks klien dengan PgBouncer. Gunakan uji antrean lonjakan beban (burst queueing) dan uji konkurensi database yang berkelanjutan untuk mengambil keputusan. Autoscaler tidak boleh hanya melihat CPU sambil mengabaikan kapasitas database di hilir.
Pertanyaan Lanjutan 3: Bagaimana Cara Membuktikan Kebocoran Koneksi Dibandingkan Kueri yang Memang Lambat?
Kebocoran sering kali tampak sebagai peminjaman aktif yang terus meningkat, permintaan pending yang persisten, dan permintaan yang sebenarnya sudah selesai sementara sesi databasenya mungkin berstatus idle. Kaitkan setiap peminjaman dengan rute, tugas, dan sampel stack trace; bandingkan hold time dengan masa aktif permintaan; dan periksa jalur exception, pembatalan, serta early-return. Jika sesi PostgreSQL tetap aktif atau menunggu pada sebuah lock, jelaskan kueri dan transaksinya sebelum melabelinya sebagai kebocoran koneksi.
Pertanyaan Lanjutan 4: Bisakah Formula Ukuran Pool Milik HikariCP Diterapkan Secara Langsung?
(core_count × 2) + effective_spindle_count adalah heuristik awal dalam dokumentasi HikariCP, yang secara eksplisit menyarankan untuk melakukan uji beban di sekitar nilai tersebut. SSD, cache hit rate, jenis kueri, dan database jarak jauh dapat mengubah hasilnya. Yang lebih penting, ketika satu database digunakan bersama oleh banyak replika aplikasi, setiap nilai kandidat tingkat database tetap harus dibagi di antara semua replika tersebut. Formula tersebut tidak dapat menggantikan anggaran global 450 atau bukti SLO nyata.
Pertanyaan Lanjutan 5: Apakah Prepared Statements Selalu Tidak Didukung pada Transaction Pooling PgBouncer?
Jangan membuat klaim mutlak di semua versi dan konfigurasi. Validasi matriks fitur PgBouncer terhadap versi yang digunakan, dukungan prepared-statement tingkat protokol, dan pengaturan driver. Transaction pooling tetap tidak menjamin bahwa dua transaksi akan menggunakan sesi server yang sama. Buat daftar semantik sesi aktual yang diandalkan aplikasi, verifikasi dalam pengujian integrasi, lalu pilih transaction pooling, session pooling, atau pool langsung untuk masing-masing jalur.
Pertanyaan Lanjutan 6: Latensi Akuisisi Turun Setelah Memperbesar Pool, tetapi p99 End-to-End Meningkat. Mengapa?
Antrean telah berpindah dari pool aplikasi ke dalam database. Dengan semakin banyaknya kueri yang masuk secara bersamaan, perebutan lock, I/O, atau antrean CPU meningkatkan waktu eksekusi kueri. Metrik akuisisi yang lebih baik tidak berarti latensi pengguna menjadi lebih baik. Bandingkan p99 end-to-end, durasi kueri database, wait event, dan throughput, lalu pilih titik konkurensi yang memberikan total latensi terendah dengan ketersediaan ruang (headroom) yang stabil.