Performa RabbitMQ bisa ditingkatkan dari banyak sisi. Di episode ini kalian mengoptimalkan publisher dengan batching dan async confirms, menyetel prefetch dan paralelisme consumer, memilih tipe queue dan lazy mode yang tepat, serta melakukan tuning level sistem seperti Erlang VM dan file descriptors.

Broker yang sama bisa terasa sangat berbeda tergantung cara kalian menggunakannya. Sebuah aplikasi yang mem-publish satu pesan per koneksi baru, dan aplikasi lain yang memakai channel bersama dengan batching, bisa berbeda sepuluh kali lipat throughput-nya. Di episode ini kita menuntaskan sisi performa.
Optimasi performa RabbitMQ bisa dipecah menjadi empat lapisan: publisher, consumer, queue, dan sistem. Masing-masing punya tuas yang bisa diputar — dan hampir selalu, optimasi paling berdampak ada di sisi aplikasi, bukan di konfigurasi broker.
Ingat aturan utamanya: ukur dulu, optimalkan kemudian. Jangan menebak-nebak; pakai alat seperti PerfTest (episode 30) untuk mendapatkan baseline sebelum dan sesudah setiap perubahan.
Publisher yang mem-publish satu pesan lalu menunggu konfirmasi per pesan sangat lambat. Batching — mengumpulkan beberapa pesan sebelum mengirim — mengurangi jumlah round-trip secara drastis. Kombinasikan dengan async confirms: kirim batch, lalu proses konfirmasi dalam callback.
channel.confirm_delivery()
for i in range(1000):
channel.basic_publish(exchange="", routing_key="bulk", body=f"m{i}".encode())
# tunggu semua confirm selesai
connection.process_data_events()Pola di atas mem-publish 1000 pesan dalam satu gelombang, dan confirms ditangani asinkron oleh broker — jauh lebih cepat daripada menunggu satu per satu.
Koneksi TCP itu mahal; channel itu murah. Reuse connection selama mungkin, dan jangan buat koneksi baru per pesan. Untuk throughput tinggi, gunakan beberapa channel sejalan dengan thread worker.
Satu pola yang sering keliru: membuat connection baru di dalam loop publish. Setiap koneksi butuh handshake TCP, pertukaran AMQP capability, dan alokasi proses Erlang di broker. Jika aplikasi mem-publish 1000 pesan dengan 1000 koneksi baru, performanya bisa puluhan kali lebih lambat daripada satu koneksi dengan 1000 publish berurutan. Selalu buat koneksi di awal aplikasi dan bagi channel-nya.
prefetch_count yang terlalu kecil membuat consumer menganggur menunggu pesan; terlalu besar membuat satu consumer menimbun pesan. Ukur dan sesuaikan. Juga tambahkan paralelisme: beberapa worker consumer per channel atau beberapa channel sekaligus meningkatkan utilisasi CPU.
Satu pola yang efektif: gunakan pool worker di sisi consumer — satu channel menerima pesan, lalu mendistribusikannya ke beberapa goroutine atau thread untuk diproses paralel. Kombinasi prefetch yang cukup besar dengan worker pool sering kali menaikkan utilisasi CPU tanpa harus menambah koneksi baru.
auto_ack memberi throughput tertinggi karena broker tidak menunggu konfirmasi, tapi berisiko kehilangan pesan saat consumer crash. manual ack lebih aman dengan overhead kecil. Trade-off ini adalah keputusan bisnis: berapa nilai data yang diproses dibandingkan biaya kehilangan.
Jika kalian tetap memilih auto-ack untuk kecepatan, sediakan kompensasi: arahkan pesan yang gagal ke dead letter exchange (episode 11), atau pastikan consumer idempotent sehingga pemrosesan ulang setelah crash tidak merusak data. Dengan begitu kecepatan tetap didapat tanpa kehilangan jejak error.
Pilihan tipe queue sangat menentukan performa: classic untuk single-node sederhana, quorum untuk keandalan, stream untuk throughput replay. Untuk queue yang cenderung menumpuk besar, pertimbangkan lazy mode yang menulis pesan ke disk lebih awal:
rabbitmqadmin declare queue name=big_queue \
arguments='{"x-queue-type":"classic","x-queue-mode":"lazy"}'x-queue-mode=lazy membuat pesan langsung ditulis ke disk, mengurangi risiko memori penuh untuk antrean yang panjang. Detail lengkap lazy queue ada di episode 23.
Pasang x-max-length agar queue tidak tumbuh tak terkendali, dan kecilkan ukuran pesan: hindari menyimpan data besar di body, kompresi payload (episode 9), dan gunakan referensi object storage untuk file.
Atur high watermark memori agar broker mengingatkan lebih awal:
vm_memory_high_watermark.relative = 0.7
disk_free_limit.relative = 1.5vm_memory_high_watermark 0.7 berarti alarm memori mulai pada 70 persen penggunaan — menyisakan ruang aman sebelum crash.
tcp_bufsize) untuk link berlatensi tinggi.Untuk memeriksa apakah file descriptor menjadi bottleneck, bandingkan jumlah file descriptor yang sedang dipakai dengan batasnya:
rabbitmqctl status | grep -A 4 -i "file descriptors"Jika angka yang dipakai mendekati batas, naikkan ulimit sistem dengan mengedit /etc/security/limits.conf lalu restart service. Ingat: file descriptor yang habis membuat koneksi baru ditolak — dan gejalanya sering membingungkan karena tidak terlihat seperti error broker.
Pada mesin dengan banyak core dan arsitektur NUMA, alokasi scheduler Erlang bisa dioptimalkan dengan mengatur affinity CPU. Konfigurasi ini jarang diperlukan untuk mesin kecil, tetapi di node dengan banyak core dan beban tinggi, penyesuaian +sbwt dan +sbwtdcpu di argumen VM Erlang bisa mengurangi cache miss dan kontensi scheduler. Lakukan hanya setelah pengukuran menunjukkan scheduler sebagai bottleneck, bukan berdasarkan tebakan.
Optimasi sering menghadapkan kalian pada pilihan latency vs throughput. Batching, misalnya, menaikkan throughput tetapi menambah sedikit latency karena pesan ditahan menunggu batch penuh. Sebaliknya, publish satu-satu meminimalkan latency tetapi throughput-nya rendah. Mana yang diutamakan bergantung pada bisnis: sistem trading mengejar latency, sementara pipeline data mengejar throughput. Tulis target angka di awal — misalnya "5000 publish per detik dengan p95 latency di bawah 20 ms" — lalu ukur terhadap target itu.
Karena banyak variabel saling memengaruhi, mengubah banyak konfigurasi sekaligus membuat hasil pengukuran tidak bisa diatribusikan. Lakukan satu perubahan, ukur, catat, lalu lanjut ke perubahan berikutnya. Simpan baseline sebelum mulai, dan pertahankan environment pengukuran yang stabil — menjalankan benchmark di laptop dengan aplikasi lain terbuka akan menghasilkan angka yang menyesatkan.
Tip
Jangan lupa membandingkan: lakukan satu perubahan pada satu waktu, ukur ulang, lalu lanjutkan. Mengubah banyak variabel sekaligus membuat kalian tidak tahu mana yang berdampak.
Di episode 22 ini kalian sudah mengoptimalkan publisher dengan batching dan async confirms, menyetel prefetch dan paralelisme consumer, memilih tipe queue dan lazy mode, serta melakukan tuning level sistem untuk Erlang VM, file descriptors, disk, dan network.
Inti yang harus dibawa pulang:
Di episode 23 selanjutnya kita akan mengelola memory dan resource management — alarm memori dan disk, strategi perhitungan memori, paging pesan ke disk, lazy queues, limit connection, channel, dan queue per vhost, serta pengelolaan log dan kompaksi message store. Ini pertahanan broker terhadap resource yang menipis!