Aikar's Flags Explained: Do You Need Them, and How to Check

ZCraft Studios

What Aikar's JVM flags actually change, the exact flags to use, how much RAM to give them, and how to measure whether they helped, because most lag is not caused by garbage collection.

Aikar's Flags Explained: Do You Need Them, and How to Check

Aikar's flags are one of the most copied pieces of Minecraft server advice, and one of the most misunderstood. They tune Java's garbage collector. They do not fix lag caused by too many entities, a heavy plugin, or a huge view distance, and those are the usual causes. So before you paste anything into your start script, find out whether garbage collection is your problem.

Measure first

A Minecraft server has 50 milliseconds per tick to stay at 20 TPS. If a tick takes longer, the server falls behind and players feel it. Start by looking at how long ticks actually take:

/mspt
/spark tps
/spark healthreport

/mspt is built into Paper. spark is a profiler plugin, and some server jars already bundle it. If your average MSPT sits well under 50, the flags aren't going to make a visible difference. If it spikes past 50 in regular bursts and the health report shows long GC pauses at the same moments, you have a garbage collection problem and these flags are worth trying. If MSPT is high all the time with short GC pauses, the load is real work, and the answer is in a spark profile, not in JVM flags.

What the flags do

Minecraft creates a huge number of small, short-lived objects every tick. Java's default G1 collector settings are tuned for something more general. Aikar's flags reshape G1 for that pattern. The ones that carry most of the weight:

  • -Xms equal to -Xmx. The heap starts at full size, so Java never spends time resizing it while players are online.
  • -XX:+AlwaysPreTouch. Allocates and touches all the heap memory at startup. Startup is slower and the memory is committed immediately, but it avoids page faults mid-game.
  • -XX:MaxGCPauseMillis=200. The pause time G1 aims for. It's a target, not a guarantee.
  • -XX:G1NewSizePercent=30 and -XX:G1MaxNewSizePercent=40. A larger young generation, because most Minecraft objects die young. Collecting dead objects there is cheap.
  • -XX:G1HeapRegionSize=8M. Larger regions suit the large allocations the server makes.
  • -XX:InitiatingHeapOccupancyPercent=15. Starts concurrent collection early, so it doesn't fall behind and force a long pause.
  • -XX:MaxTenuringThreshold=1. Objects that survive one collection are promoted quickly, rather than being copied around several times.
  • -XX:+DisableExplicitGC. Stops code from triggering a full collection by calling System.gc().

The flags

For heaps up to about 12 GB:

java -Xms6G -Xmx6G -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 paper.jar --nogui

For heaps above 12 GB, the published guidance changes a handful of values: G1NewSizePercent=40, G1MaxNewSizePercent=50, G1HeapRegionSize=16M, G1ReservePercent=15 and InitiatingHeapOccupancyPercent=20. The rest stays the same. Check the current set at mcflags.emc.gs, since flag recommendations get revised.

How much RAM

Java uses memory beyond the heap: class metadata, thread stacks and native buffers. If you give the heap the entire amount your host allows, the process can get killed for exceeding its limit. Leave roughly 10 to 20 percent of the allocation free. On a 4 GB plan, set -Xmx around 3 to 3.5 GB.

More heap is not automatically better either. A server that uses 3 GB steadily gains nothing from an 8 GB heap, and you're paying for memory that sits idle. Look at your actual usage in the spark health report before buying more.

Did it help? Check properly

Change one thing at a time, and compare on similar load. Two checks:

  • Run /spark healthreport before and after, during a busy period, and compare the GC section and MSPT.
  • Turn on GC logging and read the pauses directly:
-Xlog:gc*:logs/gc.log:time,uptime:filecount=5,filesize=1M

You are looking for fewer pauses over about 100 ms, and no pauses long enough to show up as a lag spike. If the log looks the same as before, the flags weren't your bottleneck, and you've learned that for free.

What usually matters more

  • Lower view-distance and simulation-distance in server.properties. This is the cheapest big win.
  • Pre-generate the world with the Chunky plugin, so players aren't generating new terrain as they explore.
  • Count your entities. Mob farms, item drops and villagers cost far more than most plugins.
  • Profile with spark (/spark profiler start, let it run during the lag, then /spark profiler stop) to see which plugin or system is eating the tick.

On a managed host, you usually set flags in the startup settings, and some hosts already apply a tuned set. Ask support before overriding it.

Aikar's flags are a good default for any server with more than a couple of players. Just don't treat them as the fix for lag until the numbers say so.

Share: