# Optimasi Performa Event Loop Node.js untuk Skala Enterprise Jutaan RPS

> Diterbitkan oleh Literally Web ID pada 21 Oct 2026
> Sumber: https://literally.web.id/articles/optimasi-performa-event-loop-nodejs-untuk-skala-enterprise-jutaan-rps

---

Dalam 15 menit ke depan, kita akan merakit stack Node.js enterprise yang mampu melibas jutaan RPS tanpa tersendat di tengah jalan. Ingat kejadian pukul 3 pagi saat pagerduty berdering karena event loop lag melonjak hingga 4000ms? Ya, itu bukan salah Node.js-nya, melainkan karena kita membiarkan V8 Garbage Collector bekerja sendirian tanpa pengawasan, sementara ada proses berat yang menyumbat jalur utama. Mari kita bedah tuntas dan selesaikan masalah ini dari akarnya di dapur produksi kita.

## 1. Menu Kita Hari Ini & Alat yang Perlu Disiapkan
Sebelum kita menyalakan terminal, mari pastikan meja kerja kita bersih dari distraksi dan siap tempur. Hari ini kita tidak sedang membuat aplikasi CRUD sederhana untuk portofolio, melainkan merombak sistem backend berbeban masif.

Alat tempur yang wajib sudah terinstal di mesin Anda:
- Node.js versi LTS terbaru (v20.x atau lebih tinggi) dengan dukungan V8 modern.
- Clinic.js untuk melakukan profiling event loop secara visual dan akurat.
- ApacheBench (ab) atau autocannon untuk melakukan uji beban (load testing).
- Text editor kesayangan Anda (VS Code dengan ekstensi ESLint & Prettier).

> [!IMPORTANT]
> Pastikan Anda menjalankan eksperimen ini di environment Linux (Ubuntu 22.04 LTS direkomendasikan) dengan alokasi RAM minimal 4GB agar metrik V8 Garbage Collection terbaca secara presisi tanpa gangguan swap memory.

## 2. Peta Jalan Singkat: Apa yang Sedang Kita Rakit
Perjalanan kita kali ini dibagi menjadi tiga tahapan krusial:
1. Kita mulai dengan menyelami **Anatomi V8 Garbage Collection** untuk memahami bagaimana memori dialokasikan dan kapan jeda (pause) berbahaya terjadi.
2. Dilanjutkan dengan memindahkan beban komputasi berat ke **Worker Threads untuk Heavy Computation** agar jalur utama event loop tetap bersih dan responsif.
3. Terakhir, kita tutup dengan teknik **Profiling Menggunakan Clinic.js** untuk memvalidasi performa secara real-time.

Mari kita mulai langkah pertama dengan membongkar memori internal V8.

## 3. Langkah 1: Mempersiapkan Fondasi & Environment
Mari kita buat direktori kerja baru dan inisialisasi project Node.js kita. Buka terminal Anda dan ketikkan perintah berikut:

```bash
mkdir node-enterprise-perf
cd node-enterprise-perf
npm init -y
npm install clinic autocannon
```

Setelah dependensi terinstal, mari kita atur bendera (flags) V8 di level sistem operasi untuk mengontrol ukuran heap memory. Secara default, V8 membatasi heap sekitar 1.4GB hingga 2GB pada sistem 64-bit. Untuk server enterprise dengan RAM 32GB, angka ini sangat tidak efisien dan memicu GC (Garbage Collection) terlalu sering.

Buat file `.env` sederhana untuk konfigurasi environment kita:

```env
NODE_OPTIONS="--max-old-space-size=4096 --nointro" 
PORT=8080
```

> [!TIP]
> Jangan pernah menaikkan `--max-old-space-size` melebihi 75% dari total RAM fisik server Anda. Sisakan ruang untuk sistem operasi dan buffer jaringan Nginx di depannya.

## 4. Langkah 2: Meracik Konfigurasi Inti Tanpa Basa-basi
Sekarang kita masuk ke bagian inti: menulis kode server yang memisahkan antara I/O ringan dan proses berat menggunakan `worker_threads`.

Buat file `worker.js` untuk menangani komputasi berat (misalnya enkripsi atau manipulasi data masif):

```javascript
const { parentPort, workerData } = require('worker_threads');

// Simulasi komputasi berat CPU-bound
function heavyComputation(data) {
    let sum = 0;
    for (let i = 0; i < 1e9; i++) {
        sum += i;
    }
    return sum + data;
}

const result = heavyComputation(workerData);
parentPort.postMessage(result);
```

Sekarang, buat file `server.js` yang memanfaatkan worker di atas agar event loop tidak pernah terblokir:

```javascript
const http = require('http');
const { Worker } = require('worker_threads');

const server = http.createServer((req, res) => {
    if (req.url === '/compute') {
        const worker = new Worker('./worker.js', { workerData: 100 });
        
        worker.on('message', (result) => {
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ status: 'success', result }));
        });

        worker.on('error', (err) => {
            res.writeHead(500, { 'Content-Type': 'text/plain' });
            res.end('Internal Server Error');
        });
    } else {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('Fast path response!');
    });
});

server.listen(8080, () => {
    console.log('Enterprise server running on port 8080');
});
```

Jalankan server tersebut dengan perintah:

```bash
node server.js
```

Perhatikan bagaimana rute `/` merespons secara instan sementara `/compute` diproses secara asinkron di latar belakang tanpa mengganggu thread utama.

## 5. Langkah 3: Sentuhan Akhir Keamanan & Optimasi
Di lingkungan enterprise, kita tidak bisa hanya mengandalkan kode Node.js murni. Kita membutuhkan reverse proxy seperti Nginx di depan untuk menangani SSL termination, rate limiting, dan static caching sebelum request menyentuh event loop kita.

Buat file konfigurasi Nginx `/etc/nginx/sites-available/node_enterprise`:

```nginx
upstream node_cluster {
    server 127.0.0.1:8080;
    keepalive 64;
}

server {
    listen 80;
    server_name api.enterprise.internal;

    location / {
        proxy_pass http://node_cluster;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        
        # Buffer tuning untuk high throughput
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }
}
```

## 6. Tes Rasa: Memastikan Semuanya Berjalan Sempurna
Saatnya menguji racikan kita di dapur produksi lokal. Gunakan `autocannon` untuk mensimulasikan ribuan pengguna konkuren yang menghantam server kita.

Buka terminal terpisah dan jalankan perintah uji beban berikut:

```bash
npx autocannon -c 200 -d 30 http://localhost:8080/
```

Lihat hasilnya pada terminal Anda. Anda akan melihat angka *Requests/sec* yang menembus puluhan ribu dengan latensi rata-rata di bawah 5 milidetik. 

Untuk memvisualisasikan performa event loop, jalankan Clinic.js:

```bash
npx clinic doctor -- node server.js
```

Hantam server dengan `autocannon` selama proses profiling berjalan, lalu hentikan dengan `Ctrl+C`. Clinic.js akan merender laporan HTML interaktif yang menunjukkan apakah event loop Anda bersih dari blocking.

## 7. Pertolongan Pertama: Jika Terjadi Kendala Kecil
- **Kendala 1: Latensi tiba-tiba melonjak tinggi setiap beberapa menit.**
  *Solusi:* Ini adalah tanda klasik dari *Major Garbage Collection Pause*. Cek ukuran heap Anda dengan bendera `--trace-gc` untuk melihat berapa lama V8 membersihkan memori. Kurangi pembuatan objek temporer di dalam loop utama.
- **Kendala 2: Error `ERR_WORKER_OUT_OF_MEMORY`.**
  *Solusi:* Worker thread memiliki alokasi memori default yang terbatas. Berikan batasan data yang dikirim antar thread atau naikkan limit worker memory melalui opsi V8.

Dengan fondasi arsitektur ini, event loop Node.js Anda kini siap menghadapi badai trafik enterprise jutaan RPS tanpa keringat dingin. Selamat merilis ke production!