The short version

The fastest way to fix Minecraft server lag is to identify which kind of lag you have, record a profile while it is happening, and change one suspected cause at a time. Do not begin by buying more RAM or pasting a list of JVM flags. Low client FPS, high network latency, and low server TPS have different causes, so the wrong fix can waste money or make the server harder to diagnose.

Before changing server software, plugins, mods, world files, or configuration, stop the server cleanly and make a restorable backup. Paper’s own basic troubleshooting guide warns that editing server files while it is running can corrupt them and recommends testing on a copy when possible. Our backup and world migration guide covers the safe process in detail.

Identify the type of lag first

Ask what players actually see. “It lags” is not a diagnosis.

Symptom Most likely category First check
One player has choppy camera movement, but mobs and other players move normally Client FPS Client graphics, shaders, resource packs, GPU and render distance
Interactions arrive late, players rubber-band, or only distant players complain Network latency or packet loss Ping, route, Wi-Fi, server region and packet loss
Mobs freeze, redstone slows, blocks break late, and everyone notices together Server tick lag TPS, MSPT and a profile captured during the event
Lag begins when players explore new terrain Chunk generation or storage Profile during exploration; disk and CPU activity
Short freezes repeat every few minutes Garbage collection, saves, backups, or a scheduled task GC pauses, save timing, disk I/O and task schedule
Lag starts near a farm, trading hall, storage system, or specific base Entities, block entities, hoppers, redstone, or a plugin in that area Profile in that location and compare entity/chunk counts
Lag appeared after an update or new add-on Plugin, mod, datapack, or version mismatch Logs, profile, changelogs and a controlled rollback

For client FPS, test the same player on another server and have another player visit the same location. If the first player alone is affected, lowering shaders, particles, client render distance, or resource-pack complexity is more relevant than changing the server.

For network lag, compare a wired connection with Wi-Fi, test more than one player, and note their physical distance from the server. A server can hold 20 TPS while a player with packet loss still rubber-bands. Moving the server closer may improve latency; adding RAM will not.

Understand TPS and MSPT

Minecraft normally targets 20 ticks per second (TPS). Each tick therefore has a 50 millisecond time budget. MSPT is the time the server spends processing a tick. Sustained MSPT above 50 means the server cannot maintain 20 TPS; occasional spikes can still cause visible stutters even when the average looks healthy.

Treat TPS as the alarm and MSPT as a measure of severity, not as the root cause. “TPS is 14” tells you that the server is behind. A profiler tells you whether the time is going into a plugin, mob pathfinding, chunk generation, saves, garbage collection, or something else.

Measure during a normal busy session and during the bad behavior. An empty-server report can look perfect while completely missing the farm or plugin task that causes the problem. Record the player count, affected world and location, software build, Java version, installed plugins or mods, and the approximate start time. That makes before-and-after comparisons useful.

Capture a spark profile while the lag happens

Paper 1.21 and newer bundles spark and calls it the preferred profiler. Paper’s profiling documentation also notes that the problem must be active while profiling. For a broad ten-minute sample, run from the console or as an operator:

/spark profiler start --timeout 600

For intermittent long ticks, Paper’s troubleshooting documentation gives this focused example:

/spark profiler start --only-ticks-over 100 --timeout 300

Open the generated report and start with the server thread. Wide or high-cost branches identify where time is being spent. Look for recognizable plugin or mod names, chunk generation, entity ticking, scheduled tasks, world saving, or garbage-collection pauses. Do not blame the first unfamiliar Java method: follow the costly branch until it reaches a component or activity you can test.

Paper has deprecated Timings in favor of spark, so an old guide that begins with /timings on is no longer the best default for current Paper. On Fabric, Forge, or NeoForge, install a compatible spark build if your platform does not bundle it, following the spark project’s current installation and command documentation.

A profiler link can reveal server details such as versions and installed add-ons. Review it before posting publicly. If you cannot interpret the result, provide the report, exact symptom, time window, and changes already tested to the relevant plugin, mod, host, or Paper support channel.

Test the likely cause, not every setting

Once the profile points to an area, use the smallest reversible test that can confirm it.

Plugins, mods, and datapacks

Update only after reading compatibility notes and taking a backup. If one add-on dominates the profile, reproduce the issue on a test copy without it. When no single name is obvious, disable half of the suspected add-ons, test, and repeat with the affected half. Paper recommends this binary-search method for plugin-induced issues; keep dependencies such as library plugins with the plugins that require them.

Do not remove add-ons from the live world casually. Mods and plugins can own custom items, blocks, data, or configuration. A staging copy lets you discover data-loss or compatibility problems without putting the real world at risk.

If you are deciding whether a plugin-oriented platform is appropriate in the first place, see Paper vs Spigot vs Purpur. Changing server implementations can alter mechanics, so it should not be a blind performance switch.

Chunks and exploration

If lag follows fast travel into unexplored terrain, profile while a player repeats that action. New chunk generation costs CPU and writes data to storage. Existing-chunk loading can also expose slow or saturated storage.

Paper documents /paper chunkinfo [<world>] for seeing loaded chunk states and /paper holderinfo [<world>] for in-memory chunk holders in its command reference. Counts alone do not prove a problem, but a profile showing chunk work plus an unusual count is a strong lead.

As a controlled test, slightly reduce view-distance or simulation-distance, restart, and repeat the same route. Paper’s server.properties reference explains the difference: view distance controls how much world data is sent, while simulation distance controls the radius in which living entities are updated. Lower values trade sight range or active-world behavior for less work. Record the original values and do not copy extreme settings from an optimization paste.

Pre-generating the playable area can move generation work to a maintenance window, but it consumes storage and CPU upfront. Set a sensible world border, back up first, and use a maintained tool compatible with your exact server version.

Entities, block entities, farms, and redstone

When lag is location-specific, compare the profile outside and inside the affected area. Paper’s current command reference documents /paper entity list [<filter>] [<world>] for counting ticking and non-ticking entity types. Large villager halls, dropped-item accumulation, mob farms, minecarts, hoppers, and always-running redstone can all be relevant, but only change the system implicated by the profile.

Fix the build before imposing a server-wide nerf: add an off switch to a clock, prevent item overflow, reduce unnecessary chunk loading, or separate densely packed entities. Global activation-range or spawning changes can break farms and surprise players. Paper explicitly cautions that copied “optimized” configurations can change entity, farm, redstone, and spawning behavior.

Memory and garbage collection

High memory use by itself is not a fault. Paper explains that a Java heap normally grows and that the process may not return that memory to the operating system. Evidence of a memory problem is repeated long GC pauses, an out-of-memory error, the process being killed by its container, or heap pressure that persists under the real workload.

Use spark’s health and profiler data to inspect GC behavior. Leave memory for the operating system, panel, and native allocations rather than setting -Xmx equal to the machine or container limit. For workload-based allocation guidance, use the canonical Minecraft server RAM guide instead of assuming every lag problem needs another gigabyte.

CPU, disk, saves, and host contention

Minecraft can be main-thread limited even when the host’s total CPU meter looks low. Paper notes that much of the tick loop runs on one thread, so total utilization across many cores can hide a saturated main thread. A faster single core or less work per tick can matter more than adding unused cores.

If spikes align with autosaves, backups, map rendering, or chunk generation, inspect storage latency and free space. Do not run compressed backups, antivirus scans, world renders, and heavy saves at the same time. On shared hosting, collect timestamps and spark reports, then ask the provider to check CPU throttling, noisy neighbors, or storage latency; those constraints may be invisible inside the panel.

Apply fixes with a before-and-after test

Use this loop for every candidate fix:

  1. Save a backup and write down the current configuration.
  2. Reproduce the lag with a defined route, player count, or farm state.
  3. Capture TPS, MSPT, a spark report, and the time of the test.
  4. Make one reversible change.
  5. Restart cleanly; Paper does not support /paper reload as a substitute for reproducing on a fresh start.
  6. Repeat the same test and compare the evidence.
  7. Keep the change only if it improves the result without unacceptable gameplay differences.

Avoid changing Java flags, distances, entity activation, plugin versions, and server software all at once. If performance improves, you will not know why; if something breaks, rollback becomes much harder. JVM flags can be useful in a documented setup, but they cannot repair a plugin spending too long on the main thread, a disk stalling during saves, or a farm ticking thousands of entities.

Bottom line: separate FPS, network, and tick lag; profile the server while the problem is visible; confirm the expensive component with one controlled change; then verify the same workload again. That process is slower than applying a “zero-lag” config pack once, but it produces a fix you can explain, measure, and safely keep.