Best JVM Flags for Minecraft Servers 2026
Aikar's JVM flags explained line by line, plus ZGC for high-memory servers, Forge/Fabric tuning, and how to apply flags in Pterodactyl and other panels.
What JVM Flags Actually Do
Minecraft runs on the Java Virtual Machine. When you launch a server JAR, the JVM handles memory allocation, garbage collection, just-in-time compilation, and thread management. JVM flags are command-line arguments that control how the JVM performs these tasks. The right flags can reduce lag spikes caused by garbage collection, improve memory throughput, and prevent out-of-memory crashes. The wrong flags, or no flags at all, can cause periodic freezes that show up as TPS drops even when your server is otherwise well-configured.
Most hosting panels give you a startup command line where you can paste these flags. If you are managing your own VPS or dedicated machine, they go into your start script. Either way, the format is the same: java [flags] -jar server.jar.
Aikar's Flags: The Standard for Paper Servers
Aikar's flags have been the community standard for Paper-based servers since 2018, and they remain the best general-purpose option in 2026. These flags configure the G1 garbage collector to behave well with Minecraft's memory access patterns. Here is the full set for a server with 10GB of 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: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
Breaking down each flag
-Xms10G -Xmx10G
These set the minimum and maximum heap size. Aikar's recommendation is to set them equal. When Xms and Xmx differ, the JVM starts with the lower amount and gradually requests more from the OS as needed. Each expansion triggers a full GC pause. By locking them to the same value, you eliminate that entire class of stutter. The JVM allocates the full heap at startup, which is what -XX:+AlwaysPreTouch ensures actually happens in physical memory rather than just virtual address space.
Choose a value that matches your hosting plan. For a breakdown of how much RAM you actually need, see the RAM calculator guide.
-XX:+UseG1GC
Selects the G1 (Garbage First) garbage collector. G1 divides the heap into regions and collects the regions with the most garbage first, which keeps pause times short. It has been the best general-purpose GC for Minecraft servers for years because it balances throughput and pause time well at heap sizes between 4GB and 12GB.
-XX:MaxGCPauseMillis=200
Tells G1 to aim for garbage collection pauses under 200 milliseconds. This is a target, not a guarantee. G1 will adjust its collection strategy to try to meet this target. The value of 200ms means G1 will not sacrifice too much throughput chasing impossibly short pauses, but will still keep pauses shorter than a noticeable lag spike.
-XX:G1NewSizePercent=30 and -XX:G1MaxNewSizePercent=40
These control how much of the heap is reserved for the young generation, where new objects are allocated. Minecraft allocates a lot of short-lived objects every tick (item stacks, position vectors, temporary collections). By giving the young generation 30-40% of the heap instead of the default ~5-10%, young generation collections happen less frequently, which means fewer pauses overall.
-XX:G1HeapRegionSize=8M
Sets the size of each G1 region to 8MB. Larger regions mean fewer regions to manage, which reduces bookkeeping overhead. For Minecraft's allocation patterns, 8MB is the sweet spot.
-XX:G1ReservePercent=20
Reserves 20% of the heap as free space to reduce the risk of a "to-space exhaustion" failure, which causes a very long stop-the-world pause. The default is 10%, which can be tight for Minecraft.
-XX:InitiatingHeapOccupancyPercent=15
Starts a concurrent GC cycle when the heap is 15% full. This sounds aggressive, but it gives G1 plenty of time to reclaim memory before the heap fills up. Starting too late forces emergency collections with much longer pauses.
-XX:MaxTenuringThreshold=1
Objects that survive one young generation collection get promoted to the old generation immediately. In Minecraft, objects are either very short-lived (one tick) or very long-lived (chunk data, entity data). There is very little in between, so letting objects sit in survivor spaces for multiple cycles wastes memory and time.
-XX:SurvivorRatio=32
Makes survivor spaces very small relative to eden space. This works together with MaxTenuringThreshold=1. Since objects are promoted after a single collection anyway, large survivor spaces are wasted memory.
-XX:+ParallelRefProcEnabled
Processes reference objects (weak, soft, phantom references) in parallel during GC. Minecraft and its plugins use a fair number of these, so parallelizing their processing speeds up GC pauses.
-XX:+DisableExplicitGC
Prevents plugins from triggering garbage collection by calling System.gc(). Some poorly written plugins call this, which forces a stop-the-world pause at an unpredictable time. Disabling it ensures only the GC algorithm decides when to collect.
-XX:+PerfDisableSharedMem
Disables the JVM's performance monitoring shared memory file. This prevents a rare issue where the JVM pauses to flush this file to disk. The downside is that tools like jstat will not work, but you should be using Spark for monitoring anyway.
ZGC for High-Memory Servers (16GB+)
If your server has 16GB or more of RAM, ZGC is worth considering as an alternative to G1. ZGC is designed for low-latency applications and keeps GC pauses under 1 millisecond regardless of heap size. The trade-off is that ZGC uses roughly 10-15% more CPU and about 3-5% more memory overhead than G1.
java -Xms16G -Xmx16G -XX:+UseZGC -XX:+ZGenerational -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+PerfDisableSharedMem -jar server.jar --nogui
ZGC became production-ready in Java 17 and received the generational mode (-XX:+ZGenerational) in Java 21. If your server runs Java 21 (which Paper recommends), generational ZGC is the best option for large heaps. It virtually eliminates GC-related lag spikes, which means your TPS stays at 20 even during memory-intensive operations like world generation.
Flags for Forge and Fabric Modded Servers
Modded servers have different memory access patterns than Paper servers. Heavy modpacks like All the Mods or RLCraft allocate more objects with medium lifetimes (tile entity data, mod caches, custom world gen), which changes the optimal GC configuration.
For Forge/NeoForge servers with 8GB or more, use Aikar's flags but increase the young generation percentage:
java -Xms8G -Xmx8G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=15 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=20 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -jar server.jar --nogui
The key differences: G1NewSizePercent bumped to 40-50%, G1HeapRegionSize increased to 16MB, and InitiatingHeapOccupancyPercent raised to 20%. Modded servers generate more garbage per tick due to custom rendering pipelines and extra tile entity processing, so they benefit from a larger young generation.
Applying Flags in Pterodactyl and Other Panels
On Pterodactyl (used by Astroworld Hosting and many others), the startup command is configured per-server in the Startup tab. You will see a field for JVM flags or a full startup command. Paste everything before -jar into the flags field. The panel handles -Xms and -Xmx automatically based on your plan's memory allocation, so you may need to remove those from your paste and use the panel's memory field instead.
On Multicraft panels, look for the "Java Settings" or "Custom JAR arguments" field. On AMP, edit the JVM arguments in the instance configuration. If you run a VPS with a start script, just edit the start.sh file directly.
Common Mistakes
- Setting Xmx higher than your available RAM. If your VPS has 8GB total and you set Xmx to 8G, the operating system and other processes have no memory left. Leave at least 1-2GB for the OS. On a 8GB plan, set Xmx to 6-7G.
- Using different Xms and Xmx values. As explained above, this causes heap resizing pauses. Always keep them equal.
- Mixing G1 flags with ZGC. G1-specific flags like
G1NewSizePercentare ignored or cause errors with ZGC. If you switch collectors, start with a clean set of flags. - Not updating flags for new Java versions. Some flags are deprecated or removed across Java versions. If you upgrade from Java 17 to 21, check that all your flags are still valid by looking for warnings in the server startup log.
- Over-allocating RAM. More RAM does not always mean better performance. Beyond what your server actually needs, extra heap just means longer GC cycles. Check the RAM calculator to find the right amount.
Need a server that handles all this? Astroworld Hosting runs NVMe SSD, Pterodactyl panel, and DDoS protection on every plan. See all features , plans start at €6.39/mo.