Diagnosing Minecraft Server Lag: A Symptom-First Guide
Table of Contents
Most lag guides give you the same checklist: lower view distance, install Paper, pre-generate the world, use Spark. The advice is correct. But running through every optimization for every kind of lag is the equivalent of taking every medicine in your cabinet for every illness.
This guide is the opposite. You tell us what the lag looks like, and we tell you what’s almost certainly causing it.
First, learn to read TPS and MSPT
Two numbers matter:
- TPS (ticks per second) — should sit at 20.0. Anything below 18 is noticeable lag.
- MSPT (milliseconds per tick) — should sit under 50ms (which is what 20 TPS implies). When MSPT > 50 sustained, TPS falls.
Run /tps in console or in-game (Paper exposes it). For more detail run /mspt — Paper shows you average, min, and max over the last 5/10/60 seconds.
Without those numbers, every “the server feels laggy” complaint is impossible to diagnose. So before anything else: install Spark (covered in our essential plugins post) so you can profile when it happens.
Now, symptoms.
Symptom 1: TPS is fine, but movement and blocks lag for players
Diagnosis: It’s not server lag. It’s network lag.
If /tps shows 20.0 and /mspt shows 25ms, the server itself is healthy. The problem is between the server and the players. Common causes:
- The player’s own internet connection
- A regional ISP route issue
- Hosting region too far from the player (Falkenstein → Brazil is ~270ms minimum, fundamentally unfixable)
- The player’s local Wi-Fi
What to do: Have the player run ping <your server ip> from the command line. If they see 200+ ms or packet loss, it’s their network. If they see 50ms and stable pings, look at their client (mods, allocated RAM, FPS — low FPS often gets reported as “lag”).
What NOT to do: Anything to the server. Server-side changes won’t help a network-side problem.
Symptom 2: TPS drops the moment players enter the Nether (or End)
Diagnosis: New-dimension chunk generation.
Each dimension is generated independently. The first time anyone walks into the Nether near new coordinates, the server generates that chunk, then the surrounding chunks for view-distance, then mob spawning, then structures (fortresses, bastions). All on the main tick thread.
What to do: Use Chunky to pre-generate the Nether and End around your usual portal area. /chunky world world_nether, then /chunky radius 2500, then /chunky start. Do the same for world_the_end. Pre-generation is single-threaded but offline — the server burns one CPU core for a few hours, then chunks are on disk and load instantly forever after.
Symptom 3: TPS drops at evening peak hours, recovers overnight
Diagnosis: Player count exceeds your server’s spawnable-entity ceiling.
Player count itself isn’t usually the bottleneck — the entities those players spawn are. Every player has a roughly 128-block sphere where mobs spawn for them. Twenty players in different chunks = potentially 2,000+ active mobs at once, each ticking AI every game tick.
What to do:
- In
paper-world-defaults.yml, lowerentity-tracking-rangeand tunespawn-limitsper-category (monsters, animals, water-creatures, ambient). Halving monster spawn-limit usually drops MSPT 20-30% on busy servers with negligible gameplay impact. - Install FarmLimiter or ClearLag with conservative settings. Skip if you can — they’re a last resort because they affect gameplay.
- Check whether anyone built a giant mob farm — these can spawn thousands of entities in a small chunk and tank TPS even with low player count.
Symptom 4: TPS drops at random moments unrelated to players
Diagnosis: Scheduled task or external pressure.
Look for a pattern. Does it happen every 5 minutes? That’s a backup. Every hour? A scheduled /save-all? Once a day at the same time? A cron-scheduled /restart or world-backup task.
What to do:
- Check your Schedules tab in the manage page for any tasks that fire on a regular interval
- Check
/spark profilerduring a lag spike — it’ll show you exactly what’s running - Disable plugins one by one if Spark points at a specific one
- Disk I/O during backups can cause spike lag — particularly on systems with shared storage. Run backups during off-peak hours
Symptom 5: TPS is fine, then drops gradually over hours/days, recovers only on restart
Diagnosis: Memory leak — usually a chunk leak from a plugin holding chunk references.
This is the worst kind of lag because it builds invisibly. Memory usage creeps up, garbage collection pauses get longer, eventually GC takes 2 seconds and the server stutters.
What to do:
- Watch the live RAM sparkline on the Console tab of your server’s manage page for a few days. If memory usage climbs steadily and never drops after
/save-all, you have a leak. - Schedule a daily restart (via the Schedules tab) at off-peak hours. 24-hour uptime is usually fine; 7-day uptime starts surfacing leaks.
- Update every plugin to the latest version. Most chunk leaks get fixed within a release or two of being reported.
- Run Spark heap profiler (
/spark heapsummary) — it’ll show you what’s consuming memory.
Symptom 6: A single command or block-break causes a 2-second freeze
Diagnosis: A heavy synchronous plugin operation. Almost always WorldEdit, a large region check, or a save operation.
What to do:
- If it’s WorldEdit, that’s expected on huge selections. Use
//perfto see how long an operation takes. - If it’s a plugin’s block listener, run
/spark profilerduring the freeze and look at the flame graph - Look for plugins that hook into BlockBreak/BlockPlace events — these run on the main thread for every interaction
Symptom 7: TPS drops the moment a specific player joins
Diagnosis: That player’s render distance + a chunk-heavy area. Sometimes a permissions check that runs on join.
What to do:
- Ask the player to lower their client-side render distance temporarily
- Lower the server’s
view-distanceandsimulation-distanceinserver.properties. View-distance of 8 (default 10) is barely noticeable to players, can cut MSPT in half - If only this one player triggers it, check what’s in the chunks they’re entering. Massive auto-farms, large redstone contraptions, beacon arrays
Symptom 8: MSPT max spikes to 200+ briefly, average is fine
Diagnosis: Garbage collection pause.
Default GC settings work for small servers but cause stop-the-world pauses on larger ones. The fix is well-documented and has been the same for years: switch to Aikar’s flags (G1GC with tuned parameters specific to Minecraft’s allocation pattern).
What to do: Replace your server startup arguments with Aikar’s recommended flags. We use them by default for Witchly Minecraft servers, but if you’ve customised your startup or your modded server uses a different egg, double-check. The full flag list is at flags.sh (aikars.co/mcflags.html for the canonical reference).
Symptom 9: TPS drops the instant a new plugin is loaded
Diagnosis: The new plugin.
This is the easiest one to diagnose and the one people most commonly resist diagnosing.
What to do: Remove the plugin. If TPS returns to 20, it was the plugin. Then either pick a better-maintained alternative, file a bug report with the author, or live with it.
What to do when none of these fit
When nothing in this list matches your symptom, profile blindly:
- Trigger the lag
- Run
/spark profiler --timeout 30immediately - Wait 30 seconds, then click the resulting link
- Look at the flame graph for any plugin function consuming an unusual percentage of tick time
Spark will find what’s slow even when you can’t describe what’s wrong. If the flame graph points at vanilla Minecraft itself (e.g., EntityLiving.tick), you’re hitting a content limit — too many entities, too many chunks loaded, too much redstone — and the fix is gameplay-side, not server-side.
A note on Witchly specifics
The free tier and Elite tier both run the same Minecraft software (Paper by default), the same JVM, and the same defaults. The difference is hardware — Elite servers run on dedicated CPU cores without contention from other servers. Free-tier servers share CPU time with other free-tier instances on the same node, which means a noisy neighbour can occasionally affect your TPS.
If your TPS pattern looks like “fine for an hour, drops for ten minutes, fine again” and nothing on your server changed during that window, it’s possibly contention. The fix is either to upgrade to Elite or accept the variance. The good news: most free-tier nodes run well below capacity, so this is rare in practice.
You can monitor your live CPU and memory on the Console tab of each server’s manage page — if you see your CPU usage maxed during a lag period, the bottleneck is your server. If CPU is at 30% and TPS still dropped, it’s something else (Aikar’s flags / GC, network, or external).
Wrapping up
Lag has shape. The shape tells you the cause. Once you’ve matched a symptom to its category, you’ve already done 80% of the diagnostic work — the actual fix is usually a single config change or a single plugin to remove.
For the broader optimization checklist (after you’ve diagnosed the cause):
- Optimizing your Minecraft server for maximum performance — the systematic optimization guide
- 15 essential Paper plugins — including Spark and Chunky, both crucial for diagnosis
- Understanding server resources — what RAM, CPU, and disk actually mean for Minecraft
- Java versions for Minecraft hosting — version mismatches that look like lag but aren’t