Optimalkan performa n8n: memecah workflow besar menjadi sub-workflow yang reusable, menerapkan batch processing dan concurrency, mengatur resource serta runtime node, sampai meningkatkan throughput dengan queue mode dan worker scaling.

Di episode 15 kalian men-deploy n8n secara produksi dengan Docker Compose, Kubernetes, dan queue mode. Sekarang instance-nya sehat — tapi workflow mulai terasa lambat. Satu workflow "laporan raksasa" memproses ribuan baris dalam satu kali jalan, beberapa workflow memuat logika yang sama, dan eksekusi saling berebut CPU di main.
Episode 16 membahas Performance Optimization: memecah workflow besar menjadi sub-workflow yang bisa dipakai ulang, menerapkan batch processing dan concurrency, serta mengoptimalkan execution runtime dan throughput.
Aturan pertama optimasi: jangan menebak. Sebelum mengubah apa pun, lihat data yang sudah kalian kumpulkan dari episode 13:
Optimasi yang tidak berbasis pengukuran biasanya memperbaiki hal yang salah. Ukur, temukan bottleneck, perbaiki, lalu ukur lagi.
Workflow yang menumpuk semua logika dalam satu kanvas sulit dipahami dan sulit dijalankan cepat. Solusinya adalah memecahnya menjadi sub-workflow yang dijalankan lewat node Execute Sub-workflow. Setiap sub-workflow punya satu tanggung jawab — normalisasi data, panggilan API, formatting laporan — dan bisa dipanggil dari banyak workflow induk.
Perbedaan performa terbesar ada pada mode eksekusinya:
Run once for each item -> sub-workflow dieksekusi N kali
Run once for all items -> sub-workflow dieksekusi 1 kali, N item sekaligusMemilih "each item" untuk 5.000 item berarti menjalankan sub-workflow 5.000 kali — setiap kali dengan overhead load, credential, dan sambungan. Pilih "all items" ketika sub-workflow memproses data secara batch, dan gunakan mode per item hanya bila setiap item memang butuh konteks eksekusi terpisah. Sub-workflow yang reusable juga membuat perbaikan menyebar: ubah sekali, semua workflow induk ikut membaik. Saat dijalankan dalam queue mode, sub-workflow yang di-fan-out dari satu trigger bahkan bisa dieksekusi paralel di beberapa worker sekaligus.
Aturan pemecahan yang mudah diingat: bila sebuah blok node muncul di lebih dari dua workflow, atau sebuah workflow mulai sulit dibaca karena terlalu panjang, saat itulah blok itu layak dipindahkan ke sub-workflow.
Ketika workflow harus memproses ribuan baris, memproses satu per satu terlalu lambat; memproses semuanya sekaligus bisa membuat memori jebol. Jalan tengahnya adalah batch processing dengan node SplitInBatches — data dipecah menjadi kelompok berukuran tetap, lalu tiap batch diproses dalam iterasi loop:
Input 10.000 item
-> SplitInBatches (batchSize: 500)
-> Loop node (proses batch)
-> jika masih ada sisa, ulangi dari awalUkuran batch adalah kompromi: terlalu kecil berarti banyak iterasi dan overhead per siklus; terlalu besar berarti lonjakan memori per batch. Mulai dari beberapa ratus item per batch, lalu sesuaikan berdasarkan beban API tujuan dan batas memori instance. Pola ini sekaligus melindungi service eksternal dari ledakan request — terutama penting saat berintegrasi dengan API pihak ketiga yang membatasi rate.
Satu kesalahan yang sering terjadi: menaruh SplitInBatches di dalam alur yang sudah berjalan per item, sehingga batch tidak pernah terpakai. SplitInBatches bekerja paling baik di titik awal pipeline — pecahkan sejak awal, dan biarkan setiap iterasi mengolah satu batch dari awal sampai akhir.
Selain struktur workflow, tuning lingkungan menentukan berapa banyak eksekusi yang bisa berjalan bersamaan. Di main, batasnya dikendalikan variabel lingkungan:
N8N_CONCURRENCY_PRODUCTION_LIMIT=10
N8N_CONCURRENCY_POLLING_LIMIT=5Nilai -1 berarti tanpa batas (default). Mengatur batas yang masuk akal mencegah satu pekerjaan berat membanjiri instance. Di queue mode, concurrency berlaku per worker — kelola lewat flag --concurrency pada n8n worker atau N8N_CONCURRENCY_PRODUCTION_LIMIT di environment worker, sebagaimana dibahas di episode 15.
Resource Node.js juga bisa diatur. Heap memory dibatasi nilai default yang mungkin terlalu kecil untuk workflow dengan banyak data:
NODE_OPTIONS=--max-old-space-size=2048Sesuaikan dengan memori fisik yang dialokasikan ke container, dan seimbangkan dengan batas CPU pada compose/values Helm agar proses tidak di-throttle.
Info
Untuk Code node yang berat, perhatikan eksekusi di task runners: n8n versi terbaru menjalankan kode di proses terpisah sehingga workload JavaScript tidak membebani event loop utama. Pastikan memori yang dialokasikan cukup, karena kode sekarang berjalan di luar proses n8n itu sendiri.
Waktu eksekusi paling sering hilang di panggilan jaringan. Pola pemborosan yang umum:
Loop jika logikanya murni transformasi.Convert to File atau pengiriman, buang kolom yang tidak terpakai dengan Set atau Remove Duplicates untuk memangkas payload antar node.Pemangkasan data juga berlaku pada database: kebijakan prune dari episode 13 (EXECUTIONS_DATA_PRUNE dan EXECUTIONS_DATA_MAX_AGE) menjaga tabel eksekusi tidak membengkak, sehingga query riwayat tetap cepat. Runtime yang sehat dimulai dari data yang tidak menganggur di mana-mana.
Pola yang juga patut diperhatikan adalah trigger yang terlalu rajin. Cron yang berjalan setiap menit untuk memeriksa data yang berubah tiap jam membuang banyak slot eksekusi — perbesar interval, atau manfaatkan trigger polling yang menyertakan kondisi berhenti lebih awal (misalnya langsung berhenti ketika tidak ada data baru). Eksekusi yang tidak pernah dimulai adalah eksekusi yang paling cepat.
Ketika satu proses tidak lagi sanggup mengeksekusi semua workload, throughput dinaikkan secara horizontal. Queue mode dari episode 15 memindahkan eksekusi ke worker: main hanya menyalurkan job ke Redis, dan sekumpulan worker mengonsumsinya. Tambah throughput dengan menambah replica worker — bukan dengan memperbesar satu instance.
Beberapa knob yang menyesuaikan perilaku:
OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true — eksekusi manual dari editor juga dialihkan ke worker, menjaga main tetap ringan untuk UI.Throughput bukan hanya soal menambah worker, tetapi memastikan setiap worker mengerjakan job yang tepat dengan data yang sudah dipangkas — kombinasi struktur workflow dari bab-bab sebelumnya dengan scaling dari episode 15.
Episode 16 menuntun kalian dari workflow yang lambat menjadi sistem yang terukur. Kalian mengukur dulu sebelum mengoptimasi, memecah workflow raksasa menjadi sub-workflow reusable, menerapkan batch processing dengan SplitInBatches, mengatur concurrency dan resource Node.js, memangkas pemborosan runtime, dan menaikkan throughput lewat queue mode dan worker scaling.
Inti yang harus dibawa pulang:
SplitInBatches menyeimbangkan kecepatan dan konsumsi memori untuk data besar.N8N_CONCURRENCY_PRODUCTION_LIMIT dan flag worker.Di episode 17 berikutnya kita memperluas n8n melampaui node bawaan: Extensions & Custom Nodes — membuat custom node dan mengemasnya sendiri, memakai community nodes, serta plugin development untuk automation yang lebih kaya. Sampai jumpa!