← Blog

Understanding Minecraft Server TPS: Why It Drops and How to Get Back to 20

By Benjamin D. · PDG

· 6 min read

Illustration for the article: Understanding Minecraft Server TPS: Why It Drops and How to Get Back to 20
Contents

Minecraft server TPS measures how many ticks a world processes every second, and the target is always 20. When that counter slips below 20, redstone falls out of sync, mobs teleport instead of walking, and players rubber-band across chunks. The drop almost always traces back to entity load, chunk activity, redstone loops, or plugin code running on the main thread.



How Minecraft server TPS is calculated

Every world runs on a single main thread that executes one tick every 50 milliseconds, which is where the 20 ticks per second target comes from. During each tick the server updates entities, processes block changes, runs scheduled tasks, and answers network packets, a cycle documented on the Minecraft Wiki. If all of that finishes inside the 50ms window, the server holds a steady 20.

Most server software built on the Paper or Spigot project exposes a /tps command reporting rolling averages over one, five and fifteen minutes, for example 20.0, 19.7, 18.9. A drop only visible on the fifteen-minute average points to a one-off event like a world generation spike, while a low one-minute figure signals a bottleneck happening right now.

Hardware sets the ceiling before any configuration change matters, because a tick that takes 60ms on a weak CPU still takes 60ms after tuning entity ranges. Anyone comparing single-thread clock speed for a new build should note that Minecraft server hosting running on high-frequency Ryzen 9 hardware gives the main thread more headroom before it ever nears that 50ms wall.



Entity counts and mob farms driving lag spikes

Every entity, whether a mob, a dropped item, an arrow or a minecart, adds work to the tick loop even when nothing visible is happening. A single AFK mob farm producing thousands of items per hour can push entity counts into the tens of thousands within one session, and each one is checked for movement, damage and despawn timers every tick.

Reducing entity load in spigot.yml

Item stacking is the fastest fix. The merge-radius setting controls how close dropped items need to be before they combine into one stack instead of existing as hundreds of separate entities. Raising it from 2.5 to around 4 blocks cuts entity count in farms without changing actual drop rates.

entity-activation-range:
  animals: 16
  monsters: 24
  raiders: 32
  misc: 8
merge-radius:
  item: 4.0
  exp: 6.0

Entity activation range tells the server which mobs need to run full AI each tick versus simply existing. Lowering animals, monsters and misc ranges means distant entities stay loaded but skip expensive AI calculations until a player actually gets close.



Chunk loading, view distance and world generation load

Since the 1.18 update, view distance and simulation distance are separate values. View distance controls how far terrain renders and loads for players, while simulation distance controls how far entities, redstone and block ticks actually run. Keeping simulation distance lower than view distance is one of the cheapest wins available.

view-distance and simulation-distance in server.properties

view-distance=8
simulation-distance=6
spawn-protection=0

Chunks around the world spawn point stay loaded permanently, even with zero players connected, and plugin-based chunk loaders used for automated farms add more of the same. Pre-generating terrain ahead of time avoids the runtime generation spikes that hit TPS the moment a player rides an elytra into unexplored land. You can queue pre-generation from the same console used for daily administration, whether that runs on a dedicated machine or a Linux VPS running the server jar directly.



Redstone circuits and command block overhead

Fast clock circuits that pulse every tick multiply block updates across an entire farm, and hopper chains checking item transfers every few ticks add real cost once hundreds of them run at once. A build that only needs to fire once per second doesn't need a clock ticking twenty times faster than that.

Command blocks set to repeating and always active run every single tick regardless of whether anything changed, and broad selectors like @e[type=!player] scan the entire loaded entity list on each execution. Scoping selectors with a distance and type filter, and switching clocks to impulse or conditional where possible, removes work the mechanism never actually needed.



Plugins and datapacks that steal tick time

Plugins run on the main thread by default, so a single poorly written command handler blocks every other player's tick while it executes. The spark profiler, run directly from console, shows exactly which plugin or datapack function consumes the most tick time over a sample window.

spark profiler start
spark profiler stop
spark tps

If a panel already includes a live console and file manager built on Pterodactyl VPS, running these commands takes seconds without leaving the browser. Common offenders include economy plugins making synchronous database calls, permission checks re-run on every event, and custom commands that loop over every online player's inventory each tick.

The fix is rarely a full rewrite. Updating to the latest plugin build, replacing abandoned plugins with actively maintained forks, and disabling anything not actually in use, rather than just blocking its commands, removes most of the avoidable main-thread cost.



Configuration changes that restore a stable 20 tick rate

JVM startup flags

The flags passed to the Java process control garbage collection behavior, and a poor GC pattern shows up as a periodic freeze rather than a steady low average. The widely used Aikar flag set keeps garbage collection pauses short and predictable on modern JVMs.

java -Xms8G -Xmx8G -XX:+UseG1GC -XX:+ParallelRefProcEnabled \
-XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions \
-XX:+DisableExplicitGC -jar paper.jar nogui

Software choice

Vanilla Minecraft ticks entities and chunks on a single thread with no additional scheduling logic. Paper and its forks add asynchronous chunk loading, smarter entity tracking and a large number of configurable performance flags in paper-world-defaults.yml, which is why almost every survival community running above a handful of players uses one of them instead of vanilla.

hopper:
  disable-move-event: false
chunks:
  prevent-moving-into-unloaded-chunks: true
entities:
  spawning:
    all-chunks-are-slime-chunks: false

Working through settings in this order, entities first, then chunk and simulation distance, then redstone scope, then plugins, then JVM flags, resolves the vast majority of TPS drops without removing content players actually built.



Conclusion

Fix entity count and simulation distance before touching a single plugin: an unchecked mob farm or a bloated view distance undoes any plugin optimization applied afterward. Profile with spark before guessing, apply Aikar flags once, and move to Paper or a fork of it if the world still runs on vanilla.



FAQ

Does adding more RAM increase Minecraft server TPS?

Not directly. Extra RAM prevents garbage collection stalls and out-of-memory crashes on large worlds with many chunks loaded, but it does not add processing power to the single main thread that actually runs ticks. A server stuck at low TPS with plenty of free RAM has a CPU or code bottleneck, not a memory one.

Why does TPS only drop when one specific player is online?

That usually means the player's location triggers the problem, such as an automated farm near their base, a claimed area with heavy redstone, or a resource-heavy chunk they generated by exploring. Running the spark profiler while that player is connected isolates whether it's their location, their client mods sending unusual packets, or a plugin reacting specifically to their actions.

Is 19 TPS considered bad?

No, 19 out of 20 is barely noticeable during normal play and falls within the range every busy server dips into occasionally. Real problems start once the average holds under roughly 18 for sustained periods, or swings wildly between 20 and 12, since that pattern indicates a recurring bottleneck rather than a brief spike.

Read next

Minecraft server rental

10,000+ 1-click modpacks

from $8.07/mo

Rent my Minecraft server