How to Get 20 TPS on Your Minecraft Server
Learn how to diagnose and fix TPS drops on your Minecraft server with Paper config tuning, entity management, and step-by-step optimization techniques.
What TPS Actually Means and Why 20 Is the Target
TPS stands for ticks per second. Minecraft runs a game loop that tries to complete 20 ticks every second, with each tick lasting 50 milliseconds. During each tick, the server processes mob AI, block updates, scheduled tasks, player actions, chunk loading, weather, redstone, and everything else that makes the world feel alive. When a tick takes longer than 50ms, the server cannot fit 20 of them into a single second and the TPS drops. Players experience this as rubber-banding, delayed block breaks, mobs freezing in place, and items refusing to pick up.
A server sitting at 19.9 TPS is functionally perfect. Nobody will notice the difference between 19.8 and 20.0. The problems start once TPS dips below 18 consistently, and anything below 15 feels genuinely broken. Your goal is not perfection on paper but stability under load, meaning your TPS should stay at or near 20 even when 30 players are online, farms are running, and chunks are generating in the background.
Measuring TPS the Right Way
Before you change anything, you need a baseline. Minecraft includes a built-in /tps command that shows the average TPS over the last 1 minute, 5 minutes, and 15 minutes. This is a decent starting point but it averages out spikes, so a server that drops to 12 TPS every few minutes and recovers can still show 19+ on the 5-minute average.
For real diagnostics, install Spark. Spark gives you tick duration histograms, which show exactly how long individual ticks take. A tick duration that hovers around 35-45ms is fine. One that regularly spikes to 80ms+ is the kind of problem that /tps will underreport. Run /spark tps and pay attention to the 95th percentile tick time, not just the average.
Paper Configs That Affect TPS Most
If you are not running Paper yet, start there. Vanilla and even Spigot leave an enormous amount of performance on the table. See the Paper vs Spigot comparison for details. Paper exposes dozens of config values across three files: paper-global.yml, paper-world-defaults.yml, and spigot.yml. Here are the ones that move the needle most.
simulation-distance and view-distance
These two settings are frequently confused. view-distance controls how many chunks are sent to the client for rendering. simulation-distance controls how many chunks are actually ticked (mobs move, redstone fires, crops grow). The trick is that you can set view-distance higher than simulation-distance to give players a pretty horizon without the server simulating all those extra chunks.
A solid starting point is simulation-distance: 6 and view-distance: 10. If your server has headroom, bump simulation-distance to 8. Going above 10 for simulation-distance is almost never worth it unless you have very few players and beefy hardware.
# paper-world-defaults.yml
simulation-distance: 6
# server.properties
view-distance=10
per-player-mob-spawns
This setting in paper-world-defaults.yml changes mob spawning from a global cap to a per-player cap. With global caps, one player with a massive dark room can eat the entire mob budget and prevent mobs from spawning near anyone else. With per-player spawning enabled, each player gets their own fair share of the mob cap. This also reduces total entity count significantly on servers with 20+ players.
# paper-world-defaults.yml (already true by default on modern Paper)
per-player-mob-spawns: true
Entity spawn limits
Lower the spawn limits in bukkit.yml and tune the spawn-limits section. Vanilla defaults are generous:
# bukkit.yml
spawn-limits:
monsters: 50 # vanilla default is 70
animals: 8 # vanilla default is 10
water-animals: 3 # vanilla default is 5
water-ambient: 10 # vanilla default is 20
water-underground-creature: 3
axolotls: 3
ambient: 1 # bats, basically useless
These numbers are per-player when per-player-mob-spawns is on. Cutting monsters from 70 to 50 shaves a massive amount of entity ticking without players noticing a difference in mob density.
Entity activation range
Spigot's entity-activation-range in spigot.yml controls how close a player needs to be for entities to receive full AI ticking. Entities outside this range only get ticked occasionally, which is one of the biggest TPS savers available:
# spigot.yml
entity-activation-range:
animals: 16
monsters: 24
raiders: 48
misc: 8
water: 8
villagers: 32
flying-monsters: 32
Chunk loading and async operations
Paper handles chunk loading asynchronously by default, but you can control how aggressively it loads chunks for different activities. In paper-global.yml, the chunk-loading section lets you limit concurrent chunk loads. If you see TPS spikes when players are exploring, cap max-concurrent-chunk-loads to a lower number. A value of 4-8 per player is reasonable.
server.properties Settings That Matter
Some performance knobs live in the main server.properties file. These are straightforward but often overlooked:
- view-distance, As discussed, 10 is a good default. See the full server.properties guide for every setting.
- simulation-distance, Set to 6 or 8.
- network-compression-threshold, The default of 256 is fine. Setting it to -1 disables compression, which wastes bandwidth. Setting it too low causes CPU overhead from compressing tiny packets.
- max-tick-time, Set this to -1 on Paper servers. Paper has its own watchdog that is far smarter than the vanilla crash timer.
Common TPS Killers
Config changes only go so far. Most TPS problems come from what is actually running on your server.
Hopper chains
Hoppers are one of the most expensive blocks in the game. Each hopper checks for items above it and tries to push items into the container in front of it every game tick. A chain of 100 hoppers performs 200 inventory checks per tick. Paper has a built-in hopper.disable-move-event setting that prevents firing the InventoryMoveItemEvent for hoppers, which can cut hopper tick cost in half. But the real fix is teaching players to use water streams and dropper chains instead of long hopper lines.
Entity farms with too many mobs
A well-designed mob farm kills mobs quickly. A poorly designed one lets hundreds of entities stack up in a kill chamber, each one consuming AI ticks, pathfinding calculations, and collision checks. Use /spark profiler to check entityTick times. If a specific chunk is eating tick time, teleport there and investigate. Consider setting max-entity-collisions in spigot.yml to 4 (down from the default 8) to reduce the cost of packed entities.
Unoptimized plugins
A single badly written plugin can destroy your TPS. Common offenders include plugins that run synchronous database queries on the main thread, scoreboard plugins that update every tick instead of every second, and region protection plugins that perform expensive lookups on every block break. Use Spark's profiler to identify which plugins are consuming the most tick time. If a plugin consistently shows up in the top 5 of your flame graph, look for alternatives or contact the developer.
Chunk generation
Generating new chunks is CPU-intensive work. When players explore new territory, the server has to generate terrain, decorate it with trees and structures, light it, and then send it to the client. This is the single biggest cause of TPS drops on new servers. The solution is pre-generating your world with Chunky before players log in. A pre-generated world eliminates this entire class of lag.
Step-by-Step Tuning Process
Do not change everything at once. Follow this process:
- Step 1: Install Spark and run a profiler for 10 minutes during normal play. Save the report.
- Step 2: Read the flame graph. Identify whether the main bottleneck is entity ticking, chunk loading, plugin X, or something else.
- Step 3: Apply the relevant config changes from above, one group at a time. Restart the server after each change.
- Step 4: Run another Spark profile under similar conditions (same player count, same activities). Compare the tick durations.
- Step 5: If TPS is still dropping, address the specific killer (remove hoppers, limit farm sizes, replace a slow plugin).
- Step 6: Pre-generate your world to remove chunk generation lag entirely.
- Step 7: Review your JVM flags. Bad garbage collection settings cause periodic TPS spikes even when your configs are otherwise perfect.
Repeat this cycle whenever you add new plugins, expand the world border, or notice TPS starting to slip. Performance tuning is not a one-time task. It is ongoing maintenance, and the servers that run at a smooth 20 TPS are the ones where the admin actually checks Spark regularly.
Need a server that handles all this? Astroworld Hosting runs NVMe SSD, Pterodactyl panel, and DDoS protection on every plan. See all features , plans start at €6.39/mo.