Belajar NATS - JetStream Performance
Series/Belajar NATS/Episode 16
Episode 16 of 23

Belajar NATS - JetStream Performance

Episode ini membahas performa JetStream: high-throughput publish versi 2.14+, batching untuk publish massal, server-side message scheduling, scaling dengan replikasi dan partisi antar subject, tuning storage, dan benchmark menuju jutaan pesan per detik.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

NATS dikenal sebagai messaging tercepat, tapi kecepatan tanpa teknik yang benar tetap sia-sia. Episode 16 ini membuka kotak alat performansi JetStream: bagaimana mempublish jutaan pesan per detik tanpa membebani server, dan bagaimana mendesain stream agar tetap cepat seiring pertumbuhan data.

Kita akan membahas high-throughput publish versi 2.14+, batching, server-side message scheduling, scaling lewat replikasi dan partisi, tuning storage, dan benchmark nyata.

High-Throughput Publish

Apa yang Baru di 2.14+

Sejak NATS Server 2.14, publish ke JetStream memiliki jalur first-class high-throughput: pesan di-buffer di server dan ditulis ke disk secara berkelompok, bukan satu per satu. Ini menghilangkan bottleneck fsync pada setiap pesan.

Server dengan konfigurasi performa
nats-server -c nats.conf --jetstream --store_dir /data/js

Perintah nats-server --jetstream --store_dir /data/js memakai penyimpanan di disk SSD yang cepat. Untuk high-throughput, pastikan direktori store berada di disk lokal yang cepat, bukan network storage.

Memanfaatkan Publish Async

Di sisi client, gunakan publish asynchronous dengan flush berkala:

Publish async di Go
nc, _ := nats.Connect("nats://localhost:4222")
js, _ := nc.JetStream()
 
for i := 0; i < 100000; i++ {
    js.PublishAsync("orders.created", []byte("data"))
}
select {
case <-js.PublishAsyncComplete():
case <-time.After(30 * time.Second):
}

js.PublishAsync("orders.created", []byte("data")) mengirim tanpa menunggu ack per pesan, dan js.PublishAsyncComplete() menunggu semua terkirim. Publish async memungkinkan ribuan pesan dalam satu pipa tanpa round-trip per pesan.

Batching: Menggabungkan Banyak Publish

Batch per Sesi

Batching mengurangi overhead jaringan dengan mengirim banyak pesan sekaligus:

PythonBatch publish dengan nats-py
async with await js.publish_batch([
    js.create_msg("orders.created", b"pesan-1"),
    js.create_msg("orders.created", b"pesan-2"),
    js.create_msg("orders.created", b"pesan-3"),
]) as batch:
    await batch.wait_for_all(timeout=30)

js.publish_batch([...]) mengirim banyak pesan sebagai satu operasi. Untuk pipeline data, batching meningkatkan throughput drastis dibandingkan publish satu per satu.

Aturan Praktis Batching

  • Batch ukuran 100-1000 pesan memberi keseimbangan terbaik.
  • Jangan buat batch yang terlalu besar hingga melewati batas pesan maksimal.
  • Selalu tangani error batch: jika satu gagal, ketahui pesan mana yang hilang.

Server-Side Message Scheduling

Alur Pengiriman yang Diatur Server

Versi 2.14 menambahkan server-side message scheduling: server mengatur kapan consumer menerima pesan, sehingga banyak consumer bisa berbagi satu stream tanpa saling berebut bandwidth.

Consumer dengan flow control
nats consumer add ORDERS PROCESSOR --push --flow-control --ack explicit

Flag --flow-control mengaktifkan kontrol aliran dari sisi server. Server memperlambat pengiriman saat consumer tidak mampu mengejar, mencegah overload yang menyebabkan pending menumpuk.

Info

Flow control dan heartbeat bekerja sama: server mengirim heartbeat untuk memastikan koneksi hidup, dan menunda pesan jika consumer sudah penuh. Aktifkan keduanya untuk push consumer di produksi.

Scaling JetStream

Replikasi dan Partisi

Untuk throughput lebih tinggi, bagilah beban:

  • Replikasi menambah salinan untuk ketahanan, bukan throughput.
  • Partisi antar subject: pecah satu subject besar menjadi beberapa stream ber-tenant.
Stream terpisah per region
nats stream add ORDERS_EU --subjects "orders.eu.>"
nats stream add ORDERS_ASIA --subjects "orders.asia.>"

Perintah nats stream add ORDERS_EU --subjects "orders.eu.>" mempartisi data per region. Setiap stream dikelola dan diskalakan sendiri — arsitektur ini disebut sharding berbasis subject.

Tuning Storage

Beberapa tuning yang berdampak besar:

  • SSD NVMe untuk store_dir jauh lebih cepat daripada HDD.
  • Pilih storage file untuk durability, memory untuk kecepatan maksimal.
  • Sesuaikan max_age dan max_bytes agar stream tidak membesar tak terkendali.
Stream dengan tuning penyimpanan
storage: file
max_age: 7d
max_bytes: 4GiB
replicas: 3
compression: true

Blok compression: true mengaktifkan kompresi pesan untuk menghemat disk. Kombinasi batasan dan kompresi menjaga performa tulis tetap stabil.

Benchmark Nyata

Mengukur Throughput

NATS menyediakan alat benchmark nats bench:

Benchmark publish/subscribe
nats bench --pub 10 --sub 10 --size 256 --msgs 1000000 benchmark.subject

Perintah nats bench --pub 10 --sub 10 --size 256 menjalankan 10 publisher dan 10 subscriber mengirim 1 juta pesan berukuran 256 byte. Output menampilkan pesan per detik dan latensi. NATS sering menunjukkan jutaan pesan per detik dalam benchmark semacam ini — tergantung hardware dan konfigurasi.

Membaca Hasil Benchmark

Contoh hasil benchmark
publish: 2,400,000 msg/sec
deliver: 2,350,000 msg/sec
latency: p50 1.2ms, p99 3.8ms

Hasil publish: 2,400,000 msg/sec di atas menunjukkan throughput jutaan pesan per detik dengan latensi milidetik. Ingat: benchmark adalah panduan, bukan janji — selalu uji dengan pola workload nyata kalian.

Penutup

Episode 16 mengoptimalkan JetStream: high-throughput publish versi 2.14 dengan buffer server-side, publish async dan batching di client, server-side message scheduling dengan flow control, scaling lewat partisi antar subject dan tuning storage, serta benchmark untuk mengukur kemampuan nyata.

Inti yang harus dibawa pulang:

  • High-throughput publish 2.14+ menulis pesan ke disk secara berkelompok.
  • Publish async dan batch meningkatkan throughput tanpa round-trip per pesan.
  • Flow control membuat server menyesuaikan kecepatan pengiriman.
  • Replikasi untuk ketahanan; partisi antar subject untuk throughput.
  • SSD, batasan ukuran, dan kompresi menjaga performa tulis stabil.
  • nats bench mengukur throughput dan latensi sebagai panduan.

Di episode 17 selanjutnya kita akan membahas NATS di Kubernetes — deploy dengan Helm chart dan nats-operator, StatefulSet untuk JetStream dengan persistence via PVC, lalu integrasi KEDA NATS JetStream scaler untuk autoscaling event-driven, Argo workflows, dan service mesh. NATS kalian siap naik ke cloud-native.

Belajar NATS - JetStream Performance | Belajar NATS