Comprendre et corriger les chutes de TPS sur un serveur Minecraft
Par Benjamin D. · PDG
· Mis à jour le September 18, 2026 · Lecture 11 min
Contents
Minecraft server TPS is the first number to look at when a world starts feeling sluggish: it tells you whether the problem lives in the game loop, in the network path, or on the player's machine. This guide explains how ticks are scheduled, how to read tick timings from the console, and which workloads actually drag a running world below 20 ticks per second.
How Minecraft server TPS works under the hood
The Java Edition game loop is fixed: 20 ticks per second, one tick every 50 milliseconds. Inside that 50 ms window, the main thread has to process everything that makes the world move:
- entity AI, pathfinding and movement (mobs, items, projectiles, minecarts, boats)
- block ticks: crops, fire spread, fluids, leaf decay, random ticks
- redstone updates and hopper transfers
- chunk loading, chunk generation and chunk saving
- player packet handling, block placement, inventory actions
- scheduled plugin or mod tasks running synchronously on the main thread
If all of that completes in 12 ms, the thread sleeps for the remaining 38 ms and TPS stays at 20. Java Edition never runs faster than 20 TPS to compensate — the ceiling is hard. If a tick takes 70 ms, the world simply falls behind: 14 ticks per second instead of 20. In game, that means mobs move in slow motion, hoppers move items 30% slower, furnaces smelt slower, the day cycle stretches, and player movement gets rubber-banded by the anti-cheat because positions arrive late.
TPS vs MSPT: the metric that actually matters
TPS is a derived, capped value. MSPT — milliseconds per tick — is the raw measurement, and it's far more useful. A world sitting at 20 TPS with 45 ms MSPT is one mob farm away from collapsing; a world at 20 TPS with 8 ms MSPT has real headroom. Watch MSPT, not TPS, if you want warning before the drop happens.
| MSPT | Resulting TPS | Interpretation |
|---|---|---|
| 0–20 ms | 20 | Comfortable headroom |
| 20–40 ms | 20 | Loaded but stable; spikes will be felt |
| 40–50 ms | ~20 | Saturated main thread, no margin left |
| 50–100 ms | 10–20 | Visible slow motion, delayed block breaking |
| >100 ms | <10 | Unplayable, timeouts likely |
Tick lag is not network lag
Three different problems get called "lag", and mixing them up wastes hours:
- Low TPS: the world itself is slow. Everyone experiences it identically, entities stutter, and MSPT is high.
- High ping: packets take too long to travel. Blocks break with delay but mobs move normally, and MSPT stays low.
- Low client FPS: only one player is affected, usually with high render distance or shaders.
Because the Minecraft main thread cannot be split across cores, single-thread frequency sets the hard ceiling for tick processing. Extra cores help with chunk I/O, garbage collection threads and Paper's async work, but a high-frequency Ryzen with NVMe storage is what keeps MSPT low on a populated world — the technical details of each configuration are documented on the Minecraft server hosting page. You can also see how similar constraints apply to other titles across All our game servers.
Reading tick timings from your console
Open the live console in your Fly-Serv panel and gather numbers before changing anything. Guessing is how people end up cutting view distance to 3 for no reason.
Built-in commands
# Paper / Spigot
/tps
/mspt
# Vanilla 1.20.3 and newer
/tick query
# Forge
/forge tps
# Paper entity census, per world and per chunk
/paper entity list
/tps returns three averages — 1 minute, 5 minutes, 15 minutes. If the 1-minute figure is 14 and the 15-minute figure is 19.8, you are looking at a periodic spike, not a permanent load: something fires on a schedule (a chunk-saving pass, a scripted event, an automatic world save, a regeneration task).
/mspt on Paper shows minimum, median and 95th percentile over 5 s, 10 s and 1 min. The 95th percentile is where the truth hides: a median of 18 ms with a 95th percentile of 140 ms means ticks are fine most of the time and catastrophic occasionally. Averages alone hide that entirely.
Profiling with spark
Spark is the standard profiler for Paper, Fabric and Forge, and it attributes main-thread time to concrete methods, plugins and worlds.
# Run a 5-minute sample while the lag is happening
/spark profiler start --timeout 300 --thread *
# Quick snapshot of TPS, MSPT, CPU and memory
/spark tps
/spark healthreport
# Per-tick entity and chunk counts
/spark activity
When the sample finishes, spark returns a web link with a call tree. Read it from the main thread downwards and look for the widest branches: ServerLevel.tick split between entity ticking, block entity ticking and chunk work. If 40% of main-thread time sits under a single plugin's scheduler task, you have your answer without touching a single config value.
The vanilla debug profiler
/debug start
# wait 60 seconds under load
/debug stop
This writes a profile report into the debug/ folder, reachable from the file manager in the panel. It's less readable than spark but works on a pure vanilla jar with no extra mods installed.
What actually causes tick drops
Chunk loading and world generation
Generating a brand new chunk is one of the heaviest single operations the main thread performs. A player flying with an elytra across ungenerated terrain, a nether portal chain, or five players exploring in five directions will all produce long ticks. The signature in spark is time spent under ChunkMap, ChunkGenerator or ThreadedLevelLightEngine.
The fix is pre-generation plus a world border. Generate the terrain once, offline, so exploration only reads chunks from NVMe instead of building them:
/chunky world world
/chunky center 0 0
/chunky radius 5000
/chunky start
# then lock the map
/worldborder center 0 0
/worldborder set 10000
Also check for accidental force-loaded chunks left over from datapacks or old builds:
/forceload query
/forceload remove all
Entity count and entity type
Entities are usually the number one line in a lag profile on a survival world. Not all of them weigh the same: item entities and experience orbs are cheap individually but arrive in thousands, villagers are expensive because of their brain and gossip logic, and mobs with pathfinding across loaded chunks are the worst offenders.
Run /paper entity list and look for chunks holding hundreds of entities. Typical culprits: an unlit mob farm with no kill mechanism, a villager breeder gone wrong, dropped items piling up on an AFK sorting system, minecart loops, and armor stands from a decorative build script.
# spigot.yml — reduce how far entities are ticked and tracked
world-settings:
default:
entity-activation-range:
animals: 16
monsters: 24
raiders: 48
misc: 8
entity-tracking-range:
players: 48
animals: 48
monsters: 48
misc: 32
merge-radius:
item: 3.5
exp: 4.0
# paper-world-defaults.yml — cap what a single chunk can store
chunks:
entity-per-chunk-save-limit:
experience_orb: 50
arrow: 16
snowball: 8
item: 150
Redstone and hoppers
Redstone ticks are synchronous and can cascade. A clock feeding a large update chain, an observer loop, or a stack of 300 hoppers checking for items every tick will show up in spark under HopperBlockEntity.tickHopper or the redstone wire handler. Slowing hopper polling has a much smaller gameplay impact than most admins expect:
# spigot.yml
ticks-per:
hopper-transfer: 8
hopper-check: 8
# paper-world-defaults.yml
hopper:
disable-move-event: true
ignore-occluding-blocks: true
disable-move-event is often the single biggest win on a plugin-heavy world, because it stops firing an event for every item movement to every listening plugin.
View distance and simulation distance
These two values are frequently confused. view-distance controls how many chunks are sent to clients; simulation-distance controls how many chunks are actually ticked. Lowering simulation distance reduces entity and block ticking; lowering view distance reduces network and memory pressure but keeps the visual range short.
# server.properties
view-distance=8
simulation-distance=5
max-tick-time=60000
network-compression-threshold=256
sync-chunk-writes=false
On a 40-player survival world, dropping simulation distance from 10 to 5 removes roughly three quarters of the ticked area per player. Keep view distance a little higher so the map still looks normal.
Single-thread speed and garbage collection pauses
When MSPT spikes are short, regular and affect everything at once, suspect the JVM rather than gameplay. A stop-the-world GC pause of 300 ms is six lost ticks. Use a fixed heap and G1 tuning:
java -Xms6G -Xmx6G \
-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 \
-XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC \
-XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M \
-XX:G1ReservePercent=20 -XX:InitiatingHeapOccupancyPercent=15 \
-XX:SurvivorRatio=32 -XX:MaxTenuringThreshold=1 \
-jar paper.jar nogui
Two rules: -Xms equals -Xmx so the heap never resizes mid-tick, and never allocate the entire machine's memory to the heap — the JVM needs space outside it for metaspace, threads and network buffers. Over-allocating RAM makes GC pauses longer, not shorter.
Plugins, mods and modpacks
Common patterns that eat ticks: a repeating task running every tick instead of every second, synchronous database queries on the main thread, chunk lookups triggered on player move events, dynamic map rendering without throttling, and world-edit style operations applied without a queue. Paper's watchdog will name the offender when it dumps a stack trace after a very long tick — check the console log for --- DO NOT REPORT THIS TO PAPER --- and read the frames below it.
For modded worlds, chunk-loading machines, item pipes and quarries are the usual cause. Many mods expose their own throttling values; the official configuration reference for Paper is worth keeping open while you tune (Source).
Keeping Minecraft server TPS stable over time
A repeatable tuning method
- Take a snapshot before touching anything:
/spark healthreportand/mspt. - Save a copy of the world through the automatic backup feature in the panel before editing any YAML file.
- Change one value at a time, restart, and let the world run 15 minutes under real player load.
- Measure again. If MSPT did not move, revert the change instead of stacking configs you no longer understand.
- Document what you changed and why, in a text file next to your configs.
Operational habits that protect tick rate
- Scheduled restarts: a nightly restart clears leaked entities and resets heap fragmentation. Automate it from the panel's scheduler rather than doing it manually.
- Entity audits: run
/paper entity listweekly and talk to the players who built whatever is holding 900 entities in one chunk. - Chunk pre-generation after every border expansion, never during peak hours.
- Version discipline: keep the server jar and plugins updated; performance regressions get patched, and outdated builds carry known tick-heavy bugs.
- Access control: a solid RCON password, a whitelist on private worlds, sub-users in the panel instead of shared credentials, and regular restore tests on your backups. Volumetric attacks are handled upstream by the anti-DDoS layer, but application-level abuse — spam bots joining, lag machines built in-game — is still your job to watch.
When the world is just too big for the machine
If MSPT sits at 45 ms with a clean profile, no entity outliers and modest distances, you have reached the limit of what one main thread can push. At that point the options are architectural: split gameplay across several worlds or several instances with a proxy, trim the modpack, or move to hardware with higher single-thread frequency. More RAM will not add ticks. More cores will not add ticks either — frequency does. Other guides on the Fly-Serv blog cover proxy setups and world splitting in more detail.
Wrapping up
Tick drops are never mysterious once you measure instead of guess. Read MSPT and its 95th percentile, profile with spark while the problem is live, then attack the widest branch: chunk generation, entity density, hopper and redstone chains, or GC pauses. Change one value, measure again, keep notes. That loop turns a stuttering world into a smooth one in an afternoon.
FAQ
Why does /tps show 20 while my players still complain about lag?Because the world is ticking normally and the delay is elsewhere. Ask players to press F3 and check their ping and FPS. High ping with low MSPT points to the network path or their connection; low FPS with normal ping is client-side (render distance, shaders, GPU). Only high MSPT means the game loop itself is behind.
Which entities should I cut first when MSPT climbs?Start with item entities and experience orbs by raising merge radius and per-chunk save limits, then villagers, then any mob farm without a kill mechanism. Run /paper entity list to find the worst chunk, teleport there, and inspect the build. Reducing entity activation range for animals and monsters usually recovers several milliseconds per tick immediately.
Almost never. Ticks are limited by single-thread CPU time, not memory volume. An oversized heap makes garbage collection pauses longer, which adds tick spikes. Set -Xms equal to -Xmx, leave headroom outside the heap for the JVM, and spend your effort on entity counts, simulation distance and chunk pre-generation instead.