Minecraft Server: Lag and Performance — Fix

The Problem

Your Minecraft server is lagging — players experience rubber-banding, delayed block breaking, slow inventory updates, or choppy entity movement. The server TPS (ticks per second) drops below the ideal 20 TPS, and the console may show “Can’t keep up! Is the server overloaded?” warnings.

Updated March 2026: Verified with latest Docker images and configurations.

Quick Diagnosis

Check your server’s TPS first. This tells you whether the issue is server-side or client-side:

In-game (with operator permissions):

/debug start
# Wait 10 seconds
/debug stop

With Paper/Spigot:

/tps
TPSStatusCause
20.0PerfectNo server-side lag
18-19.9GoodMinor fluctuations, acceptable
15-17.9NoticeablePlayers feel slight delay
10-14.9BadSignificant rubber-banding
<10UnplayableServer is overloaded

If TPS is 20 but players report lag: The issue is network latency (client-server ping), not server performance. Check player ping with /ping <player> on Paper servers.

The Fix

Method 1: JVM Memory and Garbage Collection

The single biggest performance improvement for most servers is proper JVM tuning. Default Java settings waste memory and cause GC (garbage collection) pauses that freeze the server for 50-200ms.

Recommended JVM flags for Paper/Spigot (Aikar’s flags):

java -Xms6G -Xmx6G \
  -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 rules:

  • -Xms and -Xmx must be equal — prevents the JVM from constantly resizing the heap
  • Don’t allocate more than 10-12 GB — larger heaps cause longer GC pauses
  • Don’t allocate less than 4 GB for 10+ players

For Docker Compose, set in environment:

services:
  minecraft:
    image: itzg/minecraft-server:java21
    environment:
      MEMORY: "6G"
      JVM_XX_OPTS: "-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"

Method 2: Use Paper Instead of Vanilla

Paper (fork of Spigot, which is a fork of CraftBukkit) includes hundreds of performance optimizations that the vanilla server lacks. Switching from Vanilla to Paper typically doubles your TPS capacity with the same hardware.

Switch in Docker:

services:
  minecraft:
    image: itzg/minecraft-server:java21
    environment:
      TYPE: PAPER
      VERSION: "1.21.4"

Paper’s key optimizations:

  • Async chunk loading (vanilla loads chunks on the main thread)
  • Entity activation ranges (entities far from players tick less frequently)
  • Optimized redstone processing
  • Reduced hopper lag
  • Better mob spawning algorithms

Method 3: Reduce View Distance and Simulation Distance

View distance controls how many chunks are loaded. Each additional chunk loaded costs CPU and RAM. The default (10 chunks) is overkill for most servers.

In server.properties:

view-distance=8          # Default 10 — reduce to 6-8
simulation-distance=6    # Default 10 — reduce to 4-6

Impact:

View DistanceChunks Loaded (per player)RAM per Player
10 (default)441~200 MB
8289~130 MB
6169~75 MB
481~35 MB

Reducing view distance from 10 to 6 cuts chunk processing by 62%. Players rarely notice the difference — client-side rendering fills in the gap.

Method 4: Optimize Paper/Spigot Configuration

spigot.yml — entity activation ranges:

world-settings:
  default:
    entity-activation-range:
      animals: 16       # Default 32
      monsters: 24      # Default 32
      raiders: 48       # Default 48
      misc: 8           # Default 16
      water: 8          # Default 16
      villagers: 16     # Default 32

paper-world-defaults.yml — reduce entity processing:

entities:
  spawning:
    per-player-mob-spawns: true    # Default true (Paper)
    mob-spawner-tick-rate: 2       # Default 1 — doubles spawner efficiency
  behavior:
    disable-chest-cat-detection: true  # Saves entity scanning

bukkit.yml — reduce mob counts:

spawn-limits:
  monsters: 50       # Default 70
  animals: 8         # Default 10
  water-animals: 3   # Default 5
  ambient: 1         # Default 15

Method 5: Pre-Generate Chunks

Chunk generation is the most CPU-intensive operation. Pre-generating the world eliminates lag spikes when players explore new areas.

With Chunky plugin (Paper/Spigot):

/chunky radius 5000
/chunky start

This generates all chunks within 5,000 blocks of spawn. Let it run overnight — generation speed varies but typically processes 100-500 chunks per second.

Method 6: Hardware Optimization

Minecraft servers are single-threaded for the main game loop. Clock speed matters more than core count.

BottleneckSolution
CPU (most common)Higher clock speed CPU. Intel i5/i7 or AMD Ryzen 5/7.
RAM4 GB minimum, 6-8 GB recommended for 10-20 players
Disk I/OSSD required. HDD causes chunk load lag. NVMe ideal.
Network100 Mbps sufficient. Latency matters more than bandwidth.

VPS recommendations for Minecraft:

PlayersCPURAMCost
1-52 vCPU4 GB$10-15/month
5-154 vCPU8 GB$20-30/month
15-304-6 vCPU12-16 GB$30-50/month
30+Dedicated server32+ GB$50-100/month

Prevention

  1. Use Paper — not Vanilla. The performance difference is dramatic.
  2. Set Aikar’s JVM flags from day one — not after lag appears
  3. Pre-generate your world before inviting players
  4. Monitor TPS — install a monitoring plugin and alert on TPS < 18
  5. Limit entity farms — mob farms and hopper chains are the #1 cause of lag on established servers. Use entity-activation-range settings aggressively.
  6. Set a world border — prevents infinite world growth. Use /worldborder set 10000 for a reasonable play area.
  7. Regular restarts — schedule daily restarts to clear memory leaks. Most Docker setups can use a cron job to docker compose restart minecraft at 4 AM.

Comments