Back to Blog
jvm flagsaikar's flagsserver startuplaunch scriptminecraft optimizationjava arguments

Minecraft Server Startup Optimization: JVM Flags, Aikar's Flags, and Launch Scripts Explained

Published on July 12, 2026

# Minecraft Server Startup Optimization: JVM Flags, Aikar's Flags, and Launch Scripts Explained

Most Minecraft server admins focus on config files and plugins when fighting lag — but they completely overlook one of the most impactful optimizations of all: how the server is started. The JVM flags you pass at launch directly control how Java manages memory, compiles code, and handles garbage collection. Getting these wrong means lag spikes, slow startup times, and wasted RAM — even on powerful hardware.

This guide covers everything you need to know about writing the perfect Minecraft server launch script.

---

Why JVM Flags Matter So Much

Minecraft runs on the Java Virtual Machine (JVM). The JVM is responsible for:

  • Allocating and managing RAM (heap memory)
  • Running the garbage collector (GC) to free unused objects
  • Just-in-time (JIT) compiling Java bytecode into native machine code

Without tuning, Java uses generic defaults that are designed for desktop apps — not a continuously-running, latency-sensitive game server. The result: long GC pauses, slow class loading, and unstable TPS.

---

Aikar's Flags: The Gold Standard for Minecraft Servers

[Aikar's flags](https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/) are a well-known set of JVM arguments specifically tuned for Minecraft. They configure the G1GC garbage collector to minimize pause times and handle Minecraft's particular memory allocation patterns.

Here is the full recommended launch command for servers with 12GB or more RAM:

java -Xms12G -Xmx12G \

-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

For servers with less than 12GB, reduce -XX:G1HeapRegionSize to 4M and -XX:G1NewSizePercent to 20.

Key Flags Explained

| Flag | What It Does |

|---|---|

| -Xms / -Xmx | Sets minimum and maximum heap size. Always set them equal to prevent heap resizing pauses. |

| -XX:+UseG1GC | Enables the G1 garbage collector, optimized for low pause times. |

| -XX:MaxGCPauseMillis=200 | Hints to GC to target pauses under 200ms. |

| -XX:+AlwaysPreTouch | Pre-allocates all RAM at startup, preventing gradual slowdown as memory is first accessed. |

| -XX:+DisableExplicitGC | Prevents plugins from calling System.gc() and triggering full GC pauses. |

| -XX:InitiatingHeapOccupancyPercent=15 | Starts GC cycles earlier, before memory pressure builds up. |

| -XX:+PerfDisableSharedMem | Prevents the JVM from writing perf data to disk, which can cause random I/O stalls. |

---

Java Version: Which Should You Use?

Always run Minecraft 1.21+ with Java 21 (LTS). Java 21 includes major improvements to the G1GC and introduces virtual threads, which Paper and Folia can leverage for better async task handling.

Do not use Java 8 in 2024. It is missing years of GC improvements and security patches.

To check your Java version:

java -version

Install Java 21 on Ubuntu/Debian:

apt install openjdk-21-jdk-headless

---

ZGC: Is It Better Than G1GC?

For servers with very large heaps (32GB+) or those running on Java 21, ZGC is worth experimenting with. ZGC is a nearly pause-free garbage collector that handles large heaps extremely well.

To switch to ZGC, replace the GC-related flags with:

-XX:+UseZGC -XX:+ZGenerational

-XX:+ZGenerational is a Java 21 feature that makes ZGC generational, significantly improving throughput on typical Minecraft workloads.

Caveat: ZGC uses more CPU than G1GC. On low-core machines, stick with G1GC.

---

Writing a Proper Start Script

A bare java -jar server.jar is not enough. Here is a production-quality start.sh script:

#!/bin/bash

MEM="10G"

JAR="paper-1.21.jar"

java -Xms$MEM -Xmx$MEM \

-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 \

-jar $JAR --nogui

Make it executable with chmod +x start.sh and run it inside a screen or tmux session so it persists after you log out.

---

Common Mistakes to Avoid

  • Setting -Xmx higher than available RAM. This causes the OS to swap to disk, which is catastrophically slow. Leave at least 1-2GB free for the OS.
  • Using -Xms lower than -Xmx. This causes the JVM to gradually resize the heap, introducing pauses.
  • Not using --nogui. The Swing GUI wastes CPU and RAM on headless servers.
  • Running multiple servers on the same JVM. Each server should have its own process.
  • Forgetting to update flags after upgrading Java. Some flags are version-specific.

---

Monitoring the Impact

After applying new JVM flags, you should verify they're actually helping. Watch for:

  • Reduced GC pause frequency and duration (visible in server logs with -Xlog:gc*)
  • Stable TPS without lag spikes every few minutes
  • Lower and more consistent memory usage over time

[PulseNode](https://pulsenode.tech) automatically tracks your server's TPS, memory usage, and performance trends over time, making it easy to see whether your JVM tuning is having the intended effect — without digging through raw logs.

---

Quick Reference: Flags Cheat Sheet

| Server RAM | Recommended GC | G1HeapRegionSize | G1NewSizePercent |

|---|---|---|---|

| 4-8 GB | G1GC | 4M | 20 |

| 8-16 GB | G1GC | 8M | 30 |

| 16-32 GB | G1GC | 16M | 30 |

| 32 GB+ | ZGC (Java 21) | N/A | N/A |

---

Final Thoughts

Your launch script is the foundation everything else runs on. Incorrect JVM flags can undo every other optimization you make — no matter how well-tuned your paper-world.yml or spigot.yml are. Spend 10 minutes getting this right, and your server will run smoother from the very first tick.

Start with Aikar's flags, match your heap size to your available RAM, and upgrade to Java 21 if you haven't already. Then monitor the results — because optimization without measurement is just guessing.

---

*Want to keep an eye on how your server performs after applying these changes? [PulseNode](https://pulsenode.tech) gives you real-time TPS monitoring and historical performance data so you can see exactly what's working.*

Optimize your server performance?

PulseNode monitors your Minecraft server in real-time and gives you AI-powered optimization tips.

Start for free
Minecraft Server Startup Optimization: JVM Flags, Aikar's Flags, and Launch Scripts Explained — PulseNode Blog | PulseNode