Database connection pooling Node.js merupakan teknik untuk mengelola koneksi database agar aplikasi backend dapat bekerja lebih efisien. Dengan menggunakan kembali koneksi yang tersedia, developer dapat mengurangi proses pembentukan koneksi berulang dan mengontrol jumlah koneksi aktif pada database.
Teknik ini penting untuk aplikasi yang memiliki banyak permintaan, seperti toko online, sistem pemesanan, dashboard admin, dan layanan REST API. Dalam artikel ini, kita akan membahas cara kerja connection pooling, contoh implementasi PostgreSQL, serta tips untuk menghindari masalah koneksi pada aplikasi Node.js.
Apa Itu Database Connection Pooling Node.js?
Database connection pooling Node.js adalah mekanisme yang menyediakan sekumpulan koneksi database untuk digunakan secara bergantian oleh aplikasi. Daripada membuka koneksi baru untuk setiap permintaan, aplikasi dapat memanfaatkan koneksi yang sudah tersedia.
Sebagai contoh, sebuah aplikasi toko online perlu mengambil informasi produk setiap kali pengunjung membuka halaman katalog. Jika setiap permintaan selalu membuat koneksi baru, proses tersebut dapat menambah beban kerja server.
Dengan connection pooling, aplikasi dapat menggunakan kembali koneksi yang telah tersedia. Cara ini membantu mengurangi overhead pembentukan koneksi dan membuat pengelolaan sumber daya lebih terkontrol.
Namun, connection pooling tidak otomatis mempercepat semua query. Performa juga dipengaruhi oleh indeks database, struktur tabel, kompleksitas query, dan kapasitas server.
Mengapa Connection Pooling Penting untuk Backend?
Pengelolaan koneksi menjadi semakin penting ketika aplikasi menerima banyak permintaan secara bersamaan. Tanpa pengaturan yang tepat, aplikasi dapat membuka terlalu banyak koneksi atau menghabiskan waktu menunggu koneksi tersedia.
Berikut beberapa manfaat database connection pooling Node.js:
- Mengurangi overhead koneksi: aplikasi tidak harus membuat koneksi baru untuk setiap query.
- Mengontrol koneksi aktif: developer dapat menentukan batas koneksi dalam pool.
- Membantu menangani permintaan bersamaan: koneksi dapat digunakan bergantian sesuai ketersediaan.
- Membantu menjaga stabilitas aplikasi: batas koneksi yang sesuai dapat mengurangi risiko database kelebihan koneksi.
- Mempermudah pengelolaan backend: konfigurasi koneksi dapat dipusatkan dalam satu modul.
Manfaat tersebut tetap bergantung pada implementasi dan konfigurasi. Connection pooling yang terlalu besar justru dapat membebani database jika jumlah koneksi dari seluruh instance aplikasi melampaui kapasitas server.
Cara Kerja Database Connection Pooling Node.js
Connection pooling bekerja melalui beberapa tahapan sederhana.
- Aplikasi membuat pool koneksi ketika proses server dimulai.
- Ketika permintaan masuk, aplikasi menggunakan koneksi yang tersedia.
- Database menjalankan query yang diminta.
- Setelah query selesai, koneksi dikembalikan ke pool untuk digunakan kembali.
- Jika seluruh koneksi sedang digunakan, permintaan berikutnya menunggu hingga tersedia koneksi.
Mekanisme tersebut membantu mengurangi pembentukan koneksi yang berulang. Akan tetapi, pool tetap memiliki batas. Jika antrean permintaan terlalu panjang, developer perlu memeriksa kapasitas database, waktu eksekusi query, dan konfigurasi pool.
Cara Menggunakan Database Connection Pooling Node.js dengan PostgreSQL
Salah satu cara menerapkan database connection pooling Node.js adalah menggunakan package pg untuk PostgreSQL.
1. Instal Package yang Dibutuhkan
Buat proyek Node.js baru, kemudian jalankan perintah berikut di terminal:
mkdir belajar-connection-pool
cd belajar-connection-pool
npm init -y
npm install pg dotenv
Package pg digunakan untuk menghubungkan aplikasi dengan PostgreSQL, sedangkan dotenv membantu membaca konfigurasi dari file .env.
2. Siapkan Konfigurasi Database
Buat file .env pada direktori utama proyek:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=belajar_db
DB_USER=postgres
DB_PASSWORD=password_database
Sesuaikan konfigurasi dengan database yang digunakan. Gunakan password yang aman untuk lingkungan produksi dan jangan mengunggah file .env ke repositori publik.
3. Buat Modul Connection Pool
Buat file database.js:
require("dotenv").config();
const { Pool } = require("pg");
const pool = new Pool({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
max: 10,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});
pool.on("error", (error) => {
console.error("Unexpected database pool error:", error);
});
module.exports = pool;
Pada contoh tersebut, max: 10 berarti pool dapat menggunakan maksimal sepuluh koneksi sekaligus. Nilai ini hanya contoh dan perlu disesuaikan dengan kapasitas database serta jumlah instance aplikasi.
Parameter idleTimeoutMillis mengatur batas waktu koneksi menganggur sebelum dapat ditutup. Sementara itu, connectionTimeoutMillis menentukan batas waktu menunggu pembentukan koneksi baru.
4. Gunakan Pool untuk Menjalankan Query
Buat file app.js:
const pool = require("./database");
async function getProducts() {
try {
const result = await pool.query(
"SELECT id, nama_produk, harga FROM produk"
);
console.log(result.rows);
} catch (error) {
console.error("Gagal mengambil produk:", error.message);
}
}
getProducts();
Contoh tersebut mengasumsikan tabel produk telah tersedia dan mempunyai kolom id, nama_produk, serta harga.
Jalankan program menggunakan perintah berikut:
node app.js
Jika koneksi dan struktur tabel sudah benar, aplikasi akan mengambil data dari PostgreSQL menggunakan pool.
Untuk query tunggal, pool.query() membantu menangani peminjaman dan pengembalian koneksi secara otomatis. Untuk transaksi yang terdiri dari beberapa query, gunakan client yang sama selama transaksi berlangsung dan pastikan client dilepaskan setelah selesai.
Untuk memahami pengelolaan koneksi lebih lanjut, developer dapat membaca dokumentasi resmi node-postgres tentang connection pooling, yang menjelaskan cara menggunakan kembali koneksi database pada aplikasi Node.js.
7 Tips Mengoptimalkan Database Connection Pooling Node.js
1. Gunakan Satu Pool untuk Setiap Modul Database
Hindari membuat pool baru setiap kali endpoint dipanggil. Buat pool dalam modul terpisah, lalu gunakan kembali modul tersebut di bagian aplikasi yang membutuhkan akses database.
Pendekatan ini membantu mencegah pembuatan pool berulang yang dapat meningkatkan jumlah koneksi secara tidak terkendali.
2. Sesuaikan Batas Koneksi
Jangan langsung menetapkan batas koneksi yang besar. Perhatikan kapasitas PostgreSQL, jumlah instance aplikasi, dan jumlah koneksi yang digunakan proses lain.
Sebagai gambaran, tiga instance aplikasi dengan pool maksimal sepuluh koneksi masing-masing berpotensi menggunakan hingga tiga puluh koneksi. Karena itu, konfigurasi harus dihitung berdasarkan keseluruhan sistem.
3. Hindari Query yang Terlalu Lama
Query yang lambat membuat koneksi tertahan lebih lama. Akibatnya, permintaan lain mungkin harus menunggu koneksi tersedia.
Periksa rencana eksekusi query, penggunaan indeks, dan jumlah data yang diambil. Gunakan EXPLAIN ANALYZE di PostgreSQL ketika diperlukan untuk menganalisis performa query dengan memahami bahwa perintah tersebut benar-benar menjalankan query.
4. Selalu Lepaskan Client Setelah Digunakan
Jika menggunakan pool.connect(), pastikan client dikembalikan melalui client.release() setelah pekerjaan selesai.
Gunakan blok finally agar client tetap dilepaskan meskipun query mengalami error. Kegagalan mengembalikan client dapat menyebabkan koneksi tertahan dan pool kehabisan koneksi yang tersedia.
5. Gunakan Parameterized Query
Hindari menyusun query dengan menggabungkan input pengguna secara langsung ke dalam string SQL. Gunakan parameter agar input diproses sebagai nilai, bukan sebagai bagian dari perintah SQL.
Contoh:
const result = await pool.query(
"SELECT * FROM produk WHERE id = $1",
[productId]
);
Parameterized query membantu mengurangi risiko SQL injection untuk nilai yang diparameterkan dengan benar.
6. Pantau Penggunaan Pool
Pantau jumlah koneksi aktif, koneksi yang sedang menganggur, antrean permintaan, serta waktu eksekusi query. Pada node-postgres, properti seperti pool.totalCount, pool.idleCount, dan pool.waitingCount dapat membantu mengamati kondisi pool.
Jika antrean terus meningkat, periksa apakah query terlalu lambat, kapasitas pool terlalu kecil, atau database sedang mengalami beban tinggi.
7. Tutup Pool Ketika Aplikasi Berhenti
Pada saat proses aplikasi benar-benar dihentikan, pool perlu ditutup dengan benar agar koneksi yang masih dikelola dapat dibersihkan.
Contohnya, pada aplikasi Node.js yang berjalan sebagai server:
async function shutdown() {
try {
await pool.end();
console.log("Database pool closed");
} catch (error) {
console.error("Failed to close database pool:", error);
process.exitCode = 1;
}
}
Contoh tersebut mengasumsikan variabel pool sudah tersedia dalam cakupan kode. Dalam aplikasi nyata, hubungkan fungsi shutdown dengan penanganan sinyal proses dan pastikan server berhenti menerima permintaan baru sebelum menutup pool.
Kesalahan yang Sering Terjadi Saat Menggunakan Connection Pooling
Beberapa masalah dapat muncul ketika connection pooling diterapkan tanpa pengujian yang memadai.
Pertama, pool dibuat berulang kali di setiap permintaan. Kedua, batas koneksi terlalu tinggi sehingga database menerima terlalu banyak koneksi. Ketiga, client yang dipinjam tidak dikembalikan ke pool. Keempat, query lambat menyebabkan koneksi tertahan dan antrean bertambah.
Kesalahan lain adalah menganggap connection pooling dapat menggantikan optimasi database. Padahal, penggunaan indeks yang sesuai, desain tabel yang baik, query efisien, dan pemantauan beban server tetap diperlukan.
Developer juga perlu memahami perbedaan query biasa dan transaksi. Transaksi harus menggunakan satu client yang sama dari awal hingga selesai agar setiap perintah dijalankan dalam konteks transaksi yang benar.
Kapan Database Connection Pooling Node.js Dibutuhkan?
Teknik ini layak digunakan ketika aplikasi menjalankan query database secara berulang, melayani banyak pengguna, atau mempunyai sejumlah endpoint yang membutuhkan data secara bersamaan.
Contohnya meliputi toko online, aplikasi kasir, sistem inventaris, layanan pemesanan tukang, dashboard administrasi, dan REST API untuk aplikasi mobile.
Untuk skrip sederhana yang hanya menjalankan satu query sesekali, pengelolaan koneksi yang lebih sederhana mungkin sudah cukup. Pilihan implementasi harus mengikuti kebutuhan nyata, bukan sekadar menambahkan teknologi yang lebih kompleks.
Kesimpulan
Database connection pooling Node.js membantu developer mengelola koneksi database secara lebih terstruktur dengan menggunakan kembali koneksi yang tersedia. Penerapan yang tepat dapat mengurangi overhead koneksi dan membantu aplikasi menangani permintaan secara lebih terkendali.
Untuk memperoleh manfaatnya, gunakan satu pool yang dikelola dengan baik, sesuaikan batas koneksi, optimalkan query, kembalikan client setelah digunakan, dan pantau kondisi database secara berkala.
Connection pooling bukan solusi tunggal untuk seluruh masalah performa. Namun, jika dikombinasikan dengan desain database yang baik dan pengujian beban yang sesuai, teknik ini dapat menjadi bagian penting dari backend Node.js yang lebih andal.