Minecraft Server Optimization Guide: Fix Lag and Improve Performance

Bernis ·

Server lag is the number one complaint from Minecraft players. If your server is dropping below 20 TPS, chunks are loading slowly, or players are experiencing rubber-banding, this guide will help you diagnose and fix the most common performance issues.

Measure First

Before optimizing, you need to know what’s actually causing lag. Use these tools:

  • /tps — Shows your server’s TPS (ticks per second). A healthy server runs at 20.0 TPS. Below 18 is noticeable lag, below 15 is unplayable.
  • Spark profiler — The best tool for diagnosing performance issues. Install the Spark plugin and run /spark profiler to see what’s consuming the most processing time.
  • Timings report — Paper and Spigot have built-in timing reports (/timings on, wait a few minutes, /timings report). Useful but Spark is generally more helpful.

Choose the Right Server Software

If you’re running Vanilla, switch to Paper. This single change can double your performance. Paper includes hundreds of optimizations that Mojang’s server doesn’t have.

Performance ranking (best to worst):

  1. Purpur — Paper fork with extra optimizations and configurability
  2. Paper — The standard for performance. Recommended for most servers.
  3. Spigot — Decent but Paper is strictly better
  4. Vanilla — No optimizations. Only use if you specifically need vanilla parity.

For modded servers, Fabric with Lithium + Starlight provides the best performance. Forge is heavier but necessary for certain mods.

JVM Flags

The JVM flags you use to start your server have a significant impact on performance. The most important optimization is using the Aikar’s flags, which are tuned specifically for Minecraft servers.

-Xms{RAM}M -Xmx{RAM}M -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

Replace {RAM} with your allocated RAM in MB. Important: Set -Xms and -Xmx to the same value. This prevents the JVM from constantly resizing the heap, which causes lag spikes.

If you’re using FadeHost, these flags are already configured by default on Paper and Purpur servers.

Paper Configuration Tweaks

Paper has two config files with performance-relevant settings: paper-global.yml and paper-world-defaults.yml.

Key settings in paper-world-defaults.yml

Chunk loading:

  • chunks.max-auto-save-chunks-per-tick: 8 — Reduce to 4-6 if you have many loaded chunks
  • chunks.entity-per-chunk-save-limit — Limit entities saved per chunk to prevent entity buildup

Entity optimization:

  • entities.spawning.per-player-mob-caps: true — Distributes mob caps per player instead of globally. Huge improvement for multiplayer.
  • entities.spawning.monster-spawn-range: 6 — Reduce from default 8 to lower mob processing overhead
  • entities.behavior.pillager-patrols.disable: true — Disable if you don’t need pillager patrols

Redstone:

  • misc.redstone-implementation: ALTERNATE_CURRENT — Faster redstone processing with identical behavior for most builds

Key settings in spigot.yml

  • merge-radius.item: 4.0 — Merges nearby dropped items to reduce entity count
  • merge-radius.exp: 6.0 — Merges nearby XP orbs
  • mob-spawn-range: 6 — Match with Paper’s monster-spawn-range

Key settings in bukkit.yml

  • monster-spawns: 2 — Reduce from default 1 (ticks between spawn cycles). Higher = less frequent spawning = better performance
  • animal-spawns: 400 — Animals don’t need frequent spawn checks
  • ambient-spawns: 40 — Bats are purely cosmetic, spawn them rarely

Reduce Loaded Chunks

The more chunks loaded, the more work the server does every tick. Control this with:

  • view-distance in server.properties — How many chunks the server processes. Default 10 is high for most servers. Try 6-8.
  • simulation-distance — How far entities are ticked. Set to 4-6 for good performance with reasonable gameplay.
  • no-tick-view-distance in Paper — Lets players see further without the server processing those chunks. Set this to 10-12 while keeping simulation-distance at 4-6. Best of both worlds.

Plugin Optimization

Plugins are often the biggest source of lag after chunk loading.

Find the culprits: Run Spark profiler (/spark profiler --timeout 300) for 5 minutes during normal gameplay. Check which plugins appear in the hot paths.

Common plugin performance issues:

  • Dynmap — World rendering is extremely CPU-intensive. Limit render threads and use a generous render interval.
  • Citizens/NPC plugins — Each NPC is a full entity. Minimize NPCs in loaded chunks.
  • WorldGuard with many regions — Region checks on every block interaction add up. Simplify overlapping regions.
  • Logging plugins — Plugins that log every block break/place generate massive I/O. Use async logging or limit what’s tracked.
  • Chat plugins with formatting — Plugins that process every chat message with regex or API calls can cause chat lag.

General plugin advice:

  • Don’t install plugins you don’t actively use
  • Keep plugins updated — newer versions often have performance fixes
  • Prefer plugins that do work asynchronously
  • One plugin that does 3 things is better than 3 plugins that each do 1 thing

Pre-generate Your World

New chunk generation is the most CPU-intensive operation in Minecraft. Pre-generating your world eliminates this entirely for explored areas.

Use Chunky (Paper plugin) to pre-generate:

/chunky radius 5000
/chunky start

This generates all chunks within 5000 blocks of spawn. It will take a while but dramatically improves performance once complete.

Set a World Border

Without a world border, players can explore infinitely, generating new chunks forever and growing your world file. Set a reasonable border:

/worldborder center 0 0
/worldborder set 10000

This gives a 10,000 x 10,000 block play area (more than enough for most servers) and prevents infinite world growth.

Monitor and Iterate

Optimization isn’t a one-time thing. As your player count grows and you add plugins or mods, new bottlenecks appear. Regular monitoring helps you stay ahead of problems:

  • Check TPS daily — if it’s trending downward, investigate
  • Run Spark profiler weekly to catch new issues
  • Watch RAM usage — if it’s consistently above 80%, add more RAM
  • Keep an eye on world file size — large worlds mean more disk I/O

Need a server that’s already optimized out of the box? FadeHost servers come pre-configured with Aikar’s flags, and you can add RAM instantly when you need it. Get started today.