A tick is a budget: fifty milliseconds to simulate everything in the world once. Twenty ticks a second is full speed, and anything less means the work did not fit in the time available. So the useful question is never "why is my server lagging" - it is "what is spending the fifty milliseconds", and there is a tool that answers it exactly, by plugin and by method, in about ten minutes.
This post is the order that works: understand the two numbers, rule out the kinds of lag that are not TPS at all, measure instead of guessing, then apply the fixes from cheapest to most expensive. Buying a bigger plan is on that list, and it is last for a reason.
TPS, MSPT, and which one to watch#
The server runs a loop. Each pass through it advances the world by one tick and then sleeps until fifty milliseconds have elapsed. If the pass took longer than fifty milliseconds there is no sleep, the next tick starts late, and the count of ticks completed in the last second falls below twenty.
That gives two numbers, and they are not equally useful:
- TPS is ticks per second, capped at 20. Paper's
tpsprints averages over one, five and fifteen minutes. It is a lagging indicator - by the time it moves, the problem has been happening for a while. - MSPT is milliseconds per tick, the real measurement. Paper's
msptprints the average, minimum and maximum over the last five seconds, ten seconds and minute.
A server showing 20.0 TPS and 47 MSPT is one mob farm away from trouble. A server showing 20.0 TPS and 12 MSPT has room to grow. TPS cannot tell those apart; MSPT can. Watch MSPT, and treat anything consistently over about 35 as a warning even though nothing is visibly wrong yet.
When MSPT does go past 50, everything tied to game time slows down together: crops grow more slowly, furnaces smelt more slowly, mobs move in steps. Players describe it as rubber-banding or as blocks reappearing after they break them, which is the client predicting a world that the server has not caught up to. What tick rate actually means covers why different games handle that differently.
Lag that is not TPS at all#
Before spending an evening on entity limits, check that TPS is the problem. Four common complaints are not:
- Client frame rate. One person stuttering while everyone else is fine is a graphics problem, usually render distance or shaders.
tpsin the console settles it in one line. - Ping and packet loss. High latency looks like delay between an action and its result, but the world keeps moving smoothly. If MSPT is healthy and one region of the world's players are all complaining, it is the network - latency, jitter and packet loss explains how to tell which of the three you have.
- Chunk loading on the client. Terrain appearing slowly as a player flies is often bandwidth and client-side, not server ticks.
- A saturated CPU share. A container throttled to its allocation is slow rather than broken. On RE:NODE the CPU limit is a hard throttle to the share you bought, one container per server, and a server sitting at 100% is never grounds for suspension - but it will not go faster, either. Shared CPU and noisy neighbours is the wider version of this.
What spends the fifty milliseconds#
Inside one tick, the server ticks block entities, then entities, then handles chunk loading, then runs whatever plugins scheduled work for this tick, and periodically saves. Each of those has a characteristic failure mode.
| Spender | What it looks like | Typical cause |
|---|---|---|
| Entities | MSPT high all the time, worse near one place | A mob farm with no kill chamber, dropped items, boats |
| Block entities | Steady baseline that grows over months | Hopper chains, large item-sorting systems |
| Chunk generation | Spikes when someone explores | No pre-generation, no world border |
| Redstone | Spikes tied to one build | A clock, an observer loop, a flying machine left running |
| Plugin tasks | Regular spikes on a timer | A task running every tick, or a query on the main thread |
| Autosave | A spike every few minutes | Large world, slow disk, too many chunks per save |
| Garbage collection | Random freezes, MSPT max far above average | Heap too small, or far too large |
Two of those deserve numbers. Entities are the usual answer: a mob farm holding two thousand hostile mobs costs AI, pathfinding and collision checks on every single tick, and dropped items are worse per entity than most people expect because they merge, despawn and check for hoppers below them. And chunk generation is the most expensive single operation the server performs - one player on an elytra demands roughly forty new chunks a second, which is why world borders and pre-generation is on the fix list below rather than in a separate universe of advice.
Measure it, do not guess#
A profiler names the plugin and the method. Ten minutes of profiling beats a week of removing things one at a time, and it produces something you can show the plugin author rather than an opinion about their work.
The tool is spark. Recent Paper builds ship with it; otherwise it is a jar in plugins/. Run spark in the console to see which you have. Five commands cover almost everything:
spark tpsspark healthreportspark profiler start --timeout 300spark profiler start --timeout 300 --only-ticks-over 100spark heapsummaryEach of those answers a different question, and they are worth running in roughly that order.
spark tpsgives TPS and MSPT percentiles together, plus process CPU use, which distinguishes "the server is busy" from "the machine is busy".spark healthreportis the one-shot overview: TPS, MSPT, memory, disk, and per-world counts of entities, chunks and block entities. Start here.spark profiler start --timeout 300samples for five minutes and then posts a link to a viewer. Let it run while the server is actually misbehaving; a profile of a quiet server tells you nothing.--only-ticks-over 100is the spike-hunting version: it records only the ticks that took longer than 100 ms, so the report is not drowned in normal work.spark heapsummarylists what is occupying memory by class, which is how a leak gets found.
In the viewer, sort by self time and read down until you see something that is not the server's own code. A plugin's package name near the top with a large self time is your answer. If the top entries are all entity ticking or chunk work, the answer is not a plugin and the fixes below apply. Reading a spark report goes through a real one line by line.
Two Paper commands are worth knowing alongside it. paper entity list prints entity counts grouped by chunk, so you can find the exact coordinates of the problem farm, and paper mobcaps shows how close each spawn category is to its limit.
Fixes, cheapest first#
- Clear the entity backlog and cap what created it. Find it with
paper entity list, then deal with the source.kill @e[type=item]clears dropped items; never plainkill @e, which takes item frames, paintings, armour stands and anything else standing still. - Reduce view and simulation distance by one or two. Almost nobody notices; the server notices immediately. This is the highest-value single change on most servers.
- Tighten entity activation ranges and mob caps. Mobs outside the activation range stop running AI without disappearing, which is a large saving for a small change in behaviour.
- Deal with hoppers and redstone. Both have Paper settings that reduce their cost without changing what players can build.
- Remove or replace the plugin the profiler named. If it is a feature you need, check for a newer build first - performance bugs get fixed.
- Set a world border and pre-generate inside it, so exploration stops generating terrain during peak hours.
- Size the heap properly. More memory is not faster; a heap that is too large makes garbage-collection pauses longer. Leave the container about 1 GB outside the heap for the JVM itself and the operating system. JVM flags and Java versions has the flags, and how much RAM a Minecraft server needs has the sizing.
- Then, and only then, consider a faster machine. Minecraft's tick loop is largely single-threaded, so what helps is a faster core, not more of them - CPU vs RAM for game servers is the argument in full, and when to upgrade your plan is how to know you have run out of software fixes.
The settings that matter, with their defaults#
| Setting | File | Default | What it does |
|---|---|---|---|
view-distance | server.properties | 10 | Chunks sent to each client. Try 8 |
simulation-distance | server.properties | 10 | Chunks that actually tick. Try 6 |
entity-broadcast-range-percentage | server.properties | 100 | How far entity updates are sent |
spawn-limits.monsters | bukkit.yml | 70 | Hostile mobs per player or per world |
ticks-per.autosave | bukkit.yml | 6000 | Ticks between world saves |
chunk-gc.period-in-ticks | bukkit.yml | 600 | How often unused chunks are unloaded |
entity-activation-range | spigot.yml | 32 / 32 / 16 | Distance at which entities run AI |
merge-radius | spigot.yml | item 2.5 | How aggressively dropped items merge |
max-entity-collisions | paper-world-defaults.yml | 8 | Collision checks per entity per tick |
hopper.disable-move-event | paper-world-defaults.yml | false | Skips an event most servers never use |
redstone-implementation | paper-world-defaults.yml | VANILLA | ALTERNATE_CURRENT is much cheaper |
maxEntityCramming | gamerule | 24 | Entities in one block before damage |
randomTickSpeed | gamerule | 3 | Crop growth, fire spread, leaf decay |
The two distance settings are worth being precise about, because people change the wrong one. view-distance is how many chunks are sent to each client - it costs bandwidth and memory, and dropping it is what makes joining faster. simulation-distance is how many chunks around each player actually tick, and it is the one that costs CPU. Dropping simulation distance too far stops farms working when their owner is standing at the controls, so 5 or 6 is a floor for most survival servers rather than a target.
On a modern Paper build, per-player mob spawning is the default, which means the mob cap is applied around each player rather than across the whole world. That behaves much better with a spread-out community and is worth confirming before you start lowering caps. The rest of these files, key by key, is the Paper optimisation guide.
A worked example#
A survival server on 6 GB, eighteen regulars, four months old. Complaints about blocks not breaking. tps showed 13.4 over one minute; mspt showed an average of 74 with a maximum over 300.
spark healthreport reported around 11,000 entities in the overworld, which for eighteen players is four or five times what it should be. paper entity list put 2,100 of them in two chunks: a zombie farm with an overflowing collection area, plus every item it had ever dropped, because a hopper had been broken weeks earlier and nobody noticed.
Fixing the farm took ten minutes and brought MSPT to 41 - better, still not good. A five-minute profile with --only-ticks-over 100 then showed the remaining spikes were chunk loading, not entities: two players were mapping the outer world and generating terrain constantly. view-distance went from 10 to 8, simulation-distance from 10 to 6, and a border was set at 6,000 with an overnight Chunky run inside it.
The following evening the same eighteen players sat at 19.9 TPS and 28 MSPT. Nothing was bought, nothing was removed, and the only plugin change was none at all - which is the usual outcome when the profiler gets to speak before the chequebook does.
Watching it so you notice before your players do#
The panel's graphs for memory, CPU and disk sit next to the console for a reason: a spike is only meaningful when you can see what the server was printing at the time. Reading a server load graph covers what the shapes mean, and monitoring that tells you something is about not building an alert that cries wolf.
A few habits are worth more than a dashboard:
- Run
spark healthreportonce a week and keep the numbers. Entity counts drifting upward over a month is the earliest warning there is. - Restart on a schedule. It does not fix a leak, but it caps the damage one does and keeps chunk state tidy - restart schedules that help has the timing.
- Profile while the server is bad, not after it recovers. A saved five-minute profile from the worst evening of the month is worth more than ten taken on a quiet Tuesday.
- If the server keeps stopping rather than slowing down, that is a different problem: memory. At the memory limit the container is stopped and restarted clean rather than left to swap, and repeated restarts raise a warning and an automatic ticket. Why your game server keeps restarting is the post for that.
FAQ#
What is a good MSPT?
Under 30 is comfortable, 30 to 45 is a server with no headroom left, and anything over 50 is visible to players because ticks are now taking longer than the tick is allowed to. The average matters less than the maximum - regular spikes to 200 ms feel worse than a steady 40.
Does more RAM fix low TPS?
Almost never. Memory fixes crashes and long garbage-collection pauses; it does nothing for entity and chunk work, which is CPU. An oversized heap can make things worse by lengthening each collection. Check MSPT against memory use before spending anything.
Will fewer plugins help?
Only if the profiler names one. Twenty well-written plugins can cost less than one that schedules a task every tick. Remove things because a report points at them, not because the list feels long.
Why is TPS 20 when the server still feels laggy?
Because TPS is capped at 20 and hides everything below the fifty-millisecond line. Look at MSPT, or at the maximum rather than the average - a server at 20 TPS with occasional 300 ms ticks feels exactly as bad as players say.
Does a restart fix TPS?
It clears entity backlogs, unloads chunks and resets a leaking heap, so it usually helps for a while. If TPS degrades predictably over a few days, a nightly restart is a reasonable patch, but the thing that degrades is still there and worth finding.
Can a single player cause low TPS?
Easily. One person flying into ungenerated terrain, or standing inside a farm they built, can hold the whole server down. That is one of the more useful things paper entity list and a profile taken at the time will show you.




Comments
Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.