Episode ini membedah konfigurasi stream secara lengkap: subjects, retention dengan mode Limits, Interest, dan WorkQueue, storage file atau memory, max_age dan max_bytes, replikasi, serta stream sourcing, mirroring, dan dedupe window untuk exactly-once publish.

Episode 7 memberi kalian kenalan pertama dengan JetStream. Episode 8 ini masuk lebih dalam: bagaimana mengkonfigurasi stream dengan presisi. Di sinilah keputusan arsitektural diambil — berapa lama pesan disimpan, bagaimana pesan dihapus, apakah disimpan di file atau memory, dan berapa banyak salinan yang dimiliki.
Pilihan yang salah di episode ini bisa berujung pada kehilangan data atau pemborosan disk di produksi. Mari kita bedah setiap bagian konfigurasi stream, lalu lanjut ke sourcing, mirroring, dan dedupe window.
Setiap stream harus punya nama dan daftar subject yang ditangkap. Sebuah stream bisa menangkap banyak subject sekaligus memakai wildcard:
nats stream add ORDERS --subjects "orders.>" --subjects "payments.charged"Perintah nats stream add ORDERS --subjects "orders.>" membuat stream ORDERS yang menyimpan semua pesan di bawah orders.> dan payments.charged. Satu subject hanya bisa ditangkap oleh satu stream dalam satu akun — NATS menolak jika ada tumpang tindih antar stream.
Untuk menghindari mode interaktif, semua opsi bisa dilewatkan sekaligus:
nats stream add ORDERS \
--subjects "orders.>" \
--retention limits \
--storage file \
--max-age 30d \
--max-bytes 1G \
--replicas 3Skema --max-age 30d menunjukkan pesan bertahan maksimal 30 hari, --max-bytes 1G membatasi total ukuran, dan --replicas 3 menjaga tiga salinan. Ketiga keputusan ini adalah inti dari manajemen siklus hidup data.
Limits adalah mode default: pesan disimpan sampai melampaui batas usia atau ukuran, lalu dihapus paling lama. Ini cocok untuk event log dengan horizon waktu tertentu, misalnya menyimpan event pesanan selama 30 hari.
Interest menyimpan pesan selama masih ada consumer yang tertarik membacanya. Ketika semua consumer sudah memproses pesan dan tidak ada yang menunggu, pesan dihapus. Cocok untuk workload di mana pesan tidak perlu disimpan setelah diproses semua pihak.
WorkQueue dirancang untuk job queue: setiap pesan hanya boleh dibaca oleh satu consumer. Begitu pesan diack, ia langsung dihapus dari stream. Tidak ada replay, tidak ada broadcast.
| Mode | Pesan dihapus ketika | Penggunaan umum |
|---|---|---|
| Limits | Melampaui batas usia/ukuran | Event log berdurasi |
| Interest | Semua consumer selesai membaca | Event untuk banyak service |
| WorkQueue | Satu consumer mengack | Job queue |
Pola WorkQueue ini adalah dasar dari work queue yang akan kita bangun secara penuh di episode 11.
Opsi storage menentukan media penyimpanan:
nats stream add CACHE --subjects "cache.>" --storage memory --retention limitsnats stream add CACHE --subjects "cache.>" --storage memory cocok untuk data sementara seperti cache. Untuk semua data yang tidak boleh hilang, selalu pilih storage file.
Dua batasan paling umum:
subjects: ["orders.>"]
retention: limits
storage: file
max_age: 7d
max_bytes: 2GiB
max_msgs: 1000000
discard: oldBlok max_age: 7d menghapus pesan yang lebih tua dari 7 hari, dan discard: old menentukan bahwa saat penuh, pesan terlama dihapus dulu. Kombinasi batas ini mencegah disk terisi tanpa batas.
Warning
Tentukan max_bytes sejak awal. Stream tanpa batas ukuran akan terus tumbuh sampai memenuhi disk dan membuat server crash. nats stream report bisa menunjukkan stream mana yang sudah mendekati batas.
Field replicas menentukan berapa salinan stream yang disimpan di server berbeda dalam satu cluster. Nilai 1 untuk single-node, 3 untuk cluster yang toleran kehilangan satu node, 5 untuk toleran dua node.
nats stream edit ORDERS --replicas 3Perintah nats stream edit ORDERS --replicas 3 mengubah jumlah salinan stream yang sudah ada. Setiap salinan disinkronkan lewat konsensus Raft — topik yang akan kita bahas di episode 14. Aturan praktis: replicas harus selalu lebih kecil dari jumlah node cluster.
Sourcing memungkinkan sebuah stream menarik pesan dari subject yang sumbernya justru berasal dari stream lain:
nats stream add ORDERS_ANALYTICS --subjects "analytics.>" --sources ORDERS--sources ORDERS membuat ORDERS_ANALYTICS menyalin setiap pesan yang masuk ke stream ORDERS. Ini pola populer untuk membentuk data mart: stream utama tetap bersih, stream turunan dibuat untuk keperluan analytics tanpa mengganggu alur utama.
Mirroring menyalin seluruh isi sebuah stream dari stream lain — biasanya di cluster atau region yang berbeda — untuk keperluan disaster recovery:
name: ORDERS_DR
mirror:
name: ORDERS
external:
api: nats://dr-cluster:4222Blok mirror di atas membuat stream ORDERS_DR mencerminkan stream ORDERS yang berada di cluster disaster recovery. Ini adalah fondasi strategi DR lintas region yang akan kita bangun di episode 21.
JetStream menyediakan dedupe window: setiap publisher bisa menyertakan header Nats-Msg-Id. Jika pesan dengan ID yang sama masuk lagi dalam jendela waktu dedupe, pesan ganda ditolak. Ini langkah pertama menuju exactly-once publish.
nats pub orders.created "pesanan-1" --id order-2026-08-10-001nats pub orders.created "pesanan-1" --id order-2026-08-10-001 memberi identitas unik pada pesan. Jika client kehilangan ack lalu mengirim ulang pesan dengan ID yang sama, JetStream mendeteksi duplikat dan mengembalikan ack tanpa menyimpan pesan kedua kali.
Jendela default dedupe adalah 2 menit, bisa disesuaikan pada stream:
nats stream edit ORDERS --dedupe-window 5m--dedupe-window 5m memperpanjang jendela menjadi 5 menit. Dedupe hanya menjamin publish tidak ganda; untuk pemrosesan yang idempotent, kalian masih perlu mekanisme tambahan yang akan dibahas di episode 11.
Episode 8 membekali kalian kendali penuh atas stream: mendefinisikan subjects, memilih retention Limits, Interest, atau WorkQueue, menentukan storage file atau memory, membatasi max_age dan max_bytes, mengatur replikasi, serta memahami sourcing, mirroring, dan dedupe window untuk exactly-once publish.
Inti yang harus dibawa pulang:
max_bytes wajib ditentukan agar disk tidak penuh.replicas menentukan jumlah salinan; harus lebih kecil dari jumlah node.Nats-Msg-Id mencegah publish ganda.Di episode 9 selanjutnya kita akan membahas JetStream consumers — perbedaan pull dan push consumer, durable versus ephemeral, semantik ack, nack, ackWait, dan max delivery untuk redelivery, serta deliver_policy dan replay untuk menentukan dari mana consumer mulai membaca. Di sinilah cara membaca stream diatur presisi.