Short answer
Use the G1 flags Paper publishes, set -Xms equal to -Xmx and leave 1000 to 1500 MB for the JVM and OS. That is the whole answer: a tuned collector with a heap that does not resize, sized below your RAM rather than equal to it.
JVM flags are where people copy the longest command lines and understand them least. For a Minecraft server the picture is unusually simple: the allocation pattern is known, a public flag set exists for exactly this workload, and the heap size is the only number that has to be arithmetic.
This guide is the short version of what matters, where the flags come from, and how to tell that the JVM is behaving. Anything beyond this is tuning for its own sake.
Before you start
- Control of the server start command, which panels and systemd units both give you
- Java 21 for current Minecraft versions
- A backup, because a bad flag set is a bad start
JVM flags and what each one does
| Flag | What it does | Why it matters here |
|---|---|---|
-Xms6G -Xmx6G | Initial and maximum heap | Equal values mean the heap never resizes during play |
-XX:+UseG1GC | Selects the G1 collector | Handles Minecraft's short-lived allocation pattern best |
-XX:+AlwaysPreTouch | Commits the heap at startup | The JVM stops faulting pages in while players are waiting |
-XX:MaxGCPauseMillis=200 | Target pause length | Tells G1 how long a collection may take |
-XX:+DisableExplicitGC | Blocks System.gc() | Stops plugins forcing collections mid-tick |
-XX:+PerfDisableSharedMem | Skips the hsperfdata file | Helps on hosts where shared memory is restricted |
-Xlog:gc*:logs/gc.log:time | GC logging | Shows whether the heap is healthy or leaking |
1. Size the heap first, because every other flag assumes it
-Xmx is the maximum memory the JVM may use and -Xms is what it starts with. Set them equal: the heap never has to resize during play, and resizing is one of the sources of pauses people call lag.
Set the value below your RAM, not equal to it. Paper's documentation is explicit that the JVM and the operating system need roughly 1000 to 1500 MB beyond -Xmx, so 8 GB of RAM should get -Xmx6G. A host that is willing to say it accounts for the overhead can give you more, which is worth asking.
8 GB RAM -> -Xms6G -Xmx6G
12 GB RAM -> -Xms10G -Xmx10G
16 GB RAM -> -Xms13G -Xmx13G2. Use the G1 flags Paper publishes, unchanged
The garbage collector is where most of the benefit is. Paper documents a set of G1 flags tuned for how Minecraft allocates: mostly short-lived objects, with a few long-lived ones such as loaded chunks. Copy that set from the Paper documentation and do not substitute flags from another project.
Two of them matter most. -XX:+UseG1GC selects the collector. -XX:+AlwaysPreTouch commits the whole heap at startup, so the JVM does not fault pages in while players are waiting. The rest tune the young and old generation sizes for this workload.
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 --noguijava -Xms4G -Xmx4G -XX:+UseG1GC -XX:+ParallelRefProcEnabled \
-XX:MaxGCPauseMillis=200 -XX:+AlwaysPreTouch \
-jar server.jar nogui3. Turn on GC logging so the heap is not a mystery
Garbage collection logging records every collection with timings. It is how you tell a normal server from a leak: a healthy server logs collections every few seconds with the heap falling back after each one, while a leaking server logs collections constantly with the heap near full and barely dropping.
Java 11 and later use one flag. Older versions need the older set. Either way the file goes where you can read it later, and neither costs performance.
-Xlog:gc*:logs/gc.log:time,uptime:filecount=5,filesize=1M-Xloggc:gc.log -verbose:gc -XX:+PrintGCDetails \
-XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps \
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=1M4. Restart and verify what the JVM is actually doing
Start the server and read the first lines. The JVM prints its version and the arguments it was given, which is the fastest way to catch a flag that did not make it into the command.
Then watch behaviour rather than theory: /tps during a normal session, and the GC log afterwards. If the collections are frequent but the heap returns to a low level each time, the server is fine. If it climbs towards -Xmx and stays there, something is holding memory, and the memory guide is the next step.
/tps
/msptGood to know
- Two flags are worth knowing because they change behaviour rather than performance.
-XX:+DisableExplicitGCstops plugins that callSystem.gc()from forcing collections mid-tick.-XX:+PerfDisableSharedMemavoids creating the hsperfdata file, which matters on hosts where shared memory is restricted. - Panic settings such as
-XX:+CrashOnOutOfMemoryErrorexist and are not defaults. Leave them off unless you are debugging a specific crash. - On a hosting panel you do not set these flags yourself; the platform sets the start command and the heap. Override it only if the panel documents how, because a manual heap can exceed what the platform accounts for and get the process killed.
- Running with systemd shows where these flags live in a service unit.
Common questions
What is the best JVM flag set for Minecraft?
The G1 flags Paper publishes, with -Xms equal to -Xmx and the heap set about 1000 to 1500 MB below your RAM. That is the set Paper's own start script uses, and it is what the documentation and script generator produce.
How much RAM should I give a Minecraft server?
Enough that -Xmx is below your total RAM and the GC log shows headroom. A small world runs in 2 to 4 GB; Paper's guidance is 6 to 10 GB whatever the player count. The RAM calculator sizes it for your setup.
Do JVM flags affect a vanilla server too?
The heap and collector flags do, and vanilla benefits from them in the same way. The G1 tuning set is documented for Paper because that is where it was developed; the flags are not Paper-specific, but the values were tested on it.
Why did my server crash after I added flags?
Usually the heap. If -Xmx exceeds the memory the host actually gives you, the kernel kills the process and the log has no exception. Check the heap against the host's number, restart, and read the JVM's startup line to confirm the arguments you expected are the arguments it got.
Sources
Official documentation this guide was checked against.
Rather not run this on your own machine? PufferHost gives every player a free Minecraft server with 3 GB of RAM and 10 slots. Create a free server.