Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Java 21 and RAM Guide for Paper Minecraft Servers

java-21-server-ram.webp

Quick answer: Paper 1.20 through 1.21.11 uses Java 21. Give the heap enough memory for the measured workload, but never assign the entire machine or Pterodactyl container limit to -Xmx. On a modern JVM, Paper recommends trying default GC behavior first and adding specialized flags only when profiling shows a GC problem.

Last reviewed: 31 August 2026 against current Paper documentation.

Use the Java version for the Paper branch​


Paper's current requirements matrix recommends:

  • Minecraft 1.20 through 1.21.11: Java 21
  • Paper 26.1 and newer: Java 25

Check the JVM used by the actual startup command, not merely the default Java installed in your SSH shell.

Bash:
java -version
ps -eo pid,cmd | grep '[j]ava'

In Pterodactyl, the egg or Docker image determines the server runtime. A host can have Java 21 while a container runs a different version.

Heap is not total process memory​


-Xmx limits the Java heap, not the whole process. Java also uses native memory for threads, code cache, direct buffers, libraries and the JVM itself. The host needs RAM for Linux, filesystem cache, Docker/Pterodactyl, databases and other servers.

If an 8 GB node gives one Minecraft process -Xmx8G, there is no room for that overhead. Paper's Aikar-flags page recommends leaving roughly 1000-1500 MB outside the heap in a typical hosted case. On a machine running Panel, MariaDB, Redis or multiple containers, you may need more.

How much RAM should a server use?​


There is no accurate player-count-only formula. Memory depends on:

  • Loaded chunks and view distance
  • World count and pregeneration state
  • Entity and block-entity population
  • Plugin caches and retained objects
  • Concurrent matches/arenas
  • Online players and inventory/profile data
  • Modded or custom content

Start with a reasonable budget, observe the post-GC live set during representative peak load, retain burst capacity and preserve host headroom. If the post-GC floor rises continuously, investigate retention instead of automatically increasing Xmx.

Xms and Xmx​


-Xms is the initial heap and -Xmx is the maximum. Matching them makes the full heap commitment predictable and is part of Aikar's classic recommendation, but it also reserves a large budget immediately. On constrained shared nodes, make sure that reservation fits alongside every other service.

Paper's short modern-Java example is intentionally simple:

Bash:
java -Xms4G -Xmx4G -jar paper.jar --nogui

In Pterodactyl, ensure the container memory limit exceeds the heap enough for native overhead. An OOM-killed container can occur even when a Java heap dump suggests free heap.

Default GC or Aikar flags?​


Paper's current start-script generator says that Java 17/21+ users should try no special flags first because modern JVM defaults are capable. It points to Aikar's flags when an older stack or measured GC issue needs them.

That gives a clear decision process:

  1. Run the supported Java version with simple heap settings.
  2. Capture Spark health and profiler data during peak load.
  3. Enable GC logging if pauses or old-generation pressure are suspected.
  4. Change flags only with a hypothesis and repeatable workload.
  5. Compare pause distribution, allocation rate and player-visible hitches.

Do not mix fragments from multiple “flag guides.” Options interact, and unsupported flags can prevent startup after a Java upgrade.

Enable bounded GC logs when needed​


Paper documents this rotating Java 11+ GC log form:

Bash:
-Xlog:gc*:logs/gc.log:time,uptime:filecount=5,filesize=1M

Create the log directory with correct permissions and monitor disk use. Correlate pause timestamps with Spark and player reports.

Memory symptoms and likely causes​


SymptomInvestigate
Heap rises then drops normallyExpected allocation and collection
Post-GC floor continually risesRetained objects, unbounded cache or leak
Container killed below XmxNative overhead plus container/host limit
Long full-GC pausesOld-generation pressure, allocation rate, insufficient headroom or retention
High MSPT with low GC timeCPU-bound game/plugin work, not RAM
Host swap usage risesOver-allocation across processes or containers

Use Spark profiling before concluding that every hitch is garbage collection.

RAM myths​


  • “32 GB is always faster than 8 GB.” Beyond the required working set, more heap has diminishing returns and can complicate collection behavior.
  • “Used heap means a leak.” Java is designed to use heap and reclaim it later.
  • “Free host RAM should all go to Xmx.” Linux file cache and native memory are useful too.
  • “Aikar flags are mandatory.” Paper's current modern-Java guidance says to try defaults first.
  • “RAM fixes low TPS.” It does not fix main-thread CPU work when GC is healthy.

Practical acceptance test​


  1. Start the server from a cold boot and record startup time.
  2. Run the representative peak workload for at least 30 minutes.
  3. Capture Spark health and a profile during active gameplay.
  4. Record post-GC heap, GC pause time, MSPT percentiles and host free/swap memory.
  5. Confirm the process remains comfortably below the container/host limit.
  6. Restart and verify the same launch command is still used.

Continue with the Paper optimization guide. For production troubleshooting, send Shyam Studio the Spark report, startup command and memory limits.

Primary sources​


 

Attachments

  • java-21-server-ram.webp
    java-21-server-ram.webp
    83.6 KB · Views: 1
Last edited:
Back
Top