Apache NiFi JVM heap and garbage collection tuning

Set NiFi heap size and garbage collection in bootstrap.conf, understand what pressures the heap, and know when to tune CodeCache or capture a heap dump on OutOfMemoryError.

On this page

How Apache NiFi JVM heap tuning keeps flows stable under load

When a NiFi node slows down, stalls or throws memory errors under production load, the JVM heap and garbage collection settings are usually the first place to look. The heap holds FlowFile attributes, in-flight processor objects and queue metadata, and the garbage collector decides how often and how long the JVM pauses to reclaim that memory. A team needs to tune these settings when a node's heap runs close to its limit during normal traffic, when long collection pauses show up in the logs, or when a flow that worked in testing starts failing once real volumes arrive. NiFi runs as a JVM process, and the administration guide lists Java 21 as the minimum runtime, so confirm your installed Java version before changing any memory flags.

The heap is set in the bootstrap.conf file in the NiFi conf directory, where the java.arg entries control the initial and maximum heap size and the garbage collector arguments. Changes there apply on restart, and they should be made one node at a time in a cluster so the rest of the cluster keeps processing. Heap size is only one input. Large FlowAttribute values, big attribute maps on many FlowFiles and queues that grow past their thresholds all put pressure on the same memory, so heap changes that ignore flow design tend to move the failure rather than remove it. Treat the heap work as one part of a wider performance plan that also covers repositories, operating system limits and queue behavior, and record the baseline heap usage and GC activity before you change anything.

Before you change settings, collect the evidence: the heap usage and GC logs for the affected node, the queue sizes at the time of the slowdown, and the sizes of the largest attributes that flow through the slow processors. Ask your team or partner to confirm the GC logging options available for your Java build, and confirm how the administration guide describes the heap dump arguments for out-of-memory errors so you can capture a dump when a failure happens. Plan a test window, define what a stable node looks like in metrics, and change one setting at a time so you can tell which change helped.

Heap, garbage collection and CodeCache options in bootstrap.conf and when each fits

This table compares the bootstrap.conf JVM arguments the NiFi administration guide covers: heap sizing, the garbage collector, CodeCache and heap dump on OutOfMemoryError. Read each row as a decision: what the setting controls, when it fits and what to confirm against the guide for your installed version. The main takeaway is that heap size is only one of several JVM settings, and the others change how NiFi behaves under sustained load.

SettingWhat it controlsWhen it fitsWhat to confirm
Initial and maximum heap (-Xms, -Xmx)Memory the JVM reserves for FlowFile attributes, queues and processor objectsSet both to the same value on a dedicated host so the heap does not resize under loadCurrent argument lines and the default values shipped in your installed bootstrap.conf
Garbage collector selectionWhich collector runs and how it pauses application threadsUse the collector the guide documents for your Java 21 runtime, and change only after measuring GC pausesThe collector named in the guide for your version and any GC logging arguments it recommends
GC logging argumentsRecords collection events so pauses can be correlated with throughput dropsEnable during tuning or incident review so heap pressure can be traced to specific periodsLog file location, rotation and disk space on the repository volume
CodeCache sizingMemory for JIT-compiled code, which the guide links to sudden slowdowns under sustained, extremely high throughputConsider tuning when throughput is high for long periods and performance drops abruptly, not during normal burstsThe CodeCache arguments and thresholds the guide describes for your version, and whether they are needed at all
Heap dump on OutOfMemoryErrorWrites a heap dump file when the JVM cannot allocate memoryEnable on every production node so the evidence exists when an out-of-memory event happensDump directory, free disk space sized for a full heap dump and the handling of sensitive content in the dump
Large attributes and queuesConsume heap independently of the arguments above, regardless of how they are setKeep attribute values small and rely on swapping and back pressure to limit in-heap queue growthFlow design review of attribute sizes and connection thresholds before raising heap limits
Restart after changesWhether new arguments take effectApply changes in a maintenance window, one node at a time on a clusterNode disconnect and reconnect behavior in your cluster during the restart

How to set heap size and GC in bootstrap.conf step by step

This sequence changes NiFi's JVM heap and garbage collection settings in a controlled way, so each change is measured against a known baseline before it reaches the whole cluster.

  1. Record the current heap and GC baseline

    Before editing anything, the administrator captures how the node behaves today: heap usage over time, garbage collection frequency and pause length, and whether the node has logged out-of-memory errors. Use the node diagnostics available in the NiFi UI and the JVM garbage collection log, if enabled, on the node you plan to change. Note the current java.arg values in bootstrap.conf so you can roll back. The step is complete when you have a written baseline for one representative node and a copy of the original file.

  2. Edit the heap arguments in bootstrap.conf on one node

    On a single node, the administrator changes the initial and maximum heap sizes (-Xms and -Xmx) and any garbage collection arguments in bootstrap.conf, keeping changes small enough that a regression is easy to attribute. Avoid changing several unrelated settings at once. If you want a heap dump on an out-of-memory error, add the heap dump arguments documented in the administration guide at the same time, so you can reproduce a failure later. The step is complete when the diff against the saved copy shows only the intended lines.

  3. Restart the node and confirm the JVM flags

    Restart NiFi on the changed node only, and let it rejoin the cluster before you read anything. Confirm the flags took effect by checking the startup log for the JVM arguments it prints, or by reading the runtime values in the node diagnostics. If the flags are missing or the node fails to start, restore the saved bootstrap.conf and restart again. The step is complete when the logged or reported heap limits match what you wrote and the node shows as connected in the cluster view.

  4. Observe the node under representative load

    Let the node run the flows it normally carries, including the busiest period you know about, and watch the same measures you recorded at baseline: heap use after collections, GC frequency and pause time, and any out-of-memory or repeated full-collection events in the logs. Compare the results with the baseline rather than with an expectation. If the test traffic is not representative, say so in the change record, because a short quiet window can hide the problem. The step is complete when you have a comparison that shows whether the new settings helped, hurt or made no measurable difference.

  5. Check code cache under sustained throughput

    If the node sustains very high throughput, check whether the JVM code cache is filling and whether performance drops suddenly during peak periods. The administration guide notes that CodeCache settings may need tuning under this kind of load, so review it against your observed behavior rather than adjusting it preemptively. Record any code cache change as a separate step on the same test node so its effect is isolated. The step is complete when you can state either that code cache was not a limit under your load or what setting you changed and what you observed afterward.

  6. Roll the change across the cluster

    Apply the validated bootstrap.conf change to the remaining nodes one at a time, restarting each and waiting for it to reconnect before moving on. Keep the saved original file available for each node until the cluster has run through a full peak period. Confirm each node's startup flags with the same check used on the first node. The step is complete when every node reports the new heap settings, all nodes are connected, and the monitoring baseline has been re-measured across the cluster.

Which tuning path fits a standalone node, a cluster or sustained high throughput

A single development, test or low-volume NiFi node usually runs well on the heap size you set during installation. The goal on this path is to confirm that the default settings in bootstrap.conf match the machine and the data volume, and to avoid oversizing the heap in ways that leave too little memory for the operating system and the repositories. Tuning here is mostly a sizing check, not a performance project.

  • Match the heap to the host: Confirm that the -Xms and -Xmx arguments in bootstrap.conf leave memory for the operating system, the repositories' file caches and any other services on the same machine.
  • Keep minimum and maximum equal: Setting both to the same value avoids resizing pauses during early operation, which is a common choice for steady workloads.
  • Check the runtime version: Confirm the JVM is Java 21, the minimum runtime the administration guide lists.
  • Watch for pressure, not guesses: Only change heap settings after you see repeated out-of-memory errors, long garbage collection pauses or a steadily rising heap in logs.

Before you change anything, confirm the current heap settings, the Java version and the data rate you expect in production, and ask whether this node will ever carry production traffic.

Security and operational risks of heap dumps and JVM changes

Heap dumps and JVM argument changes both alter what NiFi holds in memory and who can see it. The cards below cover the data exposure, storage and change control, and post-change monitoring that should be decided before any heap or garbage collection setting reaches production.

Heap dumps hold live flow data

A heap dump is a snapshot of everything in the JVM at the moment of failure, so it can contain FlowFile attribute values, content held in memory and parameter values resolved during processing. Treat a dump as sensitive data in the same class as the flows it came from. Before enabling dumps through bootstrap.conf, confirm which sensitive parameters and attributes your flows carry and whether they can appear in memory.

Sensitive properties and credentials in memory

NiFi decrypts sensitive property values, such as passwords and keys held by controller services, so they exist in plaintext in the heap while components run. A dump taken during an out-of-memory event can expose them even though they are encrypted at rest. Check which controller services hold credentials, limit who can read dump files, and plan rotation for any secret that may have been captured.

Dump storage needs access controls

Heap dump files are large and are written to the path configured for the JVM, often on a shared or general-purpose volume. Restrict the directory to the NiFi service account, keep it off repository disks so a dump cannot fill the content or provenance volume, and place it on storage that your encryption and backup standards cover. Ask your security team which access logging applies to that path.

Retention limits for dump files

Dumps accumulate after repeated failures and are easy to forget. Define a retention period and an owner who deletes or archives dumps after analysis, and record when each dump was captured and which node produced it. Your data classification policy should decide whether dumps may leave the environment for vendor analysis, and whether that transfer needs approval.

JVM argument changes need change control

Heap size and garbage collection flags in bootstrap.conf change behavior on every node and usually need a rolling restart. Route each change through your normal change process with the previous values recorded, a documented restart order for the cluster, and a tested way to restore the earlier file. A change that looked safe in a test flow can behave differently under production throughput.

Monitor GC and memory after every change

A new setting can look correct at startup and still degrade under sustained load, so watch garbage collection frequency and pause time, heap occupancy after collections, and code cache usage for a full business cycle after each change. Compare results with the values recorded before the change. Set alerts that fire on rising post-collection heap use so that a slow leak is noticed before it becomes an out-of-memory event.

What teams ask before tuning NiFi heap and garbage collection

What drives the cost of NiFi heap and garbage collection tuning?

The main driver is how much analysis the heap needs, not the change itself. Setting the heap size in bootstrap.conf takes little time, but finding the right value depends on flow design, the number of FlowFiles in queues, how large your attributes are, and how many nodes you run. Costs come from two sources: your own engineers' time to collect data and test changes, and any outside help you buy under a fixed-scope written agreement. Ask any partner for the scope in writing, including which flows are reviewed, which heap dumps are analyzed and what test runs are included. DeployOpen does not publish prices, so a quote follows from that scope.

How long does heap and garbage collection tuning usually take?

Duration depends on how many environments, nodes and flows you have and how many tuning cycles the workload needs. A single node with a stable flow can often be adjusted in a few test runs, while a multi-node cluster with large queues needs longer observation under real load. Plan time for collecting garbage collection logs, changing one setting at a time, and repeating the test under peak conditions. Any specific duration should come from the written scope and from your own test environment, not from a general rule.

What does our team need to provide for this work?

You need access to the NiFi hosts, the bootstrap.conf file, the NiFi application logs and garbage collection logs, and a test environment that can reproduce your load. You also need someone who knows the flows well enough to explain which processors handle large attributes or large batches. Give the team the current NiFi version, the Java runtime in use and a record of recent out-of-memory events. Without representative load, heap settings tuned on a quiet test system may not hold in production.

Can our own engineers tune the NiFi heap without an outside partner?

Yes, many teams can change heap settings and read garbage collection logs with their own staff. The work is manageable when the flow design is stable, the team can reproduce load in a test system and someone can read heap dumps. Outside help is more useful when problems come from flow design, such as oversized attributes or queues that grow without limit, because those need changes to the flows as well as the JVM. Decide early who owns production changes and who signs off on them.

How do we recognize a heap problem in NiFi?

Common signs include repeated OutOfMemoryError entries in the application log, long garbage collection pauses, throughput that drops over time without a matching change in data volume, and nodes that become unresponsive under load. Check whether heap use rises between collections and does not fall back. Also check whether queues are large and whether attributes on FlowFiles are unusually big, since both can consume heap. Configure NiFi to write a heap dump on out-of-memory errors, as the Administrator's Guide describes, so you have evidence for analysis.

Could a CodeCache problem look like a heap problem?

Yes, the symptoms can overlap. The Administrator's Guide notes that under sustained, extremely high throughput the JVM CodeCache settings may need tuning to avoid sudden performance loss. A sudden drop in throughput under steady load, without heap exhaustion, can point to CodeCache rather than the heap. Compare the garbage collection logs and JVM metrics against the throughput history before changing any setting, so you change the right value.

When should we bring in outside help for NiFi heap tuning?

Bring in outside help when out-of-memory errors recur after you have changed the heap, when the cause is unclear from logs, or when the fix depends on flow redesign. It also helps when a production cluster is at risk and your team lacks time for controlled testing. DeployOpen plans, implements, tunes, documents and supports self-hosted open-source platforms inside your own infrastructure. Ask for a written scope that names the environments, the flows reviewed, the heap dump analysis, the test runs and the handover material before work starts.

What tuning the heap changes for your flows and your team

A larger heap is not a free fix for a slow or unstable NiFi node. Every gigabyte assigned to the JVM in bootstrap.conf is memory the operating system cannot use for the page cache, and NiFi's repositories depend heavily on that cache. The FlowFile, content and provenance repositories read and write large volumes of data, and when the host starts swapping or evicting cached pages, throughput can fall even though the heap looks healthy. The practical decision is how much memory the node has after the OS, the repositories and any co-located agents are accounted for, and whether the heap you want still leaves room for those. Ask your platform team to confirm the memory budget per node before anyone raises -Xmx, and record the reasoning next to the change.

Heap settings and flow design have to be reviewed together, because most heap pressure starts in the flow. Large attribute values, FlowFiles that carry big payloads in attributes rather than content, and connections that queue far past their back pressure thresholds all keep objects alive on the heap. A heap increase can hide these patterns for a while and then fail later at a higher volume. Assign one owner for flow design and one for JVM settings, and require that anyone who adds a processor pattern that buffers data, or raises a queue threshold, states the expected heap impact. Garbage collection behavior should be checked against the same flows after each change, not in isolation.

The upgrade path changes the baseline your team tunes against. NiFi 2 requires Java 21 as the minimum runtime, according to the NiFi administrator's guide, so any heap or garbage collection options carried over from a 1.x bootstrap.conf need to be checked against the new runtime before go-live. Flags that were valid on an older Java release can be removed or behave differently, and the upgrade is a good moment to re-measure rather than copy old values forward. Plan the Java upgrade, the NiFi upgrade and the JVM retune as one change with a rollback point, and confirm the exact supported JVM options in the NiFi System Administrator's Guide for the release you deploy.

How DeployOpen scopes and delivers NiFi JVM tuning

DeployOpen approaches Apache NiFi JVM heap and garbage collection tuning as a written, fixed-scope change to your running NiFi, starting from how your flows actually use memory. We plan, build, test, document and hand over the settings in the infrastructure you control, and we can support them afterward under a retainer.

How we scope

  • We review node sizes, current bootstrap.conf arguments, flow designs and queue and attribute patterns before proposing any heap value.
  • The written scope names the NiFi nodes, JVM versions, garbage collector choice and the load profiles that the tuning must cover.
  • We agree on the test evidence, such as GC logs and heap dump handling, that will count as acceptance before work starts.

How we build

  • We change heap, garbage collector and CodeCache arguments in bootstrap.conf in a staged order, one node or environment at a time.
  • We test under representative load, including sustained high throughput, and record garbage collection behavior against the agreed baseline.
  • We configure heap dump capture on OutOfMemoryError and confirm that dumps land on storage with enough space and access controls.

How we hand over

  • We deliver a runbook that explains each setting, the reason for its value and the signals that should trigger a review.
  • We walk your operations team through reading GC logs, interpreting heap dumps and rolling a configuration change across the cluster.
  • We provide a change record with before and after measurements so your team can audit the decision later.

How we support

  • Ongoing support is available as a retainer, covering re-tuning after flow changes, NiFi version upgrades or new node hardware.
  • We can review the effects of new large attributes or queue growth on heap use and recommend flow changes alongside JVM changes.
  • Continuous testing is available as a retainer, so heap and garbage collection settings are checked again as your workload grows.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.