
Quick answer: run ATM10 on Java 21, allocate 12GB to 16GB depending on player count, use Generational ZGC if stutter is your problem or tuned G1GC if raw average TPS is, and raise the NeoForge read and login timeouts so players do not get dropped while the pack loads.
All The Mods 10 is one of the heaviest modpacks you can run on a Minecraft server. With 400+ mods, Java's memory management becomes the single biggest factor in whether your server runs smoothly or becomes a slideshow every 30 seconds.
The default JVM arguments that most hosting panels set are generic. They work for vanilla Minecraft, but ATM10 needs specific tuning, and the -Xmx12G -Xms12G line that every forum thread repeats leaves a lot on the table. Below are the arguments we have tested and verified on our Ryzen 9 hardware, both flag sets, when to pick each one, and the config that has to go with them.
This page is only about JVM arguments and the settings that sit next to them. For hardware and RAM sizing, see ATM10 server requirements. For a quick per-workload number, use the ATM10 RAM calculator. For running it on your own machine, see ATM10 PC specs.
Why ATM10 Needs Different Flags from Other Modpacks
ATM10 runs on NeoForge with over 400 mods active at once. At startup the JVM is initialising thousands of classes and wiring up hundreds of mod threads. Once the world is running, every mod that processes items, updates machines or renders effects produces garbage at a rate that vanilla flags were never written for.
That is why copying a vanilla flag set across rarely helps. The problem is not that the collector is bad, it is that the allocation rate is an order of magnitude higher than the collector was tuned for, and the pauses land exactly when a player is flying through ungenerated chunks or a mob farm has just ticked.
What Java Version Does ATM10 Need
Java 21. NeoForge builds for ATM10 target it, and it is also what unlocks the collector work described below, including Generational ZGC. Running the pack on an older runtime is the most common reason a server either refuses to boot or performs far worse than the same flags do elsewhere. Check what your panel is actually launching with before you spend an evening tuning flags, since panels often default to an older installed runtime. If you need the full walkthrough, see the ATM10 Java version guide.
The Recommended ATM10 JVM Arguments (Generational ZGC)
This is the set we run on production ATM10 servers:
java -Xmx12G -Xms12G \
-XX:+UseZGC \
-XX:+ZGenerational \
-XX:+AlwaysPreTouch \
-XX:+DisableExplicitGC \
-XX:+PerfDisableSharedMem \
-XX:+UseFastUnorderedTimeStamps \
-Dfml.readTimeout=180 \
-Dfml.loginTimeout=180 \
-jar server.jar nogui
What each flag is doing:
-XX:+UseZGC -XX:+ZGenerational turns on ZGC in generational mode. It handles ATM10's allocation spikes far better than a stock collector, and the visible result is shorter freeze events during chunk generation and heavy mob spawning.
-XX:+AlwaysPreTouch makes Java map all of its allocated memory at startup rather than lazily. It adds roughly 10 to 15 seconds to boot time and removes the memory page fault stutters that otherwise show up mid session.
-XX:+DisableExplicitGC stops mods calling System.gc() themselves, which would trigger a full stop-the-world collection at the worst possible moment.
-XX:+PerfDisableSharedMem turns off the JVM's shared memory performance counters, cutting a small amount of OS level interference.
-XX:+UseFastUnorderedTimeStamps reduces the cost of the JVM's internal timestamping. Treat it as optional. If your JVM build refuses to start with it, drop that line and keep the rest.
-Dfml.readTimeout=180 -Dfml.loginTimeout=180 are the NeoForge timeouts covered further down.
The Tuned G1GC Flag Set for ATM10
If you would rather stay on G1GC, do not run it stock. This is the tuned set:
-Xms8G -Xmx8G -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
-XX:MaxGCPauseMillis=200 tells G1GC to target collection pauses under 200 milliseconds. That is what prevents the one to two second freezes that wreck TPS during heavy automation.
-XX:G1NewSizePercent=30 and -XX:G1MaxNewSizePercent=40 give more of the heap to the young generation, where short lived objects live. ATM10 mods create enormous numbers of these, so a larger young generation means fewer expensive full GC events.
-XX:G1HeapRegionSize=8M raises the region size, which suits the large allocations modded Minecraft produces constantly.
The AlwaysPreTouch, DisableExplicitGC and PerfDisableSharedMem flags do the same job here as they do in the ZGC set. If you use this set, add the two -Dfml timeout flags to it as well.
ZGC vs G1GC for ATM10: Which One Should You Use
We tested both alternative collectors against tuned G1GC on ATM10:
| GC | Average TPS | GC Pause (avg) | GC Pause (peak) | Memory Overhead |
|---|---|---|---|---|
| G1GC (tuned) | 19.4 | 85ms | 210ms | Baseline |
| ZGC | 18.8 | 12ms | 45ms | +15% |
| Shenandoah | 18.6 | 18ms | 80ms | +12% |
Read that table as a trade, not a winner. Tuned G1GC holds the best average TPS. ZGC gives up a little throughput and costs extra memory, and in exchange its pauses are a fraction of the length.
The practical rule:
- Your average TPS is fine but the server hitches. Use ZGC in generational mode. Short pauses are what players actually feel.
- Your average TPS is the problem and it is low across the board. Use tuned G1GC, and check whether the real limit is CPU or RAM rather than the collector.
- You are tight on RAM. Use G1GC. ZGC's memory overhead is real, and starving the heap to pay for it undoes the benefit.
Whichever you pick, change one thing at a time and measure. Running ZGC flags and G1GC flags together does not work, since the collector selection flags conflict.
How Much RAM to Allocate: -Xms and -Xmx
-Xms8G -Xmx8G
Set minimum and maximum to the same value so Java is not constantly resizing the heap. From there, size by player count:
| Players | Minimum RAM | Recommended RAM |
|---|---|---|
| 1 to 5 | 8GB | 10GB |
| 5 to 10 | 10GB | 12GB |
| 10 to 15 | 10GB | 14GB |
| 15 to 20 | 12GB | 16GB |
| 20 to 30 | 14GB | 18GB |
| 30+ | 20GB | 24GB |
8GB is the floor for a small group. Past ten players you want headroom for chunk loading, and past twenty you are sizing for everyone being active in different dimensions at the same time rather than for an average.
Never set -Xmx higher than your actual available RAM minus 2GB, which the OS and JVM overhead need. Allocating everything is one of the fastest ways to turn a stuttering server into a crashing one.
Fixing ATM10 Players Timing Out While the Pack Loads
-Dfml.readTimeout=180
-Dfml.loginTimeout=180
A pack this size can take longer to hand over its mod list and registry data than NeoForge's default timeouts allow. When that happens the client disconnects part way through joining, usually with a timeout message and no crash report, and it looks like a network fault when it is not.
Raising both values to 180 gives the handshake room to finish. This matters most on first join, after a pack update when registries have changed, and for players on slower connections. If you see people repeatedly failing to get past the loading screen while the server itself is healthy, set these before you go looking anywhere else.
Where to Put These Flags
They go in whatever actually launches the server: the start script's java line, or your panel's JVM arguments field. The -Xms, -Xmx, -XX and -D flags all belong before -jar server.jar, and anything after server.jar is passed to the server rather than the JVM. If you paste flags after the jar, they are silently ignored, which is why a flag set can look applied and change nothing.
server.properties Settings That Matter for ATM10
JVM flags are only half of it. These lines do real work:
view-distance=8
simulation-distance=6
max-tick-time=120000
max-chained-neighbor-updates=1000
Lowering simulation distance is the single biggest TPS improvement available on a heavily modded server. Most ATM10 players will never notice the difference between 8 and 6, but the server will.
Keep view distance at 8 or lower. ATM10's worldgen is expensive and rendering 10+ chunks per player will tank TPS.
max-tick-time=120000 gives the server two minutes before it declares a tick hung, which stops it killing itself during heavy world generation or initial loading.
max-chained-neighbor-updates=1000 caps how far a single block update cascade can propagate, which keeps one badly built contraption from stalling a tick. There is more of this in the ATM10 server config guide.
Testing Your Configuration
After changing flags, measure with Spark rather than guessing:
/spark tps
/spark profiler start --timeout 300
Run it for five minutes of normal gameplay and read the results. Regular GC pauses over 500ms mean the heap is too small. TPS dropping below 18 during automation means you are short on CPU or RAM, and no flag set fixes that. At that point you need a higher tier hosting plan with more allocated RAM and CPU.
The Hardware Underneath the Flags
Flags can only optimise what the hardware gives them. ATM10's mod loading leans hard on clock speed, and the Ryzen 9 9950X chews through the long instruction chains modded startup generates faster than older server chips manage. That is the hardware our ATM10 servers run on as standard.
If you have applied these flags elsewhere and TPS is still bad, the configuration probably is not the problem. Shared, oversubscribed CPU is.
ATM10 Requirements and Lag Guides
If you are still choosing server size, start with ATM10 server requirements and the ATM10 RAM calculator. If your server already runs but TPS drops, use ATM10 lag fix and optimization. For flag theory that applies beyond this pack, see Aikar flags explained.
JVM flags cannot fix a crash that happens outside Java. If your game dies with no crash report, read exit code -1073740791 explained.