Stop Copy-Pasting JVM Arguments for Your Fabric Server

Walk into any Minecraft server hosting Discord and you will find someone asking about JVM arguments. Within minutes, three different people will post walls of parameters that look like they were generated by a random number generator attached to the Java documentation. Half of these arguments are for Java versions from 2015, a quarter of them are experimental flags that might crash your server, and the rest are cargo cult optimizations that someone’s cousin’s friend swears improved their FPS.

This is not about whether JVM arguments are useful. Some of them absolutely are. This is about the epidemic of people copy-pasting parameter salad without understanding what any of it does.

The Arguments That Actually Matter

Let’s start with what you should actually be using, because there are legitimate improvements to be made here.

For Java 8: -Xms4096M -Xmx4096M -XX:+UseG1GC

For Java 11-20: -Xms4096M -Xmx4096M -XX:+UseZGC

For Java 21+: -Xms4096M -Xmx4096M -XX:+UseZGC -XX:+ZGenerational

(Note that ZGenerational is becoming the default in newer versions, but being explicit doesn’t hurt.)

Setting -Xms and -Xmx to the same value prevents the JVM from having to expand the heap during runtime, which eliminates allocation pauses. If you have 8GB of RAM, giving your server 4GB is reasonable. Adjust accordingly for your hardware.

The garbage collector choice matters. G1GC is a solid improvement over the default collectors in Java 8. ZGC is even better for newer versions, especially ZGenerational which handles the generational hypothesis much more efficiently.

The Arguments That Are Snake Oil

Everything else in those copy-pasted parameter lists is probably making your server worse.

-XX:+UnlockExperimentalVMOptions followed by a dozen experimental flags is not optimization, it’s playing Russian roulette with your server stability. I have seen people enable flags that were literally removed in later Java versions because they were found to be harmful.

Micro-tuning garbage collection parameters like -XX:MaxGCPauseMillis=50 or -XX:G1HeapRegionSize=32m assumes you have profiled your specific workload and understand the trade-offs involved. You have not profiled anything, and you definitely do not understand the trade-offs.

Memory management tweaks like -XX:+UseStringDeduplication or random parallel GC parameters from Java 8 era configurations being applied to Java 21 servers. These people are applying medieval medicine to modern problems.

The Real Problem: Version-Blind Cargo Culting

The most infuriating part of this whole ecosystem is watching people recommend Java 8 arguments for Java 21 servers, or worse, Java 21 arguments for Java 8 servers that just silently fail to apply.

Someone will post a configuration that worked on their specific setup three years ago, and suddenly it gets copy-pasted everywhere regardless of Java version, server size, or hardware. The number of times I have seen -XX:+UseG1GC recommended for Java 21 when ZGC exists and works better is genuinely painful.

This is cargo cult programming: copying the ritual without understanding the purpose or context.

What About All Those Other Arguments?

Most of the exotic arguments in those massive copy-paste configurations are either:

  1. Obsolete - Relevant for Java versions from 2015 that nobody should be running
  2. Experimental - Designed for JVM developers to test features, not for production use
  3. Enterprise-specific - Optimizations that matter for massive applications but are irrelevant for Minecraft servers
  4. Placebo - Parameters that sound important but have minimal impact on typical workloads

The JVM has gotten significantly better at automatically tuning itself over the years. Many manual optimizations that made sense in Java 8 are now handled automatically.

What You Should Actually Do

Use the version-appropriate arguments listed above. That covers 95% of what you actually need.

If your server is still having performance issues after that, the problem is not your JVM arguments. Check your mods, your server configuration, and your hardware before you start cargo culting more JVM parameters.

Profile your server if you want to optimize further. Tools like VisualVM can tell you where your bottlenecks actually are. Spoiler: it’s probably not garbage collection tuning that needs a dozen experimental flags.

When These Rules Don’t Apply

If you are running a server network with hundreds of concurrent players and dedicated infrastructure, you might need more specialized tuning. But at that scale, you should have people who actually understand what these parameters do.

If you have genuinely profiled your specific workload and identified bottlenecks that can be addressed with specific JVM arguments, go ahead. But that means you understand what you are changing and why.

The Short Version

Use the correct arguments for your Java version. Set appropriate memory limits. Choose a modern garbage collector. Stop there unless you actually know what you are doing.

The JVM developers have spent decades optimizing these systems. Random Discord users have not.