To troubleshoot Minecraft server lag with spark, first determine what is degrading: the network connection, the server tick loop, or both. Measure TPS, MSPT, and ping; profile the problem window; inspect work on the Server thread; make one change; and repeat the same measurement. High ping is not fixed by removing plugins, and 20 TPS does not rule out short spikes that players can feel.
Quick answer: if the server stays near 20 TPS with MSPT below 50 ms while one or more players have high ping, investigate the network path and client first. If MSPT exceeds 50 ms and TPS drops, the server is missing its tick budget: profile the main thread to locate the workload. These are diagnostic signals, not standalone proof, and both problems can happen at the same time.
Before profiling: what spark measures
Minecraft targets 20 ticks per second. To maintain that rate, each tick has a 50-millisecond budget. TPS describes the achieved tick rate; MSPT describes how long tick work takes. spark recommends considering the distribution—such as median, 95th percentile, and maximum—instead of making a decision from one average. See spark’s official explanations of TPS and MSPT and the tick loop.
| Symptom | Useful metric | Next test | Initial action |
|---|---|---|---|
| Rubber-banding blocks, frozen mobs, delayed commands | MSPT and TPS | Profile the Server thread | Locate work consuming the tick budget |
| Only some players experience delay or disconnects | Per-player ping | Compare players, locations, and times | Check the client, Wi-Fi, route, and packet loss |
| Short freezes while metrics usually look normal | Maximum, p95, and tick monitor | Capture only slow ticks | Look for scheduled tasks, saves, chunk generation, or GC |
| Lag while exploring new terrain | MSPT during exploration | Reproduce the route in a controlled profile | Examine chunk generation/loading and simulation distance |
| Lag began after an install or update | Before/after comparison | Controlled rollback | Revert one modification and measure again |
Prerequisites, compatibility, and backups
- Console access or an account with spark permissions.
- A representative test window with players and the workload that triggers the issue.
- A verified backup of worlds, configuration, and the plugin or mod list.
- The exact server platform and version.
Paper 1.21 and newer include spark, so you normally do not need another JAR. If you want Paper to use the external spark plugin, its documentation specifies the following Java system property. Fully restart the server; do not use /reload.
java -Dpaper.preferSparkPlugin=true -jar paper.jar --nogui
For Bukkit, Fabric, Forge, or NeoForge, download the build matching your platform from the official spark download page. With the server stopped, place the JAR in plugins/ for Bukkit platforms or mods/ for mod loaders, then start the server again. Do not mix builds or infer support from a fork’s name; verify the exact platform and version you run. The official installation documentation contains the maintained instructions.
To roll back an external installation, stop the server, remove the JAR you added, restore changed configuration or your backup if necessary, and restart. Do not delete worlds as part of troubleshooting.
Minimum permissions
The general permission is spark. For limited access, spark documents granular permissions including spark.tps, spark.healthreport, spark.ping, spark.profiler, and spark.tickmonitor. Restrict profile creation and sharing to administrators: reports can expose plugin names, configuration, and other operational details.
Step 1: record a baseline
Write down the time, online players, action that reproduces lag, panel CPU and memory usage, server version, and recent changes. Then run:
text
/spark tps
/spark health
/spark tps reports tick rate and tick-duration metrics. /spark health provides a health summary. If you need to share that report, /spark health --upload uploads it to spark’s service. Review the link before sharing and treat it as operational information; do not assume guarantees about privacy, indexing, or expiry.
text
/spark health --upload
Record median, p95, and maximum values. A healthy median alongside a high maximum is consistent with spikes; an average alone does not prove that everything is fine.
Step 2: separate high ping from tick lag
text
/spark ping
/spark ping --player PlayerName
If TPS remains near 20 and MSPT stays below 50 ms while ping is high, investigate network latency, packet loss, Wi-Fi, the route between the player and data center, client upload saturation, and concurrent downloads. Compare multiple players and time windows. One ping reading does not identify the cause, and a poor connection can coexist with slow ticks.
If MSPT exceeds the 50 ms budget and TPS drops, continue with the profiler. On Paper, /timings is deprecated; spark is the current tool identified in Paper’s command reference.
Step 3: capture a representative sample
Start profiling shortly before reproducing the problem and stop afterward. Avoid an unstructured profile that runs for hours: a huge sample can blend unrelated server states and hide the useful event.
text
/spark profiler start
/spark profiler info
/spark profiler open
/spark profiler stop
stop ends the profile and uploads the result for use in the viewer. If you do not want to upload the capture, use cancel to discard it or save the profile locally:
Does your server need more headroom for spikes?
Choose resources that fit your version, plugins, and player count, then measure again with spark after migrating.


text
/spark profiler cancel
/spark profiler stop --save-to-file
You can also cap the duration:
text
/spark profiler start --timeout 120
Start with the default profiler for general diagnosis. --thread * expands sampling to all threads; use it when you need to investigate asynchronous work or do not know where the issue occurs. --alloc profiles memory allocations and adds overhead, so it is not the first step for every lag report.
text
/spark profiler start --thread *
/spark profiler start --alloc
Step 4: capture intermittent lag spikes
To receive notices when a tick crosses a 50 ms threshold:
text
/spark tickmonitor --threshold-tick 50
To profile only ticks that exceed a chosen threshold, use spark’s current documented syntax:
text
/spark profiler start --only-ticks-over 100
Choose the threshold based on the symptom. A 100 ms value targets ticks taking at least twice the normal budget. Reproduce the event—teleportation, exploration, an active farm, a save, or a scheduled task—and stop after capturing several examples. The official Finding lag spikes guide explains this workflow.
Step 5: read the viewer without blaming the first name
- Open the Server thread when investigating tick lag.
- Look for wide branches or a meaningful percentage during the problem window.
- Expand the branch until you reach methods or tasks you can relate to a mechanic, plugin, mod, entity, or chunk workload.
- Compare it with the exact time and scenario you reproduced.
Seeing parked or waitForNextTick can be healthy: the thread completed its work and is waiting for the next tick. The Sources view groups samples by source, but a plugin appearing at the top does not establish causality. It might be calling server code, responding to another workload, or simply be prominent in a biased sample. spark is a sampling profiler: it shows where samples were observed, not an exact CPU invoice or automatic proof of fault. Refer to spark’s official viewer guide for its views.
Patterns that support the next test
- Plugin or mod: disable it only on a test copy or during a controlled window, preserve its data, and repeat the same scenario. Updating to a compatible release is usually safer than deleting configuration blindly.
- Entities or block entities: identify the world and area; inspect farms, hoppers, villagers, redstone, and accumulations. Never run mass-removal commands without a backup.
- Chunk generation or loading: compare new terrain with generated chunks; review view and simulation distances, and do not assume more threads will fix main-thread work.
- Saves, backups, or scheduled tasks: correlate the spike with the schedule. Move heavy jobs outside active hours and measure again.
- GC or allocations: confirm the pattern with memory metrics and, only when needed, an allocation profile. Do not change Java flags based on one capture.
Change one variable and validate
An optimization without a comparison is a guess. Keep the baseline, make one reversible change, and repeat the same workload in a comparable window. Verify:
- TPS stays near its target under a similar player count.
- Median, p95, and maximum MSPT improve.
- Fewer ticks cross the monitor threshold.
- No new console errors appear.
- Mechanics, plugins, mods, and saves still work correctly.
If performance worsens or a regression appears, restore the previous file or configuration, perform a clean restart, and confirm metrics return to baseline. Do not use /reload to validate plugin changes.
Common spark problems
“Unknown command”
Confirm the platform, version, and whether spark loaded. On Paper 1.21 or newer, try from the console. For an external plugin, confirm that the JAR is in the right directory and the server received a full restart. Check startup logs for load errors.
The command works, but a player cannot use it
Run it from the console or grant only the required granular permission. Verify the permissions manager is applying the permission in the correct context and world.
The profile missed the spike
Shorten the window, start before the reproducible event, or use --only-ticks-over. Repeat the test: intermittent spikes often require multiple comparable captures.
The native profiler does not start
spark documents a Java sampler fallback. Use it when the environment cannot run the native profiler:
text
/spark profiler start --force-java-sampler
Maintenance that prevents surprise lag
- Record a fresh baseline after major updates.
- Keep server, Java, plugin, and mod versions with each report.
- Schedule backups and heavy jobs outside player peaks.
- Test updates in staging or on a copy before production.
- Profile again when workloads change; an old report may not describe the current server.
When selecting or migrating infrastructure, size the server for its actual workload rather than slot count alone. Modpacks, simulation distance, chunk generation, and plugins can change tick cost dramatically. Use our published guide to the best Minecraft modpacks as a reference for comparing different workloads.
Frequently asked questions
Does 20 TPS mean the server has no lag?
Not always. Short spikes can be hidden by an aggregate reading, and network lag can exist while the tick loop is healthy. Check MSPT, p95, maximum, and ping during the incident.
How long should the profiler run?
Long enough to capture the representative event several times, not for an arbitrary duration. One or two minutes may be enough for a reproducible issue; a periodic problem needs a window aligned with its occurrence.
Is the top plugin in Sources the culprit?
Not necessarily. It is a lead for the next test. Inspect the Server thread tree, the implicated method, and its context, then compare controlled conditions before and after the change.
Does spark replace network testing?
No. spark helps observe server performance and player ping, but packet loss and a poor route require additional network tests from the affected endpoints.
Conclusion
The useful output of spark is not a link full of percentages; it is a testable hypothesis. Preserve a baseline, capture the right symptom, connect an expensive branch to real activity, and validate a reversible change. That tells you whether to tune software, reduce a specific workload, investigate the network, or resize the server—without turning troubleshooting into plugin roulette.








