Symptoms: Server-wide slowness, TPS under 20, blocks breaking with a delay, mobs freezing, chunks loading slowly. Lag can come from more than one source (CPU, RAM, disk, network, plugins, entities). This guide gives you a systematic lag fixing routine.

Possible Causes

  • Insufficient hardware — weak single-core CPU performance, too little RAM, or an HDD
  • Bad Java settings — no GC flags, an unsuitable heap value
  • Uncontrolled plugins — heavy work per tick or a DB query on the main thread
  • Entity and chunk overload — no world border, unmanaged mob farms
  • Redstone circuits — complex circuits firing non-stop clog the tick
  • A far too high view-distance / simulation-distance value

Step-by-Step Fix

Step 1

Measure first: TPS with /tps, the detail with /spark tps, and a root cause profile with /spark profiler. Upload the report to the KEYDAL Spark Analyzer and you get a free review

bash
/spark profiler --thread * --timeout 60

Step 2

Lower the view-distance and simulation-distance values. 10 / 6 is a good starting point

bash
# server.properties
view-distance=10
simulation-distance=6

Step 3

If you are still on Spigot, move to Paper or Purpur. Paper gives 40–60% better performance on the same hardware

bash
wget -O paper.jar "https://api.papermc.io/v2/projects/paper/versions/1.21.1/builds/latest/downloads/paper-1.21.1-latest.jar"

Step 4

Start with Aikar's Flags — they tune GC behaviour to the Minecraft workload. Keep the heap at Xms=Xmx

bash
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 paper.jar --nogui

Step 5

Tighten the entity-activation-range values in spigot.yml / paper.yml — distant mobs then burn no ticks

bash
# spigot.yml
entity-activation-range:
  animals: 16
  monsters: 24
  raiders: 48
  misc: 8

Step 6

Pre-generate the world with the Chunky plugin. Runtime chunk generation produces serious lag

bash
/chunky radius 5000
/chunky start

Step 7

Set a WorldBorder and limit the exploration area — the world file stops ballooning and chunk generation stays stable

bash
/worldborder center 0 0
/worldborder set 10000

Step 8

Look at plugin tick time: in the /spark profiler report, either update or replace the plugin burning the most CPU

Step 9

If the disk is an HDD, move to an SSD without exception. Minecraft region I/O is a heavy workload; NVMe is ideal

bash
iostat -x 2 5  # if await values are high, the disk is the bottleneck

Step 10

If TPS is low, find the root cause instead of restarting straight away — otherwise it is back again tomorrow