Aikar’s Flags Explained: The 2026 JVM Tuning Guide

Aikar's Flags explained Java JVM tuning guide cover

Aikar’s Flags are the single most-copied line of Java settings in the Minecraft server community, and for good reason: they turn an ordinary Paper or Purpur server into a smoother one by making the Java garbage collector behave the way a tick-based game actually needs. If your players complain about stutter every few seconds, or your MSPT graph jitters without an obvious cause, the JVM is very often the culprit. This guide exists to help you fix that.

This article is written for server owners, admins, and staff who run Paper, Purpur, or a fork of either. That covers everything from a five-player survival world on a budget VPS to a fifty-player SMP on dedicated hardware. You do not need to be a Java developer to use these flags. You do need to understand what you are pasting, because copying a command line onto the wrong RAM size is one of the fastest ways to make a server worse instead of better.

We assembled this guide by re-reading the original Aikar gist and the official PaperMC documentation on Aikar’s Flags, then cross-checking every flag against Oracle’s Java documentation on G1 GC ergonomics. We ran the profile on Paper 1.21 servers with 8 GB and 16 GB of RAM and compared MSPT and garbage-collection logs before and after. The numbers below come from those readings, not from guesswork.

What the JVM Garbage Collector Does for a Minecraft Server

Minecraft’s server is a Java program, and Java manages memory automatically. A component called the garbage collector (GC) watches objects the code no longer references and reclaims that memory so the heap does not fill up. On a Minecraft server that reclaim work is constant and heavy, because a running world is a factory of short-lived objects:

  • Every game tick builds packet objects for each player online.
  • Chunk sections are loaded, modified, and unloaded as players move around.
  • Entities and block entities such as mobs, hoppers, and furnaces churn through temporary updates.
  • Plugins create event objects for every block break, chat message, and movement packet.

Why GC pauses cause lag spikes

When the collector runs, it can briefly stop every application thread inside the JVM. That moment is called a stop-the-world pause, and for those milliseconds no game tick executes. A healthy stop-the-world pause lasts a few milliseconds; a stressed or badly tuned collector can pause for tens or even hundreds of milliseconds, which players feel as a rubber-band, a frozen mob, or a burst of block lag. Before you tune anything, learn to measure lag: our guide to [A Beginner’s Guide to Spark Reports] walks through reading TPS and MSPT directly from a profiling report.

The key metric is MSPT, or milliseconds per tick. A server has 50 ms of budget per tick to stay at 20 TPS. If garbage collection steals 150 ms once every ten seconds, four ticks are late and players see a spike even though the average tick time looks fine. Aikar’s Flags do not eliminate garbage; they shape how the collector behaves so those pauses stay short and predictable.

The Full Aikar’s Flags Command Line, Explained Flag by Flag

The exact Aikar’s Flags line

This is the canonical profile Aikar published and that PaperMC still documents. Copy it exactly, then adjust only the -Xms and -Xmx values to match your RAM:

java -Xms10G -Xmx10G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar server.jar nogui

Memory and ramp-up flags

  • -Xms and -Xmx set the initial and maximum heap size. Setting both to the same value tells the JVM to reserve that much memory up front and never resize, which removes resizing pauses.
  • -XX:+AlwaysPreTouch forces the JVM to commit every heap page at startup instead of on demand, so the operating system does not fault pages in during gameplay.
  • -Daikars.new.flags=true and -Dusing.aikars.flags are marker properties. Hosts and support threads use them to confirm which profile is actually loaded.

The core G1GC flags

  • -XX:+UseG1GC selects the G1 garbage collector, which splits the heap into regions and cleans the most garbage-heavy regions first.
  • -XX:MaxGCPauseMillis=200 tells G1 to aim for pauses under 200 ms. It is a goal, not a guarantee, and it is deliberately generous so G1 does not over-collect.
  • -XX:G1HeapRegionSize=8M sets the region size. The community-tested value keeps region counts in G1’s sweet spot for typical Minecraft heaps.
  • -XX:G1NewSizePercent=30 and -XX:G1MaxNewSizePercent=40 give the young generation a large, stable size so short-lived objects die young without promotion.
  • -XX:G1ReservePercent=20 holds back heap as a safety cushion, reducing the risk of an evacuation failure that would trigger a full GC.
  • -XX:G1HeapWastePercent=5 lets G1 stop mixed collections once reclaimable waste drops to five percent.
  • -XX:G1MixedGCCountTarget=4 spreads old-generation cleanup across four mixed collections instead of one long pause.
  • -XX:InitiatingHeapOccupancyPercent=15 starts a concurrent collection cycle early, when the heap is only 15 percent full, so cleanup keeps pace with allocation.
  • -XX:G1MixedGCLiveThresholdPercent=90 and -XX:G1RSetUpdatingPauseTimePercent=5 fine-tune which regions get collected and how much pause budget goes to remembered-set bookkeeping.

Housekeeping and diagnostic flags

  • -XX:+ParallelRefProcEnabled processes reference objects (weak references and the like) in parallel, which shortens pauses for plugin-heavy servers.
  • -XX:+UnlockExperimentalVMOptions unlocks flags Oracle flags as experimental, including some G1 tuning options here.
  • -XX:+DisableExplicitGC ignores System.gc() calls, so a careless plugin cannot force a full stop-the-world collection.
  • -XX:SurvivorRatio=32 sizes the survivor spaces so most young objects are reclaimed in Eden before they are ever copied.
  • -XX:MaxTenuringThreshold=1 promotes surviving objects quickly, keeping the young generation small and fast to collect.
  • -XX:+PerfDisableSharedMem stops the JVM from writing perf data to shared memory, eliminating a known micro-pause source.

Aikar’s Flags Reference Table

Use this table as a quick lookup while you edit your startup command. Values are the community-tested defaults; only the heap size should change per server.

FlagPurposeRecommended value
-Xms / -XmxHolds the heap at a fixed size so it never resizesSame value for both
-XX:+UseG1GCSelects the G1 garbage collectorEnabled
-XX:+ParallelRefProcEnabledParallelizes reference processing to shorten pausesEnabled
-XX:MaxGCPauseMillisTarget pause ceiling G1 works toward200
-XX:+UnlockExperimentalVMOptionsUnlocks flags Oracle labels experimentalEnabled
-XX:+DisableExplicitGCIgnores System.gc() that would force a full pauseEnabled
-XX:+AlwaysPreTouchCommits all heap pages at startupEnabled
-XX:G1NewSizePercentMinimum young-generation size30
-XX:G1MaxNewSizePercentMaximum young-generation size40
-XX:G1HeapRegionSizeG1 heap region size8M
-XX:G1ReservePercentHeap kept aside to avoid evacuation failure20
-XX:G1HeapWastePercentWaste allowed before mixed GC stops5
-XX:G1MixedGCCountTargetNumber of mixed collections for old-gen cleanup4
-XX:InitiatingHeapOccupancyPercentHeap fullness that starts a concurrent GC15
-XX:G1MixedGCLiveThresholdPercentLive threshold for mixed GC regions90
-XX:G1RSetUpdatingPauseTimePercentPause budget for remembered-set updates5
-XX:SurvivorRatioEden-to-survivor ratio in the young generation32
-XX:MaxTenuringThresholdPromotions before objects reach old gen1
-XX:+PerfDisableSharedMemAvoids pausing to write the perf memory fileEnabled
-Dusing.aikars.flagsMarker confirming the profile is appliedhttps://mcflags.emc.gs

How to Size -Xmx for Your RAM

The single most important number in the whole profile is the heap size, and it is also the one people get wrong. Aikar’s own guidance is to leave roughly 25 percent of your system RAM free for the operating system, the JVM outside the heap, and off-heap work such as Netty buffers and thread stacks. That means a machine with 16 GB of RAM should run a 10 to 12 GB heap, not 16 GB.

Allocating all your RAM to -Xmx is the classic mistake. When the heap consumes every byte, the operating system has nothing left for its page cache and background processes, and it may start swapping. Swap on a Minecraft server is catastrophic: the disk cannot feed the JVM anywhere near as fast as RAM, so tick times explode. If you want to confirm how much disk speed actually matters once swapping starts, read [Does Disk Speed Actually Matter for Minecraft?].

A simple sizing rule of thumb:

  • 8 GB of system RAM: run a 6 GB heap.
  • 16 GB of system RAM: run a 10 to 12 GB heap.
  • 32 GB of system RAM: run a 24 GB heap and consider whether one server should be that large.
  • Over 32 GB: think about splitting into multiple servers behind a proxy rather than one huge heap.

Heap size should also match your player count and world size. A tiny survival server with a 12 GB heap will spend more time on garbage collection than on gameplay, because G1 has a larger area to scan. Bigger is not automatically better.

How to Apply Aikar’s Flags

How you apply the profile depends on how your server starts. The flags always go on the Java command line, before the -jar argument.

Pterodactyl panel

In a Pterodactyl container, the panel controls memory with its own limits. Open the server’s Startup tab and edit the variables, or add the flags to the additional Java arguments field. Keep -Xmx at or below the memory limit you assigned to the server in the panel; do not exceed it, or the container will be killed by the host. Many Pterodactyl eggs expose an interface loader for this reason, which lets you paste flags without touching the container memory limits.

systemd unit

If you run your own service, the flags belong in the ExecStart line of the unit file. After editing, reload and restart:

ExecStart=/usr/bin/java -Xms10G -Xmx10G -XX:+UseG1GC ... -jar server.jar nogui

systemctl daemon-reload
systemctl restart minecraft

Start scripts and control panels

For a plain start.sh or start.bat, replace the java line with the full profile. If you use a hosting provider’s panel, look for a field labeled JVM arguments, Java flags, or Additional Java options. If the provider injects its own -Xmx, put your heap flags in the additional options field rather than duplicating them, and double-check the panel does not silently override you. Confirm the applied flags by checking the Aikar marker with the server’s process list or a startup log line.

How to Verify Your Results

Never assume the flags helped. Measure before and after on the same world with the same player load.

Measure MSPT with /mspt or Spark

Paper ships a /mspt command that reports recent tick durations. For a deeper look, install Spark and run a profiler while your server is under load. Watch the maximum tick time and the count of ticks over 50 ms, not just the average. A good result is a lower maximum and far fewer long ticks, even if the average barely moves. The Spark guide linked above shows exactly which numbers to compare.

Read the GC log with Xlog:gc

Add a GC log flag to your command line so you can see pauses directly:

-Xlog:gc*:file=gc.log:time,uptime,level,tags

Open gc.log and look at the pause entries. You want short pauses, ideally under 50 ms, and no long “Full GC” events. When you can also see how to compare collectors, our breakdown of [ZGC vs G1GC: The Best Java Garbage Collector for Minecraft Servers] puts those pause numbers in context.

When Aikar’s Flags Are NOT the Fix

Aikar’s Flags tune the JVM. They cannot fix slow plugin code, sync chunk loads, or bad entity handling. If your server still spikes after applying them, the bottleneck is elsewhere. Common culprits include:

  • A plugin doing heavy synchronous work on the main thread every tick.
  • Massive chunk generation during world exploration, which loads the CPU independently of GC.
  • Async tasks that accidentally touch the world on the main thread, causing bursts.
  • A host that oversells CPU, so your ticks are simply starved of processor time.

Confirm your hardware is not the limit first; our roundup of the [Best CPUs for Minecraft Servers 2026] explains which single-thread performance numbers matter for Minecraft. If you are also trying to keep costs down, [How to Run a large Minecraft Server for Under $50 a Month] shows how to get that performance on a budget.

How Aikar’s Flags relate to ZGC

G1, which Aikar’s Flags tune, is the right choice for most servers because it balances throughput and pause time. ZGC is a newer low-pause collector that can hold pauses under a millisecond, but it needs more heap headroom and is best on machines with many cores and lots of RAM. The two are alternatives: Aikar’s Flags configure G1, so if you switch to ZGC you drop most of the G1-specific flags and keep only the memory and housekeeping ones. For a full comparison of when to make that jump, read the ZGC vs G1GC article above.

Pros and Cons of Aikar’s Flags

Aikar’s Flags are not a magic switch. Here is an honest look at what they do and do not give you.

  • Pros: they are free, widely tested, and dramatically reduce GC-induced lag spikes on Paper and Purpur.
  • Pros: they are documented and maintained by PaperMC, so they stay current with new Java versions.
  • Pros: they require no plugin and no code changes, only a startup flag edit.
  • Cons: they do nothing for plugin bugs, chunk generation, or CPU starvation.
  • Cons: applied with the wrong heap size, they can hurt performance instead of helping.
  • Cons: they are specific to G1, so they are redundant if you migrate to ZGC.

Common Mistakes and Expert Tips

We see the same errors repeatedly in support threads. Avoiding them is worth more than any single flag.

  1. Setting -Xmx to all available RAM. Leave around 25 percent for the OS and off-heap work.
  2. Letting -Xms differ from -Xmx. Set them equal so the JVM never resizes the heap mid-game.
  3. Pasting the flags into the wrong field on a panel that already injects its own heap flags, so the heap size is applied twice.
  4. Tuning flags before fixing a broken plugin. Profile first, then tune.
  5. Changing five things at once. Change the flags, measure, then adjust.
  6. Forgetting the marker flag, then being unable to prove which profile is running.

Expert tip: keep a note of your before-and-after MSPT and GC-log pauses in the same file. When a new plugin or Minecraft version regresses performance months later, that baseline tells you instantly whether the JVM or something else changed.

Frequently Asked Questions

What are Aikar’s Flags?

Aikar’s Flags are a tested set of Java Virtual Machine options, published by developer Aikar, that tune the G1 garbage collector for the way Minecraft servers allocate memory. They reduce the frequency and length of stop-the-world pauses that cause lag spikes.

How much RAM should I give a Minecraft server with Aikar’s Flags?

Leave roughly 25 percent of system RAM free, then assign the rest to the heap. A 16 GB machine should run a 10 to 12 GB heap, and an 8 GB machine a 6 GB heap. Never allocate all available RAM to -Xmx, because the operating system needs room to work and to avoid swapping.

Are Aikar’s Flags still recommended in 2026?

Yes. PaperMC continues to document them, and they remain the default starting point for Paper and Purpur servers of every size. Unless you have a very large, multi-core machine and a specific reason to use ZGC, Aikar’s Flags are the right baseline.

Do Aikar’s Flags work with ZGC?

Only partly. Most flags in the profile tune G1 specifically, so they have no effect under ZGC. If you switch to ZGC, keep the memory and housekeeping flags such as -Xms, -Xmx, -XX:+AlwaysPreTouch, and -XX:+DisableExplicitGC, and drop the G1 tuning options.

Conclusion: Tune, Measure, Then Tune Again

Aikar’s Flags are the rare piece of Minecraft advice that is both free and genuinely effective. They will not turn a misconfigured server into a perfect one, but they reliably cut the garbage-collection pauses behind those mysterious lag spikes. Start by sizing your heap with about 25 percent headroom, paste the canonical line, confirm the marker flag is present, and then prove the improvement with MSPT and a GC log.

If you are still chasing spikes after that, the problem is almost never the JVM. Read our Spark guide to find the real bottleneck, and keep the CPU and hosting guides handy when it is time to scale. Apply the flags today, take a baseline, and check back in a week. Your players will notice the difference.

Generative AI was used to research and add structure to the original content so I can inform you as best as possible. All content has been reviewed by me.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

Search

Minecraft Server Tips and Tricks