Pufferfish Server Optimization Guide

The first thing to keep in mind is that there is no "best" configuration. The best way to use this guide is to tune the values shown to your liking. If a value is not mentioned here, it is recommended to leave it as the default setting. Additionally, you should only reduce the values mentioned in this guide if you are actually having performance issues. Value reductions here will have an impact on gameplay and may damage the experience for your players. If your server is not lagging, then you should not reduce any values. It is also recommended to follow this guide incrementally, making only a few changes at a time until the lag problem disappears. If the lag problem resurfaces, you can always further adjust the values later.

Server Software

One of the easiest ways you can improve your server's performance is by using the most optimized server software. We recommend our own fork of Paper called Pufferfish, which can be downloaded here. You can also find our source code online and join the discord server for support and to be notified of any important updates. This guide also applies if you're using other forks such as Paper or Purpur.

Need even faster software? Pufferfish+ is a fork of Pufferfish with even more performance patches, available exclusively to Pufferfish Host customers. Learn how to install Pufferfish+.

Chunk Settings

server.properties - view-distance: 7 The view distance option is the most impactful option on server performance. This option controls how many chunks the server will load around players, which players will be able to see. For servers with under 10 players, settings this value to 10 or higher can be acceptable. For servers with over 100 players, reducing this value to 5 or possibly even lower may be necessary. This option should never be reduced below 3.

server.properties - simulation-distance: 5 Simulation distance controls how many chunks around the player will tick. If you don't want to lower view distance any further but would like to avoid chunk lag, decreasing this option can help. You should never have this option set higher than the view distance.

paper.yml - prevent-moving-into-unloaded-chunks: true This option will prevent players from entering chunks which are unloaded by teleporting them back. If this were allowed to happen, it would cause a lag spike as the server would load the chunk on the main thread (referred to as a sync load). Loading chunks takes a considerable amount of time and it's best to let chunk loading happen on the async threads.

paper.yml - use-faster-eigencraft-redstone: true When enabled, this option replaces the vanilla redstone algorithm with a far faster algorithm. There have been little to no reports of this breaking redstone contraptions that work on vanilla servers.

paper.yml - grass-spread-tick-rate: 4 This option controls how quickly grass/mycelium spreads. Servers with many loaded chunks can have a negative performance impact from this behavior, so decreasing the frequency of this can improve performance. This may cause grass to spread more slowly.

Entity Settings

bukkit.yml - spawn-limits This option controls the amount of mobs per-player the server will spawn. If you're finding yourself with too many entities, adjusting this configuration section is an easy way to reduce the entity count. The most impactful change is the monsters limit. Large servers may want to reduce this value to 20 or below, while smaller servers may want to increase it to 50 or above. The default value is 70. You'll want to tune this value for your server, but some recommended values are shown below:

monsters: 30
animals: 10
water-animals: 5
water-ambient: 3
water-underground-creature: 3
axolotls: 3
ambient: 2

spigot.yml - mob-spawn-range: 3 This option controls the maximum distance from a player that mobs will spawn, in chunks. You should vary this value with the spawn-limits configuration shown above, decreasing it when you decrease the spawn limits, and increasing it when the spawn limits are increased. This will make mob spawning feel more normal to the player, even though the spawn limits are reduced as the mob cap will be more concentrated on the player.

paper.yml - per-player-mob-spawns: true When enabled, this option will allow the server to do some additional calculations to ensure that mobs are more evenly distributed between all players on the server. This will make sure that a player with a mob grinder can't hog the entire mob cap. This option has little impact on performance, but will greatly improve the player experience, especially if the spawn limits have been reduced.

spigot.yml - entity-tracking-range The default configuration for this option is fine for most servers, but it's worth mentioning for particularly large servers. If spark/timings indicates that the entity tracker is accounting for a significant portion of a server's lag, then reducing the tracking ranges in this configuration section can reduce the performance impact of the entity tracker. This option doesn't impact mob spawning or mob ticking, but rather the distance when mobs become visible to players. Be careful reducing the values too much, as adjusting these values too aggressively can result in mobs appearing out of nowhere.

spigot.yml - nerf-spawner-mobs: true When set to true, any mobs coming from spawners will have their AI effectively removed. If your server does not have any spawner-grinders, then you may consider setting this option to false instead to preserve the player experience. Servers that give players the opportunity to build grinders using spawners should always set this option to true.

paper.yml - max-entity-collisions: 2 This option will reduce the amount of work the server does to compute collisions between entities. Note that this will also prevent the entity cramming gamerule from working properly, so if you plan on using that gamerule, you should either not adjust this value, or set this value equal to or greater than the value of the maxEntityCramming gamerule.

paper.yml - update-pathfinding-on-block-update: false This option will prevent entities from re-computing their pathfinding whenever a block changes. Mobs may appear slightly more laggy with this option disabled, as their pathfinding will not update immediately upon the environment changing, but the impact is generally small enough to not be noticed by players.

paper.yml - fix-climbing-bypassing-cramming-rule: true When enabled, this option will fix a bug in Minecraft where the maxEntityCramming rule does not impact entities on ladders/vines. This breaks a vanilla behavior, but can prevent players from stacking up tons of entities in one spot.

paper.yml - armor-stands-do-collision-entity-lookups: false This option, when disabled, will prevent armor stands from participating in collisions with other entities. This can mitigate the impacts of some lag machines, whereby players stack large amounts of armor stands in one place to cripple the server with collision calculations.

paper.yml - mob-spawner-tick-rate: 2 This option controls the frequency at which spawners will attempt to spawn mobs. A value of 2 is practically impossible to notice as a player. If your world has many spawners, you may want to consider increasing this number to 4, but you should avoid going higher because it can reduce spawn rates.

pufferfish.yml - enable-async-entity-tracker: true (Pufferfish+ Exclusive) This option, only available in Pufferfish+, enables a new implementation of the entity tracker which processes entity tracking logic on an async thread. Due to internal server constraints, plugins will not be able to listen to the player velocity event if this option is enabled. Additionally, entity state may  temporarily desync, but this should automatically resolve. This option massively improves performance on servers with many entities, especially when many players are in close proximity, such as on event servers.

DAB Configuration

DAB is an important part of the Pufferfish server software, which decreases how frequently complex AI ticks. DAB impacts the ticking of villagers, zombified piglins, axolotls, hoglins, and goats (as of Minecraft 1.18). When entities are near to the player, they will tick like normal, but the farther away entities get, the slower their AI will be ticked. The values are tuned to provide the maximum performance benefit while minimally impacting the player experience. DAB may impact players' mob farms, so if this happens, you may want to consider increasing the activation-dist-mod parameter or disabling DAB altogether.

pufferfish.yml - dab.activation-dist-mod: 8 This value controls how quickly the effects of DAB wear off with distance. The default value of 8 is sufficient for most servers. Servers with large amounts of villagers may benefit from decreasing this value to 7, but the value should never be decreased below 6. If you have a small server, you may want to either increase this value to 10, or simply disable DAB.

pufferfish.yml - dab.blacklisted-entities If you don't want an entity to be impacted by DAB, you can add its name to this list.

Misc

paper.yml - nether-ceiling-void-damage-height: 127 When players are allowed to glitch onto the nether roof, they can infinitely roam without impedance, which can lead to them generating massive amounts of chunks. If you've set a custom nether height, you'll want to specify your custom height here instead of 127.

paper.yml - optimize-explosions: true This option enables a more optimized algorithm for computing the impact of explosions. While extremely difficult to notice, this algorithm does produce results that are different from vanilla. It is recommended to enable this, particularly if TNT is frequently used on your server.

paper.yml - enable-treasure-maps: false Treasure maps are poorly implemented by mojang and will cause a lag spike lasting several seconds while they are being generated. If these are not an important part of your server, it is recommended to disable them.

pufferfish.yml - enable-books: false Books are a common target for exploitation techniques, and have been used for all sorts of nasty things in the past including duplication exploits, crash exploits, and forcing servers to run out of memory while producing massive amounts of chunk data. It is highly recommended to disable books on public servers. Private servers with trusted players can safely leave books enabled.

server.properties - network-compression-threshold Depending on your situation, there are two possible values you should choose for this option. If you are running your server behind a proxy like velocity, bungeecord, or waterfall, you should set this option to -1 to disable compression. Otherwise, you should set this option to 256. Packet compression takes a significant amount of CPU load, and if running behind a proxy, it should be disabled to avoid doing the compression work three separate times.

Myths and Misconceptions

"Mob stackers are bad!" - Fact, but only sometimes. While it is true that using mob stacker plugins on naturally spawned mobs is a very bad idea, using these plugins on mobs originating from spawners is generally a good idea. If you are using this strategy to control spawner mob population, look for a stacker plugin that disables spawners when there are large mob stacks nearby.

"Lagassist/Clearlagg" - Myth. Globally clearing items off the ground is a bad idea. Not only is it rare for items on the ground to cause performance issues, but the server will clear them all by itself without intervention. If you'd like this to happen faster, you can consult the alt-item-despawn-rate option in paper.yml. Using these plugins to delete mobs is also a bad idea, as it only forces the server to do extra work. Immediately after the mobs are cleared, the server will have to do a ton of expensive calculations to determine where to spawn the new mobs.

"Switch to GraalVM/Zulu/Corretto/..." - Myth, mostly. While these JVMs can improve performance for some types of workloads, for the most part they do not improve Minecraft performance whatsoever. GraalVM, for example, will only improve performance if you're relying on running Javascript inside of your server. For the vast majority of servers that aren't doing this, you're going to have a more stable and consistent experience if you stick to Oracle or Adoptium implementations of the JVM.

Other Tips

  • Disable timings! The timings feature built in to paper is a good diagnostic tool, but it causes a very large performance impact. This is due to timings having to constantly start and stop a virtual "stopwatch". This operation can happen north of 100,000 times per tick. This requires a context switch, which is extremely expensive. Most moderately-sized servers can expect to see a 20% performance improvement simply by disabling timings, and large servers can see as much as 40% or more improvement. This feature can be disabled by setting the timings.enabled option in paper.yml. If it is disabled, it can be re-enabled in-game if required by using the command /timings on.
  • Use spark to debug performance issues. Spark is an alternative to Timings which doesn't have the downside of causing large amounts of lag. It also provides far more detailed and accurate information which can be more accurately used to assess the impact of performance.
  • Avoid "exotic" forks. Forks downstream of Pufferfish/Purpur/Paper are often plagued by stability issues, while providing no real performance improvement. These forks are also rarely benchmarked for their performance impact (if ever) and can even decrease performance in some cases.