Minecraft server optimisation: paper.yml, spigot.yml and bukkit.yml from scratch
Most Minecraft optimisation guides tell you to paste fifty lines into paper.yml. The trouble is that this file has not existed since 1.19, because Paper split it into two separate files inside the config directory. Below we go through which settings in server.properties, spigot.yml, bukkit.yml and the Paper files actually change performance, what values to put in, and what each change costs you, because every one of them takes something away in return.
The short answer: six changes that do the heavy lifting
If you are only going to change a handful of things, change these. They account for the vast majority of the real gain on a typical plugin server, and their side effects are predictable.
| Setting | File | Default | Recommended | What you gain |
|---|---|---|---|---|
view-distance | server.properties | 10 | 6 to 8 | The single biggest win. Fewer chunks to send and keep in memory. |
simulation-distance | server.properties | 10 | 4 to 6 | Fewer ticking mobs and mechanisms. Usually relieves the CPU more than view-distance does. |
max-entity-collisions | paper-world-defaults.yml | 8 | 2 | A lifesaver on servers with farms and tightly packed mob herds. |
redstone-implementation | paper-world-defaults.yml | VANILLA | ALTERNATE_CURRENT | Far faster redstone with identical behaviour in most builds. |
mob-spawn-range | spigot.yml | 8 | 4 to 6 | Mobs spawn closer to the player, so fewer of them despawn for nothing. |
hopper.disable-move-event | paper-world-defaults.yml | false | true | Removes an enormous number of hopper events from the CPU. Only when no plugin listens for them. |
One change at a time
Before you change anything, measure what actually hurts
Optimising without measuring is guessing. Your server may be choking on a single badly written plugin while you spend a week lowering the view distance and wondering why nothing helps. Three tools tell you almost everything.
- 1
/tps, or whether the server is keeping up at all20 TPS is both healthy and the ceiling, it will never go higher. A drop to 18 is already noticeable, and below 15 the game starts stuttering on every hit and every chest you open. Paper shows three numbers: the average over one, five and fifteen minutes. - 2
/mspt, or how many milliseconds one tick takesThis number matters more than TPS. The server has 50 ms per tick. If you fit into 30 ms, you have headroom. At 45 ms the TPS still reads 20, but you are half a step from dropping, which is exactly why a server only starts lagging once two more players join. - 3
spark, or what is actually eating those milliseconds
Paper retired the old Timings mechanism in favour of spark, and spark is the right tool today. Run/spark profiler startat peak hours, give it a few minutes, stop it and open the report. You get a call tree with plugin names and percentages of time. Without it you are fixing blind.
What such a measurement usually reveals
Where these files actually live (and why paper.yml is gone)
Since Minecraft 1.19 Paper no longer uses a single paper.yml, because its contents were split into config/paper-global.yml for server-wide settings and config/paper-world-defaults.yml for world settings. The migration happens automatically on first start, but every guide written before that change sends you to a place that no longer exists.
| File | What it controls | Still current |
|---|---|---|
server.properties | Game settings from Mojang itself: distances, limits, networking. | Yes, and the two most important settings live here. |
bukkit.yml | Mob spawn limits and how often spawning is attempted. | Yes. Rarely touched, occasionally necessary. |
spigot.yml | Entity tracking ranges, item merging, hoppers, projectile despawn. | Yes. |
paper.yml | The former single configuration file of Paper. | No. Gone since 1.19, stop looking for it. |
config/paper-global.yml | Global things: redstone, IO threads, player auto-save, packet limits. | Yes, one of the two halves of the old paper.yml. |
config/paper-world-defaults.yml | Collisions, mob despawn, tick rates, explosion optimisation, hoppers. | Yes, the other half and the richest source of real gains. |
Per-world settings
paper-world-defaults.yml holds the defaults for every world. If you want different settings for world_nether only, you create a paper-world.yml inside the directory of that world and override the keys you need. In spigot.yml the same job is done by adding the world name next to default under world-settings.server.properties: two settings that matter more than all the rest
If you are going to change exactly one thing on the whole server, lower simulation-distance. It decides how far from a player the server calculates mobs, crop growth, redstone and mechanisms, which means how much work the processor does on every single tick.
view-distance=7
simulation-distance=5
entity-broadcast-range-percentage=75
network-compression-threshold=256
sync-chunk-writes=false
max-tick-time=60000view-distanceis the radius in chunks the server sends to the client. Going from 10 to 7 cuts the number of chunks per player by nearly half. Players mostly notice it in long-distance views, so on a survival server 7 is practically imperceptible, while on a server built around scenic maps it is rather more visible.simulation-distanceis the radius in which anything happens at all. A value of 5 means a farm six chunks from the player stops. For most servers that is a feature, but for a technical server with AFK farms it is a serious mechanical change you need to announce.entity-broadcast-range-percentagescales the distance from which a client receives entity updates. 75 percent cuts network traffic and client-side work, which helps most on servers with a crowd at spawn.sync-chunk-writes=falselets chunks be written asynchronously and removes the noticeable stutter on autosave. The risk of losing a few seconds of the world if the process is killed hard is real, but acceptable when your backups work.- Leave
network-compression-thresholdat 256 unless the server sits behind a proxy on the same machine. Then-1disables compression and saves CPU, because the traffic never leaves localhost. Over the internet, disabling compression will noticeably increase bandwidth.
max-tick-time=-1 is not an optimisation
-1 disables the watchdog, the mechanism that kills a hung server. It speeds up nothing, and all it really does is ensure that instead of a clean crash with a full stack trace you get a server hanging for hours with no trace of what blocked it. Leave the default 60000.spigot.yml: entity ranges, item merging and hoppers
In spigot.yml the biggest gains come from shortening entity tracking ranges and merging dropped items more aggressively, because both reduce the number of objects the server has to remember and broadcast to clients. Everything below goes under world-settings: default:.
entity-tracking-range:
players: 48
animals: 32
monsters: 32
misc: 24
other: 48
display: 128
merge-radius:
item: 3.5
exp: 6.0
mob-spawn-range: 5
item-despawn-rate: 4000
arrow-despawn-rate: 600
hopper-transfer: 8
hopper-check: 8
hopper-amount: 3
nerf-spawner-mobs: true
save-user-cache-on-stop-only: true| Change | Gain | Cost to the player |
|---|---|---|
entity-tracking-range | The defaults are 128 for players and 96 for mobs, so dropping to 48 and 32 cuts a genuinely large number of packets and tracked entities per player. | Animals and mobs appear on screen slightly later, from closer up. |
merge-radius | The defaults are 0.5 for items and disabled for experience, so 3.5 and 6.0 merge stacks that would otherwise lie around in the hundreds. | At high values items visibly jump together after mining, which some players notice. |
mob-spawn-range | Mobs spawn within reach of the player instead of dying off immediately after spawning. | Less spawn variety at distance, which mob-farm servers will feel. |
item-despawn-rate | Abandoned items disappear sooner, so fewer entities stay around. | 4000 ticks is about 3 minutes instead of 5. A player who died and did not make it back loses their gear. |
nerf-spawner-mobs | Mobs from spawners have no AI, so no pathfinding is calculated. | Farms based on spawners and pushing mobs with water stop working. |
hopper-check | Hoppers check their surroundings less often, a big relief for large sorting systems. | Item transport is noticeably slower. With hopper-amount: 3 this balances out almost entirely. |
max-tick-time: a waste of time on Paper
max-tick-time section with its tile and entity keys is sometimes recommended in old guides as a cure for lag. On Paper it does nothing at all, because the engine disables those options with its own patches and they remain in the file only for compatibility. On plain Spigot they do work, but they tell the server to abandon ticking mechanisms and entities halfway through, so TPS looks better purely because the server stops doing the work. Either way, leave them alone.bukkit.yml: spawn limits, or how many mobs may live at once
bukkit.yml is rarely touched, but when several hundred mobs are alive per player, lowering spawn-limits does more than any other change. The limits are counted per player, so on a server with thirty people they multiply very quickly.
spawn-limits:
monsters: 50
animals: 8
water-animals: 3
water-ambient: 10
ambient: 1
ticks-per:
monster-spawns: 2
animal-spawns: 400
water-spawns: 400
ambient-spawns: 400
autosave: 6000
chunk-gc:
period-in-ticks: 400monsters: 50instead of the default 70 means fewer monsters to tick and fewer collisions. On a survival server players will not notice, because away from caves the limit is rarely reached anyway.ambient: 1is bats. They contribute nothing beyond sound and work for the server.monster-spawns: 2attempts a spawn every other tick instead of every tick. That is half the work of the spawner for an almost unchanged mob count, because the population limit is the bottleneck anyway.autosave: 6000moves the world save to once every five minutes. Saving less often means stuttering less often, but also more to lose in a crash, so it only makes sense alongside backups that actually work.
paper-world-defaults.yml: where most of the real gain lives
This file contains optimisations Spigot does not have at all, which is why moving from Spigot to Paper is on its own the biggest optimisation available to you. Below are the settings that give a measurable effect without breaking mechanics.
chunks:
max-auto-save-chunks-per-tick: 8
delay-chunk-unloads-by: 10s
prevent-moving-into-unloaded-chunks: true
collisions:
max-entity-collisions: 2
entities:
armor-stands:
tick: false
behavior:
disable-chest-cat-detection: true
experience-merge-max-value: 16
spawning:
despawn-ranges:
monster:
soft:
horizontal: 28
vertical: 28
hard:
horizontal: 96
vertical: 96
per-player-mob-spawns: true
alt-item-despawn-rate:
enabled: true
environment:
optimize-explosions: true
treasure-maps:
find-already-discovered:
loot-tables: true
hopper:
disable-move-event: true
ignore-occluding-blocks: true
misc:
redstone-implementation: ALTERNATE_CURRENT
tick-rates:
mob-spawner: 2
sensor:
villager:
secondarypoisensor: 80
behavior:
villager:
validatenearbypoi: 120despawn-ranges has four levels, not two
soft: 32 and hard: 128 as plain numbers. Paper now expects separate horizontal and vertical keys under soft and hard, and the default for each of them is the word default rather than a number. A bare number placed there is ignored.| Setting | What it does | What to watch for |
|---|---|---|
max-entity-collisions: 2 | Limits how many collisions an entity calculates per tick. With packed mob herds or a farm this is an order-of-magnitude difference. | Mobs clip into each other, and farms that push mobs by crowding them may stop working. |
hopper.disable-move-event | Stops firing an event for every item a hopper moves. On a server with a sorting system this saves an enormous amount. | Plugins watching item flow (chest protection, logging, custom crafting) will no longer see those events. Check before enabling. |
despawn-ranges | Mobs beyond 96 blocks from the player disappear immediately, those closer than 28 never do. | Farms relying on mobs accumulating far from the player will lose throughput. |
optimize-explosions | A cheaper algorithm for calculating blast damage. | Minimal differences in damage at the edge of a blast. Worth testing on a PvP server with creepers. |
armor-stands.tick: false | Armour stands stop being ticked. Servers with decorations and holograms have thousands of them. | Stands stop reacting to gravity and water. If you use them as part of a mechanic, leave ticking on. |
alt-item-despawn-rate | Lets you set a shorter despawn time for junk like cobblestone and dirt without touching valuable items. | Requires filling in the item list in the file. Enabling it without a list changes nothing. |
tick-rates (villagers) | Villagers recalculate their points of interest less often. In a large village this is one of the heaviest parts of the tick. | Villagers are slower to find beds and workstations after the village changes. |
Redstone: one change sometimes worth more than the rest of the file
The misc.redstone-implementation key sits in paper-world-defaults.yml rather than in the global file, and getting that wrong is a mistake half the guides out there repeat. The default is VANILLA, with EIGENCRAFT and ALTERNATE_CURRENT as the alternatives. The latter is a from-scratch rewrite that only updates what actually changed, so in dust-heavy builds it can be many times faster than the vanilla algorithm.
When not to enable ALTERNATE_CURRENT
VANILLA. If someone reports a broken contraption after the change, this is the first place to look.paper-global.yml: a few small things to finish
The global file has little to offer in performance terms, because most of the switches live in the world configuration. These three are still worth knowing.
misc:
region-file-cache-size: 256
player-auto-save:
rate: -1
max-per-tick: -1
chunk-system:
io-threads: -1A value of -1 under player-auto-save means the server takes its frequency from ticks-per.autosave in bukkit.yml and picks a sensible per-tick limit on its own, so if you set 6000 there, nothing else needs touching. io-threads below zero means a single thread for disk operations, which is perfectly sufficient for a small or medium server.
JVM flags: not server config, but it counts just as much
The best-tested set of flags for Minecraft servers is the so-called Aikar flags, a G1 garbage collector configuration that trades rare long pauses for frequent short ones. You will not see the effect in the average TPS, only in the disappearance of regular one-second freezes.
java -Xms8G -Xmx8G \
-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- Setting
-Xmsequal to-Xmxis a deliberate decision rather than a way to save memory. A heap that does not grow never forces an expensive resize mid-game. - Above 12 GB the set changes:
G1NewSizePercent=40,G1MaxNewSizePercent=50,G1HeapRegionSize=16M,G1ReservePercent=15andInitiatingHeapOccupancyPercent=20. - Do not hand the server all available memory. The JVM needs room outside the heap for metaspace, threads and network buffers, so leave roughly 1 to 2 GB of headroom. Otherwise the process gets killed by the system before you ever see a Java error.
- Do not stitch flags together from several guides. The sets can contradict each other, and
-XX:+UseZGCnext to-XX:+UseG1GCis the fastest way to stop the server from starting at all.
On a managed panel you usually do not need this
-Xmx value usually cannot even be pushed above your package. This section matters mainly on your own VPS, or when the panel lets you supply your own startup line.Ready-made sets for three kinds of server
Different servers have different bottlenecks, so a single universal set does not exist. Below are starting points worth beginning from and then tuning with measurements.
| Setting | Survival with friends (up to 10) | Public with plugins (20 to 60) | Modpack (up to 15) |
|---|---|---|---|
view-distance | 8 | 6 | 6 |
simulation-distance | 6 | 4 | 4 |
spawn-limits: monsters | 70 | 40 | 30 |
max-entity-collisions | 4 | 2 | 2 |
mob-spawn-range | 6 | 4 | 4 |
nerf-spawner-mobs | false | true | true |
hopper.disable-move-event | true | depends on your plugins | false, because mods often need it |
redstone-implementation | ALTERNATE_CURRENT | ALTERNATE_CURRENT | VANILLA |
Modpacks are a different league
Five things that look like optimisation but are not
- Adding RAM to a server that has no RAM problem. Lag with the
Can't keep upmessage is a processor problem on a single thread. More memory will not speed up tick calculation, and too large a heap makes garbage collector pauses longer. - Copying a config from someone else wholesale. Files from guides refer to older versions and contain keys your build no longer knows. Paper ignores unknown keys silently, so you will be convinced you configured something.
- Disabling the watchdog. It masks the problem instead of solving it and takes away the one log you could have learned something from.
- Turning off everything that can be turned off. A server with mob AI disabled, zero despawn and a clipped entity tick has excellent TPS and is no fun to play on. Optimisation is the search for the best ratio of gain to mechanics taken away from players.
- Keeping ten plugins that do the same thing. Every plugin listens for events. Three land-protection plugins mean triple the work on every block placed, and that is one of the most frequent events on a server.
Frequently asked questions
Does paper.yml still exist?
No. Since Minecraft 1.19 Paper uses config/paper-global.yml and config/paper-world-defaults.yml. The old paper.yml is migrated automatically on the first start of a newer build and is no longer read.
Which should I lower first, view-distance or simulation-distance?
simulation-distance first. It governs the actual calculation of mobs and mechanisms, so it gives a bigger CPU win, and players notice it less than a shortened view distance. Lower the view distance only as a second step.
Do these settings work on Purpur and Pufferfish?
Yes, because both are Paper forks and inherit its entire configuration. On top of that they have their own files, purpur.yml and pufferfish.yml respectively, with further options, including more aggressive mob AI optimisations.
How long before a change shows an effect?
TPS and MSPT react immediately after a restart, but a trustworthy measurement needs normal traffic, so ideally compare /mspt at the same peak hour before and after. Changes to chunks and mob despawn only show after tens of minutes, once the world has cycled through.
Will lowering view-distance reduce player ping?
It will not reduce ping itself, because that depends on the distance to the server and the quality of the connection. It will reduce the amount of data sent to the client, which helps players on weaker connections and removes stutter when moving into new terrain.
Can I edit these files while the server is running?
You can save them, but the server reads its configuration at startup, so changes only apply after a restart. On top of that the server rewrites some of these files on shutdown, so a live edit may simply be wiped. It is safer to stop the server, change the file and start it again.
Optimisation only pays off on a sensible processor
Packages on highly clocked AMD Ryzen processors, which is exactly where the single thread ticking your world benefits. You edit the configuration files straight from the panel or over SFTP, and take a backup with one click before every change.


