Minecraft Server Optimization Guide
Boost your Minecraft server's TPS with optimized JVM flags, chunk settings, and server software choices.
We earn commissions from hosting providers on this page. This doesn't affect our rankings, which are based on independent testing and research. Full disclosure
Running a Minecraft server is easy. Running one that stays at 20 TPS with 50 players online, custom plugins, and a sprawling world? That takes deliberate optimization. This guide walks you through every layer of Minecraft server performance tuning -- from choosing the right server JAR to fine-tuning entity behavior and pre-generating your world. Whether you are running a small survival server for friends or a public network with hundreds of concurrent players, these techniques will help you eliminate lag and deliver a smooth experience.
Choosing the Right Server JAR
Your choice of server software has the single biggest impact on performance. Vanilla Minecraft server (the JAR from Mojang) has no optimizations and no plugin support. You should never use it for a server you care about.
Paper is the gold standard for most servers. It is a fork of Spigot that includes dozens of performance patches, async chunk loading, and extensive configuration options. Paper supports all Bukkit and Spigot plugins and is actively maintained with rapid updates after each Minecraft release. If you are running a plugin-based server, Paper is the right choice about 90% of the time.
Purpur takes Paper further. It is a fork of Paper that adds even more performance tweaks along with extensive gameplay customization options. You can change mob behavior, tweak game mechanics, and enable features like rideable mobs -- all through config files. Purpur maintains full Paper plugin compatibility. If you want maximum configurability on top of solid performance, Purpur is worth considering.
Fabric + Lithium is the best choice for modded or semi-vanilla servers. Fabric is a lightweight mod loader, and Lithium is an optimization mod that rewrites internal game systems (physics, chunk loading, entity ticking) without changing vanilla behavior. Pair Lithium with Starlight (lighting engine optimization) and FerriteCore (memory reduction) for a performance-optimized modded base. Fabric does not support Bukkit/Spigot plugins, so this path is for mod-based setups only.
Forge is necessary if your modpack requires it, but its performance is generally worse than Fabric. Many popular modpacks still target Forge, so you may not have a choice. If you are on Forge, focus heavily on the JVM and config optimizations covered below.
Aikar's JVM Flags
Java's default garbage collection settings are terrible for Minecraft. Aikar's flags are a specific set of JVM arguments that configure the G1 garbage collector to minimize lag spikes caused by garbage collection pauses. These flags are considered mandatory for any serious Minecraft server.
For servers with 12GB or less RAM:
java -Xms10G -Xmx10G -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 server.jar --nogui
Key principles: always set -Xms equal to -Xmx (prevents heap resizing lag), use G1GC (not ZGC or default), and allocate enough RAM but not too much. Over-allocating RAM (giving a vanilla server 16GB when it needs 4GB) actually hurts performance because garbage collection has more memory to scan.
How much RAM do you actually need? A vanilla server with 10 players needs 2-4GB. A plugin-heavy server with 20-40 players needs 6-8GB. A modded server with 100+ mods needs 8-12GB. Large modpacks like All the Mods 10 may need 10-16GB.
server.properties Optimization
The server.properties file contains settings that directly affect server load. Here are the most impactful changes:
view-distance controls how many chunks around each player the server keeps fully loaded and ticking. The default of 10 is too high for most servers. Set this to 6-8 for good performance. Players can still see further using the simulation-distance split.
simulation-distance (Paper and 1.18+) controls how far from the player entities and redstone are actually simulated. Set this to 4-6. This is separate from view-distance, meaning chunks between simulation-distance and view-distance are sent to clients for rendering but do not consume server tick time.
entity-broadcast-range-percentage controls the distance at which entities are sent to players. Lowering this to 75-100 reduces the number of entities tracked per player.
network-compression-threshold should be set to 256 (default is 256, do not lower it). This balances bandwidth usage with CPU cost.
max-tick-time can be set to -1 to prevent the server from killing itself during temporary lag spikes, but only do this on servers where you actively monitor performance.
Paper and Spigot Configuration Tuning
Paper exposes dozens of performance knobs through its configuration files. Here are the highest-impact settings:
In paper-world-defaults.yml:
entity-per-chunk-save-limit-- Cap the number of entities saved per chunk. Set limits likeexperience_orb: 16,arrow: 16,snowball: 8to prevent chunk-crashing entity buildup.despawn-ranges.softanddespawn-ranges.hard-- Reduce these to despawn hostile mobs closer to players. Soft: 28, Hard: 56 is a good starting point.hopper.disable-move-event-- Set totruefor a significant performance boost. Breaks some plugins that listen to hopper events, so test first.max-auto-save-chunks-per-tick-- Lower to 6-8 to spread autosave IO across more ticks.optimize-explosions-- Set totrue. Uses a faster explosion algorithm.prevent-moving-into-unloaded-chunks-- Set totrueto prevent players from loading chunks faster than the server can generate them.treasure-maps.enabled-- Set tofalseif you do not need them. Treasure map generation triggers massive chunk scanning.
In spigot.yml:
merge-radius.itemandmerge-radius.exp-- Increase to 4.0 and 6.0 to merge nearby items and XP orbs, reducing entity counts.mob-spawn-range-- Lower to 4-6 to concentrate mob spawns closer to players.entity-activation-range-- Reduce toanimals: 16, monsters: 24, misc: 8to skip ticking distant entities.
Chunk Loading and Pre-Generation
Chunk generation is one of the most CPU-intensive operations on a Minecraft server. Every time a player explores new territory, the server has to generate terrain, caves, structures, and biome features from scratch. On a busy server, multiple players exploring simultaneously can tank your TPS.
Pre-generating your world with the Chunky plugin eliminates this problem entirely. Install Chunky, set your world border, and run generation before players join:
/chunky radius 5000
/chunky start
This generates all chunks within a 5000-block radius of spawn. For a full survival world, pre-generate a 10,000-block radius. This process takes time (potentially hours for large areas) but is absolutely worth it. Run it during off-peak hours or before the server launches.
Set a world border using /worldborder set 20000 to prevent players from exploring infinitely and forcing endless chunk generation. A world border also makes pre-generation feasible.
Entity Management
Entities (mobs, items, XP orbs, minecarts, armor stands) are the most common source of lag on established servers. A single poorly-designed mob farm can spawn hundreds of entities and destroy server performance.
Set entity limits per chunk. Paper's spawn-limits in paper-world-defaults.yml controls how many mobs can exist globally. Lower the defaults: monsters: 50, animals: 8, water-animals: 3, ambient: 1.
Use the ClearLag plugin or Paper's built-in features to periodically remove ground items and limit entity counts. Configure ClearLag to warn players before clearing and to exempt named items.
Audit mob farms. Use the spark profiler (see below) to identify which chunks have the most entities. Common culprits: uncontrolled villager breeders, item sorters with thousands of items on the ground, and mob grinders without proper kill mechanisms.
Disable unnecessary entities. In paper-world-defaults.yml, you can disable bat spawning entirely (bat.spawn: false through Purpur) and limit the number of experience orbs by configuring merge behavior.
Monitoring Performance with Spark
You cannot optimize what you cannot measure. The spark plugin is the standard profiling tool for Minecraft servers. Install it and use it regularly.
Check TPS and tick durations:
/spark tps
A healthy server maintains 20 TPS with average tick times under 50ms. If your MSPT (milliseconds per tick) regularly exceeds 50ms, your server is lagging.
Run a profiler session:
/spark profiler start
Let it run for 5-10 minutes during peak player activity, then stop it with /spark profiler stop. Spark generates a detailed report showing exactly which parts of the server tick are consuming the most time. Look for:
- Entity ticking -- Too many mobs or poorly configured entity activation ranges.
- Chunk loading/generation -- Players exploring ungenerated territory.
- Plugin overhead -- Inefficient plugins consuming tick time.
- Scheduled tasks -- Plugins running heavy operations on the main thread.
Monitor memory usage:
/spark health
If your heap usage regularly exceeds 85%, you either need more RAM or need to find memory leaks (often caused by chunk loading or caching plugins).
Common Performance Mistakes
Allocating too much RAM. Giving a vanilla server 32GB when it needs 4GB means the garbage collector has to scan 32GB of heap. This causes longer and more frequent GC pauses. Match your RAM allocation to your actual needs.
Using too many plugins. Every plugin adds overhead to the server tick. Audit your plugin list regularly. If a plugin has not been updated in over a year, find an alternative. Consolidate plugins where possible -- EssentialsX alone replaces what used to require 10+ separate plugins.
Not setting a world border. Without a world border, a single player can fly to coordinates in the millions, forcing the server to generate (and store) an effectively infinite world. Set a border appropriate for your server's lifespan.
Ignoring autosave settings. The default autosave configuration tries to save all chunks every 5 minutes, which can cause lag spikes. Spread saves across ticks using Paper's max-auto-save-chunks-per-tick setting.
Running heavy operations on the main thread. If you write custom plugins or scripts, never perform database queries, HTTP requests, or file operations on the main server thread. Use async tasks. The main thread has only 50ms per tick to work with.
Skipping updates. Paper and its forks release performance improvements regularly. Staying on an outdated build means missing free performance gains. Update during maintenance windows and test thoroughly.
Putting It All Together
Server optimization is not a one-time task. It is an ongoing process of measuring, adjusting, and monitoring. Start with the highest-impact changes: choose Paper or Purpur, apply Aikar's flags, reduce view-distance and simulation-distance, and pre-generate your world. Then use spark to identify your specific bottlenecks and address them one at a time.
The difference between an optimized and unoptimized server is dramatic. A well-tuned Paper server on modest hardware (4 cores, 8GB RAM) can comfortably handle 40-50 players at a steady 20 TPS. The same hardware running vanilla with default settings might struggle with 15 players. Every optimization compounds, so invest the time upfront and your players will thank you with longer session times and fewer complaints about lag.
Recommended Hosting for Minecraft
Our top picks based on performance testing and user reviews.