Disable sync-chunk-writes on non-Paper servers
Moves chunk saving off the main thread to avoid long I/O stalls and reduce lag spikes on vanilla, Fabric, and Spigot servers.
Practical Minecraft server optimization guide for survival, SMP, and mini-game servers. Fix lag, stabilize TPS, and configure Paper or Purpur with safe, battle-tested presets from real production servers.
Use this guide as a practical checklist when preparing a new server or rescuing an existing world from lag spikes and TPS drops.
Optimize around target 20 TPS and sub-50 ms MSPT using configuration presets designed for modern 1.21.x server workloads.
All recommendations prioritize stability first, then performance. You can apply them gradually without wiping worlds or resetting player progress.
Designed around common hosting scenarios from self-hosted dedicated instances to cloud VPS and game panel providers with limited CPU time.
Apply these high-impact changes before doing deep profiling to quickly remove the most common Minecraft server bottlenecks.
Moves chunk saving off the main thread to avoid long I/O stalls and reduce lag spikes on vanilla, Fabric, and Spigot servers.
Gives you modern async chunk loading, better mob caps, and dozens of performance patches that do not exist on Bukkit or Spigot.
Keeps tick cost low while still allowing players to see far enough for survival, SMP, and mini-game servers.
Prevents uncontrolled mob counts while keeping survival gameplay and farms feeling natural for players.
Stops a single player or farm from consuming the entire mob cap so every online player gets fair mob spawns.
Tip: click any recommended value to copy it to your clipboard before editing configuration files.
These baselines are derived from established community optimization guides and modern Minecraft Wiki documentation for 1.21.x servers.
Stabilize player connections, reduce timeouts, and keep packets efficient for busy survival and SMP servers.
| File | Option | Recommended | Type | Notes |
|---|---|---|---|---|
| server.properties | network-compression-threshold | 256 | CPU ↔ bandwidth tradeoff | Use 256 as a starting point. Increase the value if your CPU is overloaded, or lower it for bandwidth-constrained players. Set to -1 only on very low-latency internal networks or proxy setups. |
| purpur.yml | use-alternate-keepalive | true | connection stability | Reduces random timeouts for players on unstable networks by sending more frequent keepalive packets. Avoid enabling this when using TCPShield where the feature is known to conflict. |
Control how many chunks your server loads and ticks around each player to eliminate stutter from world streaming.
| File | Option | Recommended | Type | Notes |
|---|---|---|---|---|
| server.properties | simulation-distance | 4 | gameplay tick radius | Defines how far around players the server actively ticks blocks and entities. Lower values heavily reduce CPU usage while still keeping farms and redstone working nearby. |
| server.properties | view-distance | 7 | visual radius | Controls how many chunks are sent to the client. Keep this higher than simulation-distance so players can see more without the server ticking everything they see. |
| paper-world configuration | delay-chunk-unloads-by | 10s | chunk reuse window | Keeps recently visited chunks loaded for a short time to avoid constant load/unload cycles when players move back and forth through the same areas. |
| paper-world configuration | prevent-moving-into-unloaded-chunks | true | anti sync-load safety | Stops players from walking into completely unloaded chunks that would otherwise trigger expensive synchronous chunk loads on the main thread. |
| paper-world configuration | entity-per-chunk-save-limit | Projectile caps around 8–16 each | save-time protection | Prevents extreme cases where huge numbers of arrows, tridents, or other projectiles are saved into a single chunk and crash the server on load. |
Tune mob counts and AI ranges so that combat and farms feel good while the server stays responsive under load.
| File | Option | Recommended | Type | Notes |
|---|---|---|---|---|
| bukkit.yml | spawn-limits | monsters: 20, animals: 5, water-animals: 2, ambient: 1 | global mob caps | Multiplying these values by the player count gives the total mobs allowed. Lower values reduce CPU pressure but also reduce ambient mobs in survival worlds. |
| bukkit.yml | ticks-per.* | monster-spawns: 10, others: 400 | spawn frequency | Increases the interval between spawn attempts for non-essential mobs. Monsters can spawn slightly less frequently without hurting farms, while ambient and water mobs can be much slower. |
| spigot.yml | mob-spawn-range | 3 | spawn radius | Reduces the chunk radius used for mob spawning. Keep this at or below your simulation-distance so mobs do not spawn where they will immediately despawn. |
| spigot.yml | entity-activation-range | animals: 16, monsters: 24, villagers: 16, misc: 8 | AI tick distance | Lower values mean mobs far away from players are effectively frozen, saving CPU. Do not go too low or farms and villager mechanics may break. |
| spigot.yml | entity-tracking-range | players: 48, mobs: 48, misc: 32 | visibility distance | Defines how far away entities are visible to players. This should usually stay above your activation range so mobs do not suddenly appear at close range. |
| spigot.yml | tick-inactive-villagers | false | villager AI outside range | Prevents villagers far away from any player from ticking, which can dramatically reduce CPU usage in large trading halls. |
| spigot.yml | nerf-spawner-mobs | true | farm safety | Disables AI for mobs that come from spawners so large grinder setups do not overload the mob AI system. |
| paper-world configuration | despawn-ranges | soft: 30, hard: 72 for most categories | mob cleanup distance | Despawn mobs more aggressively when they are far beyond any player. Hard range should stay slightly above your simulation-distance multiplied by 16 blocks. |
| paper-world configuration | per-player-mob-spawns | true | fair mob distribution | Distributes the mob cap between players instead of globally, giving more consistent gameplay on busy SMP servers with farms. |
Avoid these frequent mistakes when building a lag-free Minecraft server for long-term communities and creator projects.
Treat backups as mandatory, not optional. Keep automated off-site copies of your world and plugin data so a single crash, filesystem issue, or admin mistake never wipes months of progress.
Old server jars and plugins miss critical performance patches and security fixes. Upgrade to supported versions and avoid depending on abandoned plugins whenever possible.
Bukkit and Spigot are effectively in maintenance mode and lack modern optimizations. Move to Paper or Purpur to benefit from better chunk loading, mob handling, and performance improvements.
Cheap shared hosting often oversells CPU resources. Your server competes with many others on the same machine, so performance will fluctuate and lag spikes are almost guaranteed under load.
Datapacks that run commands every tick scale poorly with player count. Prefer plugins or lighter datapacks that modify loot tables, biomes, or world generation instead of running constant command loops.
Minecraft servers care far more about strong single-core CPU performance and SSD storage than raw RAM capacity. Prioritize high clock speed CPUs and SSDs before buying more memory than you really need.
Run your server with real players online and note TPS, MSPT, and lag complaints. Identify whether your bottlenecks are CPU, disk I/O, or network related.
Implement the quick fix checklist and the baseline settings for networking, chunks, and mobs. Restart the server and verify that it boots cleanly without new errors.
Invite players back, monitor logs, and watch how TPS behaves during peak activity. Adjust view distance, mob caps, and despawn ranges based on the actual playstyle of your community.
If performance is still poor after tuning, profile plugins and consider moving to stronger single-core hardware with SSD storage instead of simply buying more RAM.