
Quick Answer: Minecraft 1.21 lag is caused by heavier world generation and more entities, but "lag" is four different problems with four different fixes. Check /tps and /mspt first, then: 1) run Purpur instead of vanilla, 2) drop simulation-distance to 4 or 6, 3) use Aikar's flags with -Xms equal to -Xmx, or ZGC on 8GB and up, 4) pre-generate the world with Chunky, 5) profile with Spark before you buy more hardware. How many players the server holds after that depends mostly on your plugins, farms and mods, so measure it yourself with /tps, /mspt and Spark.
Server Lag or Client Lag? Check This First
Half the lag reports you get are not server lag at all. Split them before you touch a config file.
Server lag (low TPS) affects everyone at the same time. Mobs freeze in place, blocks break with a delay and pop back, hoppers stall, inventories open slowly. You confirm it with /tps.
Client lag (low FPS) affects one player. Their movement stutters, the frame rate drops, but mobs and redstone behave normally for everyone else. They confirm it with the F3 debug screen, bottom right. The fix is on their machine: lower render distance, a client performance mod, better GPU. No amount of server RAM helps.
TPS is server side game logic, 20 ticks per second, 50 milliseconds per tick. FPS is client side rendering. A player with 300 FPS still sees rubber banding when server TPS sits at 14.
What Your TPS Number Means
- 20 TPS, perfect, every tick finishes inside its 50ms budget
- 15 to 19 TPS, mild lag, movement stutters and redstone gets sloppy
- 10 to 14 TPS, heavy lag, block delays and mob freezing
- Below 10 TPS, effectively unplayable
Anything consistently below 19.5 is worth investigating.
The Four Types of Minecraft Server Lag
Before you fix anything, classify what you are seeing. Throwing RAM at a network problem does nothing, and upgrading the CPU will not stop a garbage collection freeze.
1. TPS Lag (Tick Lag)
Symptoms: block break delays, mob AI freezing, redstone misfiring, items stuck in hoppers, and the console printing Can't keep up! Is the server overloaded?
What is happening: the main thread cannot finish the game logic inside 50ms, so ticks get skipped.
2. Chunk Loading Stutter
Symptoms: smooth at spawn, hitches or full freezes when players walk or fly into new terrain. Elytra flight is the worst case.
What is happening: the server is generating terrain live, which hammers one CPU core and the disk at the same time.
3. Garbage Collection Lag
Symptoms: the server runs fine for a few minutes, freezes solid for a noticeable moment, then resumes. The pattern repeats on a rhythm.
What is happening: the JVM is pausing every thread to clean up unused memory.
4. Network Lag (Desync)
Symptoms: players rubber band backwards, broken blocks reappear, hits do not register. Only some players are affected, not the whole server at once.
What is happening: packets between client and server are delayed or dropped. TPS can be a flat 20.0 while this is going on.
How to Check TPS and MSPT on a Minecraft Server
/tps
/tps
Output:
TPS from last 1m, 5m, 15m: 19.8, 19.9, 20.0
Good is above 19.5 and stable. 17 to 19 means noticeable lag. Below 17 is unplayable.
/mspt
TPS alone hides how close you are to the edge. A server at 20.0 TPS with 49ms ticks is one mob farm away from collapsing. MSPT shows the real headroom:
/mspt
- Below 40ms, healthy, room to grow
- 40 to 50ms, warning zone, any spike drops ticks
- Above 50ms, the server is already skipping ticks
Checking Garbage Collection Activity
If the freezes are rhythmic, log the collector. Add to your startup flags:
-verbose:gc -Xlog:gc*:file=gc.log:time
Then read gc.log. Pauses above 200ms are a problem. A line like this is a two second freeze:
[Full GC (Allocation Failure) 2048M->1800M(2048M), 2.1 secs]
Why Minecraft 1.21+ Is So Much Heavier
The Technical Changes
Minecraft 1.21 "Tricky Trials" and later introduced changes that all cost tick time:
| Change | Why it costs performance |
|---|---|
| Trial Chambers (new structure) | Complex generation with many entities and spawners |
| Breeze mob | Its own AI and pathfinding |
| Wind Charges | Extra projectiles to simulate in combat |
| Copper and Tuff variants | More block states to keep in memory |
How much extra load that adds depends entirely on your world and players, so we won't put a percentage on it. A setup that barely held 20 TPS on 1.20 can fall short on 1.21 with the same hardware and plugins. If your server "suddenly started lagging after the update", nothing broke. The workload grew. Check /mspt and a Spark profile before and after the update to see where the extra time goes.
Step 1: The Right Server Software (Vanilla vs Spigot vs Paper vs Purpur)
1.1 The Server Software Hierarchy
Vanilla (Mojang) → Bad for performance
↓
Spigot → Basic optimizations
↓
Paper → Excellent optimizations + API
↓
Purpur → Paper + configuration freedom, best of the four
Older charts put Pufferfish between Paper and Purpur, because Purpur used to pull in Pufferfish's patches. Current Purpur is built directly on Paper. Pufferfish itself has no build for 26.x (its newest download is 1.21.8), so it is not an option on a current server.
Short version if you just want the ranking:
- Purpur, Paper plus a huge config surface. Best for 20+ players.
- Paper, async chunk loading and redstone rewrites. Great for 10 to 50 players.
- Spigot, vanilla plus basic tweaks. Acceptable for 5 to 20 players.
- Vanilla, no optimizations at all. Only for a 2 to 5 player world.
Plugin compatibility is identical across Spigot, Paper and Purpur, so there is no compatibility reason to stay on the slower option.
1.2 Why Purpur
| Feature | Vanilla | Paper | Purpur |
|---|---|---|---|
| Async chunk loading | No | Yes | Yes (from Paper) |
| Entity activation range | No | Yes (spigot.yml) | Same as Paper |
| Redstone optimizations | No | Yes | Same as Paper |
| Config options | Few | Many | Very many |
| Villager lobotomize option | No | No | Yes |
| Per mob gameplay settings | No | No | Yes |
How big the difference is on your server depends on the plugins, farms and player count, so measure it: note /mspt during a normal evening, switch the jar, and compare the same kind of evening afterwards.
1.3 Installing Purpur
Downloads are at https://purpurmc.org/downloads
# SSH to your VPS
ssh root@your-vps-ip
# Create server directory
mkdir -p /opt/minecraft-server
cd /opt/minecraft-server
# Download Purpur (replace the version with the current one)
wget https://api.purpurmc.org/v2/purpur/1.21.1/latest/download -O purpur.jar
# Accept EULA
echo "eula=true" > eula.txt
First start, which generates the config files:
java -Xms2G -Xmx4G -jar purpur.jar nogui
Stop the server after 30 seconds with Ctrl+C. You now have every config file you need for the next steps.
Step 2: server.properties (View Distance and Simulation Distance)
nano server.properties
# === PERFORMANCE CRITICAL ===
# Simulation distance: how many chunks around a player are "active"
# Default 10, lower it to 4 or 6
# This is the single most important setting
simulation-distance=4
# View distance: how far a player can SEE
# Costs bandwidth and chunk tracking, not much tick time
# 10 is fine on decent hardware, drop to 6 or 8 if you are still short
view-distance=10
# Network compression, balance between CPU and bandwidth
# 256 is the sweet spot
network-compression-threshold=256
# Spawn protection, unnecessary on survival
spawn-protection=0
# Ceiling on a single tick before the watchdog kills the server
max-tick-time=60000
# World size cap, keeps generation bounded
max-world-size=10000
# === CHUNK LOADING ===
# Chunks around spawn that always stay loaded
# Lower or 0 for less RAM
spawn-chunk-radius=2
Why Simulation Distance Matters More Than View Distance
| Simulation Distance | Active chunks per player | Share of the default |
|---|---|---|
| 10 (default) | 441 chunks | 100% |
| 6 | 169 chunks | 38% |
| 4 | 81 chunks | 18% |
Going from 10 to 4 cuts the number of chunks the server simulates around each player by more than 80%. Players barely notice. Farms run slightly slower and mobs spawn closer, that is the whole trade.
View distance is a different budget. It decides how many chunks the server has to keep tracked and sent to each client, so it costs memory and bandwidth. Cut simulation distance first. If you are still over 50ms MSPT, then bring view distance from 10 down to 6 or 8, which cuts the number of chunks tracked and sent per player by a third or more.
Step 3: purpur.yml (Advanced Purpur Options)
nano purpur.yml
world-settings:
default:
# === MOB AI OPTIMIZATION ===
mobs:
zombie:
ridable: false
aggressive-towards-villager-when-lagging: false
# Tropical fish do nothing but cost AI time
tropical_fish:
ridable: false
takes-damage-from-water: false
# Axolotls spawn a lot and do little
axolotl:
ridable: false
# === REDSTONE ===
# Limit hopper checks, one of the biggest lag sources
hopper:
disable-move-event: true
# === ENTITIES ===
# Merge dropped items so there are fewer entities
merge-radius:
item: 4.0
exp: 6.0
# Despawn junk items faster
alt-item-despawn-rate:
enabled: true
items:
cobblestone: 300
netherrack: 300
sand: 300
gravel: 300
# === VILLAGERS ===
villager:
lobotomize:
enabled: true
check-interval: 100
brain-ticks: 2
# === PATHFINDING ===
use-async-pathfinding: true
Lobotomize villagers. Villagers that cannot pathfind, which is every villager in a trading hall, stop receiving AI after 100 ticks. They still trade and still breed, but they cost very little per tick. On a server with a big trading hall this is often the largest single win available.
Step 4: spigot.yml (Entity Activation and Growth)
nano spigot.yml
world-settings:
default:
# === MOB SPAWN LIMITS ===
mob-spawn-range: 6
entity-activation-range:
animals: 16
monsters: 24
raiders: 48
misc: 8
water: 8
villagers: 16
flying-monsters: 48
entity-tracking-range:
players: 48
animals: 48
monsters: 48
misc: 32
# === DESPAWN RATES ===
item-despawn-rate: 3000
arrow-despawn-rate: 600
# === MERGE SETTINGS ===
merge-radius:
item: 4.0
exp: 6.0
Entity activation range is how far from a player a mob keeps running its AI. The defaults are generous, 32 for animals and monsters. Halving them means a mob 20 blocks behind a wall stops pathfinding until someone comes back.
Growth modifiers in the same file are often set the wrong way round. 100 is vanilla speed, and a higher value makes crops grow faster, not slower. Paper's documentation describes it as "The growth modifier percentage for cactus, where Vanilla speed is 100%". Lowering the values slows farms down, but the server still random ticks those blocks, so it is not a real performance fix. Leave them at 100 and handle farm output with entity limits and item merging instead.
Step 5: paper-world-defaults.yml (Paper Specific)
nano config/paper-world-defaults.yml
entities:
spawning:
spawn-limits:
ambient: 5
axolotls: 3
creature: 8
monster: 50
underground_water_creature: 3
water_ambient: 15
water_creature: 3
# Give each player their own mob budget instead of a global pool
per-player-mob-spawns: true
behavior:
tick-inactive-villagers: false
collisions:
# Stops mob grinders from turning into a physics simulation
max-entity-collisions: 2
chunks:
auto-save-interval: 6000
prevent-moving-into-unloaded-chunks: true
max-auto-save-chunks-per-tick: 8
environment:
optimize-explosions: true
anticheat:
anti-xray:
enabled: true
engine-mode: 2
per-player-mob-spawns is the setting most people miss. Without it, one player standing in a mob farm eats the entire server mob cap and everyone else's spawns die with it.
anti-xray engine mode 2 costs some CPU. It is worth it on a public server and worth skipping on a private one that is already tight on tick time.
Step 6: bukkit.yml (Global Spawn Caps)
spigot.yml controls range, bukkit.yml controls raw counts:
spawn-limits:
monsters: 50
animals: 8
water-animals: 5
ambient: 1
The vanilla monster cap of 70 is high for a server with plugins. Dropping to 50 costs almost nothing in gameplay and takes real work off the tick.
Step 7: How Much RAM to Allocate (and How to Waste It)
| Server Type | Players | Mods/Plugins | Minimum RAM | Recommended RAM |
|---|---|---|---|---|
| Vanilla 1.21 | 1 to 10 | None | 2GB | 4GB |
| Vanilla 1.21 | 10 to 20 | None | 4GB | 6GB |
| Vanilla 1.21 | 20 to 50 | None | 6GB | 8GB |
| Light plugins | 10 to 20 | 10 to 15 | 4GB | 6GB |
| Heavy plugins | 20 to 50 | 20+ | 8GB | 12GB |
| Light modpack | 1 to 10 | 50 to 100 | 4GB | 6GB |
| Heavy modpack | 1 to 10 | 150+ | 6GB | 8 to 12GB |
| Large modpack | 10 to 20 | 200+ | 12GB | 16 to 24GB |
Three mistakes that cost more performance than they buy:
- Do not give every byte of the machine to Java. Leave 1GB to 2GB for the operating system, the panel and backups. A host that starts swapping is far slower than a host with a smaller heap.
- Do not allocate 32GB because it was on the plan. Bigger heaps mean longer collection cycles. A tuned 12GB heap beats a sloppy 32GB heap on the same box.
- Do not guess. Run
/spark heapsummaryand size the heap to what the server actually holds.
Set -Xms and -Xmx to the same value. A JVM that resizes the heap while the game is running produces exactly the stutter you are trying to remove.
Step 8: Java Startup Flags (Aikar's Flags)
8.1 Why Plain java -jar Is Bad
Default java -jar server.jar runs with an untuned collector. Large garbage collections can freeze the server for a noticeable moment, memory is used inefficiently, and players can disconnect on the longer pauses.
8.2 Aikar's Flags for 4GB
java -Xms4G -Xmx4G \
-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 purpur.jar nogui
For a 6GB server, replace -Xms4G -Xmx4G with -Xms6G -Xmx6G. Nothing else changes.
8.3 ZGC for 8GB and Larger Heaps
Above roughly 8GB, G1 pause times grow with the heap. ZGC collects concurrently and keeps pauses under 10ms, which is below the point anyone can feel it:
java -Xms8G -Xmx8G \
-XX:+UseZGC \
-XX:+ZGenerational \
-XX:+ParallelRefProcEnabled \
-XX:+UnlockExperimentalVMOptions \
-XX:+DisableExplicitGC \
-XX:+AlwaysPreTouch \
-XX:ZCollectionInterval=5 \
-XX:ZAllocationSpikeTolerance=2.0 \
-Dusing.aikars.flags=https://mcflags.emc.gs \
-jar purpur.jar nogui
Generational ZGC (-XX:+ZGenerational) is the version you want on a modern JDK. If your Java build rejects the flag, drop that one line and keep the rest.
Run Java 21 (Temurin or another current build). More on flag choice in Aikar's flags explained.
8.4 Startup Script
nano start.sh
#!/bin/bash
java -Xms4G -Xmx4G \
-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 purpur.jar nogui
chmod +x start.sh
./start.sh
Step 9: Performance Mods and Plugins Worth Installing
Lithium, Server Side Logic
Lithium rewrites large parts of Minecraft's internals without changing a single gameplay rule: mob pathfinding, block ticking, chunk loading, physics. Nothing a player can see changes, everything gets cheaper.
cd /opt/minecraft-server/mods
wget https://cdn.modrinth.com/data/gvQqBUqZ/versions/latest/lithium-fabric-mc1.21.jar
Lithium is a mod for Fabric (newer versions also exist for NeoForge). It does not load on Paper or Purpur. Those servers rely on their own optimization patches instead.
FerriteCore, RAM Reduction
FerriteCore restructures how block states and other game data are stored in memory, which lowers RAM use. The saving is biggest on modded servers with many blocks and models. On a 4GB server or any modded server, that headroom goes straight back into chunk caching.
cd /opt/minecraft-server/mods
wget https://cdn.modrinth.com/data/uXXizFIs/versions/latest/ferritecore-7.0.0-fabric.jar
Check the RAM graph in your panel before and after installing it to see what it saves on your own pack.
Krypton, Network Optimization
Krypton rewrites the packet layer. It matters once you are past roughly 15 concurrent players, when packet volume rather than tick time starts to dominate.
wget https://cdn.modrinth.com/data/fQEb0iXm/versions/latest/krypton-0.2.8-fabric.jar
For Forge and NeoForge Modpacks
| Mod | Function | Source |
|---|---|---|
| ModernFix | General optimizations and faster startup | modrinth.com/mod/modernfix |
| FerriteCore | RAM reduction | modrinth.com/mod/ferritecore |
| EntityCulling | Skips rendering and some processing for hidden entities | modrinth.com/mod/entityculling |
| Canary | The Lithium equivalent for Forge | modrinth.com/mod/canary |
| Roadrunner | Async chunk loading | modrinth.com/mod/roadrunner |
Install these one at a time and check /mspt after each. Stacking five optimization mods blind is how you end up with a crash you cannot attribute.
How to Fix Lag Spikes Every 30 Seconds (Garbage Collection)
This is the rhythmic freeze: fine for a few minutes, then a hard stop for a noticeable moment, then fine again.
- Confirm it. Add
-verbose:gc -Xlog:gc*:file=gc.log:timeand look for pauses over 200ms. - Set
-Xmsequal to-Xmx. - Use Aikar's flags on small heaps, Generational ZGC on 8GB and up.
- Do not fix it by allocating more memory. A larger heap with the wrong collector makes the pause longer, not rarer.
If the pauses continue with ZGC and a correctly sized heap, you are not looking at a GC problem. Profile with Spark instead.
How to Fix Chunk Loading Lag: Pre-Generate the World
If the server is smooth at spawn and hitches whenever someone explores, you are paying for terrain generation live, during ticks. Generate it up front instead.
Install the Chunky plugin and run it with nobody online:
/chunky world world
/chunky radius 5000
/chunky start
That covers a 10,000 by 10,000 block area around spawn. Depending on the CPU it takes between one and six hours, and it is the single best thing you can do for a server whose players roam.
Two things that make pre-generation stick:
- Set a world border so players cannot walk past the generated area:
/worldborder set 10000 - Run on NVMe. Chunk loading is an I/O operation before it is anything else. See the storage table further down.
Full walkthrough in the world pre-generation guide.
Entity and Mob Management (Farms, Items, Grinders)
Entities are the most common cause of TPS lag on an established server, because entity load grows every week the server is up while the config stays where you left it.
ClearLag and Manual Cleanup
The ClearLag plugin removes ground items and excess mobs on a timer:
/lagg clear # remove dropped items
/lagg killmobs # kill excess mobs
/lagg area 20 # count entities within 20 blocks
Set auto clear to run every 10 minutes in its config.yml. Be aware that the clear itself causes a brief TPS dip, which is a common answer to "why does the server hiccup on a schedule".
Limit What Players Can Build
Mob grinders, iron farms and villager breeders are where the entities come from. The caps in bukkit.yml and max-entity-collisions: 2 in the Paper config do more than any cleanup plugin, because they stop the entities from existing rather than deleting them after they have already cost you a tick.
How to Find the Plugin or Mod That Is Causing Lag
Spark, the Profiler Worth Learning
cd /opt/minecraft-server/plugins
wget https://ci.lucko.me/job/spark/lastSuccessfulBuild/artifact/spark-bukkit/build/libs/spark-bukkit.jar
In game:
/spark profiler start
# let it run 60 seconds to 3 minutes during real activity
/spark profiler stop
Spark returns a web link with a call tree: which plugin, which mod, which task, which chunk. It tells you the answer instead of letting you guess. During an intermittent problem, run it long:
/spark profiler --timeout 600
There is a deeper walkthrough in the Spark profiler guide.
Memory side:
/spark heapsummary
/spark heapdump
Timings
/timings on
# wait 10 minutes
/timings paste
Read the report by looking for the biggest bars:
Entity Tickhigh, too many entities, cut activation range and despawn ratesTile Entityhigh, too many hoppers and chests, rework the redstoneWorld Tickhigh, simulation distance too high
Plugins That Commonly Cost You Tick Time
| Costly choice | Better alternative |
|---|---|
| WorldEdit on a large paste | FastAsyncWorldEdit (FAWE) |
| An outdated EssentialsX build | Current EssentialsX |
| PermissionsEx | LuckPerms |
| An old Multiverse build | Current Multiverse |
The pattern is version age, not brand. Abandoned permissions plugins and old world editors are the usual suspects, and heavy logging plugins are worth checking with Spark before you blame the hardware.
Which CPU Do You Need for a Minecraft Server?
Minecraft's main game loop is single-threaded. Clock speed beats core count, every time. Sixteen slow cores will lose to four fast ones.
Good single-thread performance, in the class of chips people actually run servers on:
- AMD Ryzen 9 7950X, 5.7GHz boost
- AMD Ryzen 7 5800X, 4.7GHz boost
- Intel i9-12900K, 5.2GHz boost
- Budget option, AMD Ryzen 5 5600X, 4.6GHz boost
Avoid old Xeons in the 2.4GHz range, budget Celerons and ARM processors. They benchmark fine on paper for web workloads and fall apart on a tick loop.
Paper and Purpur move some work off the main thread (chunk loading, some mob AI, pathfinding), so extra cores are not wasted, but they never turn a slow core into a fast one. More on picking silicon in the best CPU for a Minecraft server.
Plan guidance on Space-Node (Standard tier prices per month):
- MC Iron, 4GB for €3.60: vanilla or Paper with a small group
- MC Lapis, 6GB for €5.40: a plugin SMP with more players
- MC Diamond, 8GB for €7.20, or MC Special 1, 12GB for €10.80: modpacks or bigger communities
These are starting points. Plugins, farms and mods decide more than the player count, and you can upgrade later without losing the world.
Storage: NVMe vs SSD vs HDD
| Type | Chunk loading | Auto save | Price |
|---|---|---|---|
| HDD | Slow, visible during exploration | Can cause noticeable freezes | Cheap |
| SATA SSD | Much faster | Usually a small hitch at most | Standard |
| NVMe | Fastest | Rarely noticeable | Now common on game hosts |
Chunk loading and the five minute auto save are both I/O bound. On an HDD backed server, the auto save alone is enough to produce a visible freeze on a schedule.
How to Fix Rubber Banding and High Ping (Network Lag)
Network lag looks like server lag to players and nothing like it in the metrics. TPS reads 20.0, MSPT is healthy, and people still teleport backwards.
- Check who is affected. If it is one or two players, the problem is their connection or their route, not your server. Have them run a traceroute during a lag episode.
- Check the server location against your player base. Latency decides how block placement, PvP hits and inventory actions feel. Pick the location closest to most of your players. Ping depends mostly on distance, so a server on the wrong continent feels laggy however fast it is. The plan selector on our Minecraft hosting page shows a live latency check per region before you order.
- Look at the time of day. A budget host on a congested network drops packets at peak hours and is clean at 4 AM. That pattern is the network, not your config.
- Rule out an attack. If lag spikes correlate with specific events or repeat at odd times, check whether the server is being hit. Filtering handles it without touching legitimate game traffic. See DDoS protection for Minecraft servers.
- Set compression sensibly in
server.properties:
Lower values send less data and burn more CPU. 256 is the balance point for almost everyone.network-compression-threshold=256
Why Is My Server Lagging With Only 5 Players?
Player count is rarely the cause. Work through this order:
- Run
/tpsand/mspt. If TPS is at 20 and MSPT is under 40ms, the lag is client side or network side, and no server change will help. - Check RAM. 2GB minimum for vanilla, 4GB once you have plugins. Then check you are not swapping.
- Check the CPU. You want 3.5GHz or better on boost clock. A 2.4GHz core will lag with two players in a redstone build.
- Profile with Spark. On a five player server, one bad plugin is usually the entire problem.
- Cut simulation distance to 4 and see whether the number moves.
Most five player lag is either an outdated plugin or a cheap core. It is almost never a shortage of memory, which is what people upgrade first.
Why Does the Server Only Lag at Certain Times?
Rhythmic lag has a scheduler behind it. The candidates, in the order they usually turn out to be responsible:
- Auto save, every 5 minutes by default (6000 ticks). Painful on slow storage, invisible on NVMe.
- Garbage collection, a brief freeze on a rhythm. See the GC section.
- Backups, if they run at peak time. Move them to off hours.
- Plugin tasks, scheduled jobs inside plugins. Spark finds these.
- ClearLag sweeps, every 10 minutes by default, brief dip each time.
Run /spark profiler --timeout 600 across a full cycle and match the spike to the schedule.
How to Fix "Can't Keep Up! Is the Server Overloaded?"
[WARN] Can't keep up! Is the server overloaded? Running 5000ms behind, skipping 100 ticks
This means a tick could not finish inside 50ms, so the server skipped ticks to catch up. That is the rubber band players feel.
Three causes, in order of frequency:
- Simulation distance too high. Drop it to 4.
- Redstone and hoppers. Use
/sparkto find the chunks with the most tile entities. Water streams move items for free where hoppers cost a check per tick. - Not enough CPU. Fewer players or a faster core.
High RAM Use and Server Crashes
Diagnose before you buy memory:
/spark heapsummary
/spark heapdump
Common causes:
- Too many entities in spawn chunks. Reduce
spawn-chunk-radiusto 0 or 2. - A mob farm running unattended. Cap it with
entity-activation-rangeand per player mob spawns. - A leak in a plugin or mod. The heap dump names the class holding the memory. Disable the suspect and watch whether the curve changes.
A server that crashes with OutOfMemoryError after several hours is leaking, not undersized. Adding RAM only moves the crash later in the day.
Can One Server Hold 100+ Players?
Yes, with the right build:
- 24GB to 32GB RAM
- A top end Ryzen 9 or i9 class CPU, 5.0GHz or better on boost
- Purpur, with async work enabled
- NVMe storage for chunk I/O
- A tight plugin list, audited with Spark
- A pre-generated world so nobody is generating terrain at prime time
Past a certain size, the answer is not a bigger box, it is a proxy: split lobby, survival and minigames across backend servers behind Velocity or BungeeCord. See Velocity vs BungeeCord.
When the Hardware Is Actually the Problem
Most lag is configuration. Some of it is not, and it is worth knowing the difference before you spend money.
You have genuinely outgrown the machine when all of the following are true:
- Spark shows
MinecraftServer.tickServeritself as the bottleneck, not a named plugin or mod - The main thread sits pinned at 100% CPU
- Adding players or loaded chunks drops TPS proportionally, in a straight line
- You have already pre-generated the world, tuned the collector and cut simulation distance
At that point the only fix is more single-thread performance and faster storage. Everything else you do is rearranging the same workload.
Optimization Checklist
server.properties:
-
simulation-distance=4(6 at most) -
view-distance=10, lower to 6 or 8 only if MSPT is still high -
network-compression-threshold=256 -
spawn-protection=0
purpur.yml:
-
villager.lobotomize.enabled: true -
merge-radius.item: 4.0 -
alt-item-despawn-rate.enabled: true -
use-async-pathfinding: true
spigot.yml:
-
mob-spawn-range: 6 -
entity-activation-rangereduced -
item-despawn-rate: 3000
Paper config:
-
per-player-mob-spawns: true -
max-entity-collisions: 2 -
optimize-explosions: true
bukkit.yml:
-
spawn-limits.monsters: 50
Startup:
- Aikar's flags, or ZGC above 8GB
-
-Xmsequal to-Xmx - 1GB to 2GB left free for the operating system
- Java 21
World:
- Pre-generated with Chunky
- World border set
Monitoring:
- Spark installed
-
/tpsand/msptchecked after every change, one change at a time
Result: Measure Your Own Before and After
We are not going to show you a made-up before and after table. The gain depends on your world, plugins and players. What you can do is measure it yourself:
- Before you change anything, write down
/tps,/mspt, RAM use from the panel graph, and how often the console warns "Can't keep up", during a normal busy evening. - Apply the changes from this guide one at a time.
- Write down the same numbers on a comparable evening afterwards.
When the fixes work, players notice less rubber banding, chunks that keep up while they walk, combat that registers, and no disconnects during a GC pause.
Where to Start Tomorrow
If you only have an hour, do these in order and check /mspt between each one:
- Move to Purpur if you are on vanilla or Spigot.
- Set
simulation-distance=4. - Fix the startup flags, with
-Xmsequal to-Xmx. - Pre-generate the world with Chunky and set a border.
- Run Spark for 60 seconds under load and read the top of the call tree.
Steps 1 through 3 take about 20 minutes and cover most of the distance. Step 5 is what stops you from guessing on everything after that.
Ready to run an optimized Minecraft server? Space-Node Minecraft hosting runs Ryzen 9 CPUs and NVMe storage, and every plan supports Purpur. Plans start at €2.70 per month for MC Coal (3GB).
Related guides:
- Aikar's Flags: Best JVM Arguments for Minecraft
- Paper vs Purpur vs Fabric: Server Software Compared
- Minecraft Server Requirements: RAM, CPU and Storage
- World Pre-Generation with Chunky
- Spark Profiler: Find and Fix Server Lag
- Best Minecraft Server Plugins 2026
- Best CPU for a Minecraft Server
- RAM Calculator: How Much Do You Really Need?
- Top Performance Mods for Minecraft 1.21
- Forge vs NeoForge: Which Modloader to Choose in 2026