How To Reduce Minecraft Server Lag (Complete Guide)

How to Reduce Minecraft Server Lag (Complete Guide)

Quick answer: most Minecraft server lag comes from three things, in this order. Wrong server jar (Vanilla or Spigot instead of Paper), too many entities (mob farms, item drops, villager breeders), and view distance set too high for your CPU. Fix those three and 80% of servers stop lagging. If you've done all three and it's still bad, you need to actually profile the server with Spark instead of guessing.

The rest of this guide walks through diagnosis first, then the fixes in order of impact.

First, figure out what kind of "lag" you actually have

People say "my server is lagging" to describe three completely different problems, and the fixes for each are different.

TPS lag is when the server can't keep up with game logic. Blocks break with a delay, mobs walk in place, hoppers stop moving items. Normal TPS is 20. Anything below 19 is starting to be a problem.

MSPT (milliseconds per tick) is the more useful number. A tick has to finish in 50ms to maintain 20 TPS. If your average MSPT sits at 60, you're actually at 16-17 TPS. MSPT tells you how close to the edge you are, even when TPS still reads a clean 20.

Latency lag is network. High ping, rubber-banding, hits not registering. Has nothing to do with TPS. Your server can run at 20 TPS while a player has 300ms ping and feels like everything is broken.

Client lag is your own framerate. If your FPS is 30, the server is probably fine. Try a lower render distance or turn off shaders before blaming the host.

Run /tps on Paper or Purpur, /forge tps on Forge, or /spark tps on Fabric (if you have the Spark mod). That tells you what you're dealing with.

The one tool you actually need: Spark

Install Spark. It works on Paper, Fabric, Forge, NeoForge, and basically everything. It replaced the old Timings system (which Paper removed in 1.20.5) and gives you a flame graph showing where the server is spending CPU time.

Run a 60-second profile while the lag is happening:

/spark profiler --timeout 60

You'll get a link to a flame graph. Look at the widest blocks. That's where time is going. If EntityTick is eating 40% of your tick budget, you have an entity problem (probably a mob farm or 10,000 dropped items somewhere). If a plugin name is eating 25%, that plugin is the issue.

For memory issues, run:

/spark heapsummary

This shows what's using your RAM. If you see 50,000 instances of net.minecraft.world.entity.item.ItemEntity, someone has built a cobblestone generator without a chest.

Don't skip this step. Most lag advice online is generic. Most lag problems are specific. Spark turns "I don't know why it's slow" into "this exact plugin is doing this exact thing."

Fix 1: Run Paper

If you're on Vanilla, Spigot, or anything older, switch to Paper. This is the single biggest performance win for almost every survival or SMP server, and you don't lose anything because Paper runs all Bukkit and Spigot plugins.

For modded servers, the equivalent move is installing performance mods. On Fabric: Lithium, Starlight, FerriteCore, C2ME. On Forge or NeoForge: Embeddium, Rubidium, and Canary if it's available for your version.

Fix 2: Right-size your RAM

The biggest myth in Minecraft hosting is that more RAM means less lag. It doesn't. Once your server has enough RAM to load its working set, extra memory just means longer garbage collection pauses, and those pauses show up as periodic lag spikes.

Rough guide for Paper:

  • 1-5 players, no mods: 2 GB
  • 5-20 players: 4-6 GB
  • 20-50 players: 6-10 GB
  • Modded: match the pack's recommended RAM, plus 2 GB

Fix 3: Use proper JVM startup flags

Java's default garbage collector is bad for Minecraft. Aikar's flags are the de facto standard, tuned for low-pause G1GC behavior. For a 6 GB server, your start command should look like this:

java -Xms6G -Xmx6G \
  -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 \
  -jar paper.jar nogui

Two things people miss: set Xms and Xmx to the same value (avoids heap resizing pauses), and don't paste these into a 1 GB server because the region sizes assume at least 4 GB.

On Server Heron, the Pelican panel sets these flags automatically when you pick the Paper egg, so you don't have to manage the command yourself.

Fix 4: Drop your view distance

Default view distance is 10 chunks. For most servers, this is too high. Each player loads roughly (2*view_distance + 1)^2 = 441 chunks at view distance 10. Drop to 8 and you're at 289 chunks. Drop to 6 and you're at 169. Almost 3x fewer chunks loaded.

In server.properties:

view-distance=8
simulation-distance=6

Simulation distance is the more important number. It controls how far away mobs tick, redstone runs, and crops grow. Set it lower than view distance. Players won't visually notice the difference between 10 and 6 sim distance, but your CPU will.

If players complain they can't see far enough, push view distance back up and keep simulation distance low. Most people don't realize these are separate settings.

Fix 5: Pre-generate the world

Generating new chunks is the single most expensive thing a Minecraft server does. The fix is to generate them before anyone is online.

Install Chunky (free Paper plugin). In console:

/chunky radius 5000
/chunky start

That pre-generates a 5000-block radius around spawn. Set a matching world border:

/worldborder set 10000

(World border uses diameter, Chunky uses radius. 5000 radius = 10000 diameter.)

Once Chunky finishes, no new chunks generate when players explore inside the border. The classic "server stutters when I walk somewhere new" complaint just disappears.

Fix 6: Limit mobs

Default mob caps are way too high for modern servers. Edit bukkit.yml:

spawn-limits:
  monsters: 35
  animals: 8
  water-animals: 3
  water-ambient: 5
  ambient: 1
ticks-per:
  monster-spawns: 10
  animal-spawns: 400
  water-spawns: 1
  water-ambient-spawns: 1
  ambient-spawns: 1

Default monster cap is 70. Cutting it to 35 still gives you plenty of hostile mobs for gameplay and roughly halves entity tick cost.

In paper-world-defaults.yml you can also tune entity activation range:

entity-activation-range:
  animals: 16
  monsters: 24
  raiders: 48
  misc: 8

Lower numbers mean entities outside that range don't tick. They still exist, they just don't path or attack until a player walks close. Players never notice, your TPS does.

Fix 7: Audit your plugins

Every plugin has a cost. Run /spark profiler during peak load and check the flame graph for plugin names. Usual offenders:

  • Anti-cheats that scan every player movement (NoCheatPlus, Matrix, AAC)
  • Economy plugins hammering a database on every transaction
  • Hologram or floating-text plugins
  • ChatControl-style plugins running heavy regex on every chat message
  • Old all-in-one plugins that do 40 things badly

If a plugin sits in the top 3 of your flame graph and you only use one feature of it, find a lighter alternative or remove it.

Fix 8: Network compression

In server.properties:

network-compression-threshold=256

Default is 256. If your players and server are in the same region (low ping), bump this to 512 or set it to -1 to disable compression entirely. Compression eats CPU. Less compression means more bandwidth used but lower CPU cost.

If your players are spread across continents, leave it at 256 or drop to 128.

Fix 9: Pick a host near your players

This one isn't a server software fix, it's geography. If your players are in Europe and your host is in Dallas, every player has 100-150ms baseline ping. Nothing your server does can fix that.

Server Heron hosts on Hetzner Cloud in Europe, so EU players typically see ping well under 30ms. If your community is mostly EU based, hosting in the EU matters more than another 4 GB of RAM.

Quick reference

Symptom Likely cause First thing to try
TPS at 20, MSPT at 45+ One slow thing per tick Spark profiler, find the spike
TPS drops with more players online View / sim distance too high Drop sim distance to 6
Lag spikes every 30-60 seconds GC pauses Lower RAM or fix JVM flags
Stutters when walking into new chunks Chunk generation Run Chunky, set world border
Slow at the same hour every day Backup or scheduled task Check cron and plugin schedulers
Mob farms tank TPS Entity count Lower mob caps, use a mob limiter
Modpack feels heavy One specific mod culprit Spark profile, check the mod flame graph

Common errors and what they actually mean

"Can't keep up! Did the system time change, or is the server overloaded?"
The server fell behind by more than 2 seconds in one tick. Once in a while is normal (backup, GC pause). If it's constant, profile it.

"Watchdog has detected a single server tick has taken 60 seconds"
The server is fully frozen. Almost always a plugin deadlock or infinite loop. The console dumps a thread stack when this happens.

"Java heap space" / OutOfMemoryError
You ran out of RAM. Either bump RAM slightly or find the leak with /spark heapsummary. A leak usually means a plugin or mod is holding references it shouldn't.

Players can connect but get kicked with "Internal server error"
Usually a plugin throwing an exception during login. Open logs/latest.log and find the stack trace right after the player's join message.

"Server thread has stopped responding to ticks"
Same as the Watchdog message, just shows up in different places. Same fix.

FAQ

How do I check my server's TPS?
Paper / Purpur: /tps. Forge / NeoForge: /forge tps. Fabric: install the Spark mod, then /spark tps. The three numbers after the colons are TPS averaged over 1, 5, and 15 minutes.

Will more RAM fix my lag?
Usually no. RAM only helps if you're actually running out. At 80% memory use with GC pauses, going from 8 to 12 GB might help. At 40%, more RAM does nothing.

Are more CPU cores worth it?
Mostly no. Minecraft's main game loop is single-threaded. A faster single-core score helps far more than more cores. The exception is large modded servers or Folia, which use multiple cores meaningfully.

My TPS is 20 but players say it's laggy. What gives?
That's network or client-side lag, not server lag. Check player ping (with EssentialsX /ping) and ask them to check their own FPS (F3 in the game). One of those numbers is the actual problem.

How often should I restart my server?
Once every 24 hours is a fine baseline for most servers. It clears accumulated memory pressure and resets any slow leaks. Schedule it in your panel and announce restarts in chat with a plugin like AutoRestart so nobody loses progress.

Should I use Timings or Spark?
Spark. Timings was deprecated in Paper 1.20.5 and Spark works on every server type, including Forge and Fabric where Timings never existed.

Still lagging?

If you've worked through this list and the server still drags, do this: run a 60-second Spark profile during the lag, copy the share link, and post it in our Discord. Almost every lag issue is diagnosable from a single profile, and posting a real one in any Minecraft admin community gets you a faster answer than another 1,000 words of "my server is slow" ever will.