Minecraft Server Optimization
Complete Guide for Spigot, Paper, and Purpur (1.20-1.21)
The performance of a Minecraft server relies on suitable software and hardware configuration. This guide is intended for administrators using Spigot, Paper, or similar forks like Purpur and Pufferfish, covering versions 1.20.x to 1.21.x. We will detail the essential settings in configuration files (spigot.yml, paper.yml, bukkit.yml, purpur.yml), explain why default values are often inadequate, and show how targeted adjustments can improve TPS, reduce CPU load, and stabilize your server.
This guide also includes recommendations for useful plugins, a comparison of the advantages of Purpur and Pufferfish over Paper and Spigot, as well as advice on Java configuration (versions, JVM G1GC flags). The content is organized into sections for quick and efficient reference.
Choosing Your Server Software
Comparison of Available Solutions
| Software | Base | Main Advantage | Recommended for |
|---|---|---|---|
| Spigot | CraftBukkit | Historical plugin compatibility | Small simple servers |
| Paper | Spigot | Optimizations + advanced options | Majority of servers |
| Pufferfish | Paper | Maximum performance | Highly populated servers |
| Purpur | Pufferfish | Advanced customization | Servers requiring exotic options |
Paper Over Spigot
Spigot and its predecessor CraftBukkit are the historical basis for Bukkit servers, but they now lag behind in terms of performance compared to Paper. The latter is a fork of Spigot that incorporates numerous optimizations and fixes while maintaining full compatibility with Spigot and Bukkit plugins. Paper also exposes dozens of advanced configuration options to fine-tune performance without significantly altering gameplay.
Pufferfish for Pure Performance
Pufferfish is a fork of Paper that emerged in 2021, entirely focused on performance. It integrates many advanced patches while remaining compatible with the Paper API.
Improvements included in Pufferfish:
| Feature | Description |
|---|---|
| Asynchronous processing | Some entities are partially processed in the background |
| DAB System | Faster mob AI algorithms |
| SIMD Map Rendering | Optimization via vector instructions |
| Hopper Management | More efficient hopper operation |
| Ray Tracing Optimization | Accelerated line of sight calculations |
| Memory Management | Reduced garbage collector pauses |
| Sentry.io Integration | Automatic server error reporting |
| Profiler Flare | Advanced analyses including memory profiling |
Most of these optimizations are transparent to gameplay. Those that may have an impact can be disabled in pufferfish.yml. If your goal is to support a large number of players with high load, Pufferfish often represents the best choice.
Note: There is also Pufferfish+, a commercial version even more optimized with entity tracking and fully asynchronous pathfinding, designed for very large servers.
Purpur for Customization
Purpur is a fork of Paper focused on advanced customization. Technically, it includes all the optimizations of Pufferfish but does not add any additional performance gain. However, it offers hundreds of new configuration options to adjust gameplay mechanics: ability to ride certain mobs, flying squids, single-player sleep, and many more.
By default, these additional features are disabled, and the server behaves like a standard Paper/Pufferfish. Only use Purpur if you truly need these gameplay options, as more patches potentially mean more bugs.
What to Avoid
| To Avoid | Reason |
|---|---|
| Obscure or Paid "Custom" JARs | 99% chance of inefficiency or harm |
| Pure Vanilla Server | Significant performance gap compared to Paper |
| Sticking with Spigot | You miss out on free Paper optimizations |
bukkit.yml Configuration
The bukkit.yml file manages parameters such as passive and hostile entity spawn settings. The default values in Bukkit/Spigot are calibrated for small sparsely populated servers but can be excessive for a survival server with many players.
Spawn Limits
These quotas define the number of mobs that can spawn per player. By default, a player can have up to about 70 monsters, 10 animals, and 15 aquatic creatures around them, which can quickly saturate the server with multiple connected players.
Recommended Values:
| Category | Default Value | Recommended Value |
|---|---|---|
| Monsters | 70 | 20 to 30 |
| Animals | 10 | 5 |
| Aquatic Creatures | 15 | 2 |
| Ambient Creatures | 15 | 1 |
The internal calculation multiplies these limits by the number of connected players. By reducing these numbers, you decrease the density of mobs to manage and lighten the server load.
Caution: Values that are too low reduce wildlife and game difficulty. For a "hardcore" survival server or one focused on mob farms, do not set them too low. The value of 30 monsters offers a good compromise if you want to keep the action.
Spawn Frequencies
These settings control the frequency of attempts to spawn new entities. By default, Minecraft tries to spawn monsters every tick (20 times per second) and animals every 400 ticks (about 20 seconds).
Recommended Values:
| Category | Default Value | Recommended Value |
|---|---|---|
| monster-spawns | 1 | 2 to 10 |
| animal-spawns | 400 | 400 |
| water-spawns | 1 | 400 |
| ambient-spawns | 1 | 400 |
Setting monster-spawns to 2 means trying only once every 2 ticks. The difference in spawn rate is imperceptible to players, but the server processes half as many spawn cycles. For aquatic and ambient categories, intervals of 400 ticks or more are perfectly acceptable since these creatures quickly reach their population cap.
Paper Additional Option
Paper offers the per-player-mob-spawns option which distributes spawns more evenly among players rather than filling one player's quota before moving on to the next. By enabling this option, you can afford lower limits without depriving players of encounters: each player will have their fair share of mobs around them.
spigot.yml Configuration
The spigot.yml file contains several key parameters to control entity activity range and item management. The default values aim to replicate solo behavior, but in multiplayer, they can be reduced to save resources.
View and Simulation Distances
| Parameter | Description | Recommendation |
|---|---|---|
| view-distance | Chunk rendering distance | Leave as "default" in spigot.yml |
| simulation-distance | Entity activity distance | 4 chunks (server.properties or Paper) |
| view-distance (effective) | Chunks sent to the client | 7 to 10 chunks |
Starting from Minecraft 1.18+, it is recommended to leave view-distance as "default" in spigot.yml and use distance settings in server.properties or via Paper. The trick is to set a low simulation distance (4 chunks) while keeping a higher view distance (8 to 10 chunks). This way, players see far but the server only calculates the nearby surroundings.
Mob Spawn Radius (mob-spawn-range)
This radius in chunks determines how far mobs can spawn from the player. By default set to 8 chunks (128 blocks), it can be reduced to concentrate spawns.
Recommendation: Set this parameter to 4 or 6 chunks if your simulation distance is low. Ensure that mob-spawn-range remains less than or equal to your effective simulation distance. By reducing this radius, even with reduced spawn limits, players will feel like they are in a lively world as mobs will appear closer to them.
Entity Activation Range
This is a major performance lever. It defines the distance in blocks from which entities stop being active (their AI is "asleep" until a player is nearby).
Recommended Values:
| Category | Default Value | Recommended Value |
|---|---|---|
| Monsters | 32 | 24 |
| Animals | 32 | 16 |
| Aquatic Creatures | 32 | 8 |
| Villagers | 32 | 16 |
| Flying Monsters (phantoms) | 32 | 48 |
| Raiders | 32 | 48 |
| Misc | 16 | 8 |
Reducing these ranges relieves the CPU as distant entities no longer consume resources. However, too low values can break certain mechanisms. For example, iron farms require "active" villagers within a certain range of zombies.
Tip: Also enable tick-inactive-villagers: false so that villagers fall asleep outside the player's field. Since 1.14, villagers have a huge impact on ticks when active in large numbers.
Entity Tracking Range
This parameter defines the distance at which entities are sent to the client. It can be larger than the activation range without significant server cost as it only affects data sent to players.
Recommendation: Keep tracking ranges slightly higher than activation ranges to avoid mobs suddenly "popping" on the screen. Values of 48 for most categories (except misc at 32) make a good compromise.
Item and XP Merging (merge-radius)
| Type | Default Value | Recommended Value |
|---|---|---|
| Items | 2.5 | 4 to 5 |
| XP | 3.0 | 6 |
Merging entities of items on the ground significantly reduces the number of entities to manage. Instead of 50 separate XP orbs, you have one or two larger ones. Do not increase these radii too much as items could "teleport" from one block to another or pass through walls to merge.
Tip: Paper offers the fix-items-merging-through-walls option to prevent this behavior if you enlarge the merge radius significantly.
Ground Entity Lifetimes
| Parameter | Default Value | Recommended Value |
|---|---|---|
| arrow-despawn-rate | 1200 ticks (1 min) | 300 ticks (15 sec) |
| item-despawn-rate | 6000 ticks (5 min) | 4000 ticks (3 min) |
Shot arrows will be cleaned up more quickly, avoiding their invisible accumulation. For items, 3 minutes are more than enough for a player to pick up their drops.
Paper Note: The alt-item-despawn-rate option allows you to set a specific despawn time for certain items (cobblestone, netherrack, gravel). This can be a good alternative to a clearlag plugin.
Other Important Parameters
| Parameter | Recommended Value | Description |
|---|---|---|
| nerf-spawner-mobs | true | Spawner mobs have no AI until touched |
| save-user-cache-on-stop-only | true | User cache is saved only on stop |
| max-tick-time (tile and entity) | 1000 | Almost completely disables the tick limiter |
nerf-spawner-mobs: If your server has many spawner farms, this is a huge performance gain. "Nerfed" monsters have almost no CPU cost and simply wait to be killed.
max-tick-time: By setting it to 1000ms, you disable the safety net system that can cause strange behaviors (entities or redstone machines missing cycles). The server will still try to calculate everything as planned, even if it leads to a TPS below 20.
paper.yml Configuration
Paper and its forks have additional configurations compared to Spigot. These options are often improvements disabled by default to maintain vanilla behavior, but once enabled, they significantly boost performance.
Game Engine Optimizations
Optimized Redstone
| Option | Value | Description |
|---|---|---|
| use-faster-eigencraft-redstone | true | Activates the EigenCraft algorithm |
| redstone-implementation | ALTERNATE_CURRENT | Alternative depending on the version |
This new engine reduces redundant redstone updates and greatly improves the performance of complex circuits without changing their observable behavior.
Optimized Explosions
| Option | Value | Description |
|---|---|---|
| optimize-explosions | true | Optimized algorithm for TNT and creepers |
The algorithm calculates blast areas faster with imperceptible precision loss for players.
Integrated Anti-Xray
| Option | Value | Description |
|---|---|---|
| anti-xray.enabled | true | Activates protection |
| anti-xray.engine-mode | 2 | Recommended obfuscation mode |
Paper's anti-xray is much more efficient than traditional plugins. It obscures undiscovered ore blocks by temporarily replacing their appearance in sent chunks. Never use third-party anti-xray plugins on Paper.
Entity and Mob Management
Reduced Collisions
| Option | Default Value | Recommended Value |
|---|---|---|
| max-entity-collisions | 8 | 2 |
In a large mob pile, each entity will only handle 2 collisions at a time instead of 8, reducing the combinatorial explosion of calculations.
Player-Based Spawns
| Option | Recommended Value |
|---|---|
| per-player-mob-spawns | true |
The server evenly distributes the global mobcap among players, preventing a single player from monopolizing all hostile spawns.
Hopper Optimization
Hoppers are known to be one of the worst enemies of TPS as they perform constant checks.
| Option | Value | Condition |
|---|---|---|
| hopper.disable-move-event | true | Only if no plugin listens to InventoryMoveItemEvent |
| hopper-transfer (spigot.yml) | 8 | Acceptable default value |
| hopper-check (spigot.yml) | 8 | Instead of the default 1 |
| hopper.ignore-occluding-blocks | true | Disables a rarely used vanilla behavior |
By disabling disable-move-event, you prevent the server from creating an event for every item movement in a hopper. This is a massive performance gain on servers filled with sorting systems.
Attention: If you use chest protection plugins or log plugins for moved items, do not disable this option.
Villager Optimizations
| Option | Value | Description |
|---|---|---|
| tick-inactive-villagers | false | Villagers sleep outside the player's view |
| villager.lobotomize (Purpur) | true | Removes AI from villagers far from their goal |
| villager.search-radius.* (Purpur) | 16 | Reduces bed/work search radii |
Purpur Miscellaneous Options
| Option | Value | Description |
|---|---|---|
| zombie.aggressive-towards-villager-when-lagging | false | Zombies stop pursuing villagers in case of lag |
| entities-can-use-portals | false | Prevents mobs from using portals |
| use-alternate-keepalive | true | Avoids timeouts for slow players |
Chunk Loading and World
Protection Against Unloaded Chunks
| Option | Recommended Value |
|---|---|
| prevent-moving-into-unloaded-chunks | true |
This option prevents a player moving too fast (e.g., with elytra) from entering a chunk not yet generated, which would cause a very costly synchronous load that could freeze the server.
Unload Delay
| Option | Recommended Value |
|---|---|
| delay-chunk-unloads-by | 10s |
If a player quickly travels back and forth, the server will not constantly load/unload the same chunks. This avoids repeated IO/CPU operations.
Treasure Maps
| Option | Value | Description |
|---|---|---|
| treasure-maps.enabled | false | Completely disables treasure maps |
| treasure-maps.find-already-discovered | true | Maps point to already discovered structures |
Treasure maps can cause huge lag spikes if they search for structures very far away. If you keep them, make sure to have a worldborder and ideally have pre-generated interiors.
World Pregeneration
Since versions 1.18+, Mojang has optimized terrain generation and asynchronous loading. Pregeneration is no longer essential except on very slow CPUs. However, for a server launch, you can use a plugin like Chunky to pregenerate the interior of your worldborder.
Tip: Place a worldborder on each of your worlds (Overworld, Nether, End) to prevent players from endlessly generating unnecessary terrain. The Nether border should be proportionally 8 times smaller.
Recommended Performance Plugins
Summary Table
| Plugin | Function | Essential |
|---|---|---|
| Spark | CPU and memory profiler | ✅ Yes |
| Timings (integrated) | Heavy task report | ✅ Yes |
| FarmLimiter/FarmControl | Limits entity clustering | As needed |
Spark
Essential for profiling your server. Spark allows you to record real-time CPU and memory performance profiles.
Useful commands:
| Command | Function |
|---|---|
/spark profiler | Starts recording |
/spark profiler --stop | Stops and generates the report |
/spark tps | Displays current TPS |
/spark health | Server health status |
/spark gc | Garbage collector information |
/spark profiler --memory | Tracks memory leaks |
It's the perfect tool to identify the cause of your lag spikes: discovering that a certain type of mob or a plugin function monopolizes 40% of tick time.
Timings (integrated in Paper/Spigot)
The /timings report command generates a report of the heaviest tasks since the last reset. Paper greatly enhances this tool compared to Spigot, providing load graphs and details of the most costly events.
FarmLimiter / FarmControl
This type of plugin monitors and limits the size of entity clusters in AFK farms. A common issue: players create huge mob farms or 500 cows in a tiny enclosure.
Operation: Beyond a threshold (e.g. 30 mobs of the same type within a given radius), new spawns are blocked or excess mobs are gradually removed.
ClearLag
Well-known plugin that periodically cleans up ground entities and excess mobs.
Opinion: ClearLag can temporarily resolve overload issues, but it's more of a band-aid than a lasting solution. Properly configuring despawns and item merges often makes ClearLag unnecessary. Additionally, ClearLag itself consumes resources to regularly scan all entities.
Chunky
Simple and efficient world pregeneration plugin. You define a radius or borders, and it gradually fills all chunks. It works asynchronously to avoid crashing your server during the operation.
VillagerOptimizer
If your villagers remain problematic despite adjustments, this plugin reduces the frequency of their costly tasks (bed searching, pathfinding). It's similar to Purpur settings but usable on Spigot/Paper.
What to Avoid
| Avoid | Reason |
|---|---|
| "Miracle" plugins promising multithreading | 99% ineffective or dangerous |
/reload command in production | Causes memory leaks and crashes |
| Hot-swapping plugins | Inconsistencies and instability |
Always prefer a clean server restart after adding or removing plugins.
Java and JVM Configuration
Optimizing Minecraft goes beyond game configs: Java runtime environment and allocated resources also matter.
Required Java Version
| Minecraft Version | Minimum Java Version |
|---|---|
| 1.17 and earlier | Java 8 or 11 |
| 1.18 to 1.20.4 | Java 17 |
| 1.20.5 and newer | Java 21 |
Avoid Java 8 or 11 on modern servers. Language and garbage collector improvements in Java 17/21 bring significant performance and stability gains.
Garbage Collector Configuration
Minecraft server heavily uses memory, generating many temporary objects. Poor GC settings can cause pauses of several hundred milliseconds.
Recommended principles:
| Principle | Recommendation |
|---|---|
| Sufficient RAM | 8 GB for a typical 50-player server |
| Xms = Xmx | Set the same value for heap min and max |
| Garbage Collector | G1GC (default on Java 17+) |
| Flags generator | Use flags.sh to obtain optimal flags |
Example command line:
java -Xms8G -Xmx8G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -jar server.jar nogui
Tip: Use the flags generator on flags.sh, which automatically provides the appropriate command line based on your Java version and allocated RAM.
GC Monitoring
The /spark gc command or certain timings can indicate the percentage of time spent in GC. Ideally, this should remain low (below 5%). If you notice frequent pauses, increase RAM or diagnose potential memory leaks.
JVM Alternatives
| JVM | Recommendation |
|---|---|
| OpenJ9 | ⚠️ Not officially supported |
| GraalVM | ⚠️ Not officially supported |
| HotSpot (standard) | ✅ Recommended |
Although alternative JVMs exist, Paper and Spigot do not officially support them and they can cause unpredictable issues.
System Tips
| Component | Recommendation |
|---|---|
| CPU | Focus on frequency over core count |
| Storage | SSD/NVMe for the world |
| network-compression-threshold | 256 (default) or 512 for 100+ player servers |
Minecraft is essentially single-threaded. Therefore, processor frequency and IPC take precedence over core count.
Conclusion and Recommendations
By implementing the recommendations in this guide, you will achieve a significantly more stable and performant server, capable of maintaining 20 TPS in situations where the default configuration would have faltered.
Key Points Summary
| Area | Priority Action |
|---|---|
| Server Software | Switch to Paper or an optimized fork |
| Distances | Reduce simulation-distance and activation ranges |
| Spawns | Decrease limits and increase intervals |
| Entities | Enable nerf-spawner-mobs and tick-inactive-villagers: false |
| Redstone | Activate the alternative Paper algorithm |
| Hoppers | Increase hopper-check and disable move-event if possible |
| Monitoring | Regularly use Spark |
Continuous Best Practices
Constantly Monitor: Use Spark to identify sources of lag. Optimization is an ongoing process as each new farm or plugin added can introduce a weakness.
Set Limits: Don't let players do whatever they want at the expense of the server. Clearly announce your entity rules and use tools to enforce them automatically.
Accept Compromises: A server that is 100% vanilla in behavior and 100% smooth does not exist for high loads. Is it better to have villagers that are slightly less "intelligent" or a spawn of 200 villagers that paralyzes everything? The answer is clear.
Update Intelligently: Keep your software (Paper, Purpur) up to date as they often incorporate new optimizations. Read the changelogs and stay informed about developments like Folia, Paper's future multi-threaded server.
Each server is unique. This guide provides you with a solid foundation to refine: test changes gradually (ideally one by one), measure the impact via Spark or timings, and adjust based on your observations.
To test these optimizations on a high-performance infrastructure, discover our free Minecraft server offers and see the difference in real conditions!


