
Quick answer: install spark, run /spark health --upload, turn on /spark tickmonitor --threshold-tick 50, then profile only slow ticks with /spark profiler start --only-ticks-over 100 --timeout 120. The viewer tells you whether TPS loss comes from chunk generation, entities, plugins, garbage collection, or one bad mod.
The 10-minute spark diagnosis workflow
| Step | Command | What it tells you |
|---|---|---|
| 1 | /spark health --upload | TPS, CPU, memory, disk and general server health in one shareable link |
| 2 | /spark tps | Current TPS and CPU usage without starting a full profile |
| 3 | /spark tickmonitor --threshold-tick 50 | Which ticks exceed 50ms, the point where 20 TPS starts falling behind |
| 4 | /spark profiler start --only-ticks-over 100 --timeout 120 | Samples only slow ticks so normal background work does not hide spikes |
| 5 | /spark profiler stop | Uploads the profile and opens the viewer link |
| 6 | /spark gc | Garbage collection history, useful when lag appears every few minutes |
| 7 | /spark heapsummary | Finds memory-heavy object groups without creating a huge heapdump |
On BungeeCord, Velocity and Forge/Fabric client installs, spark uses /sparkb, /sparkv, and /sparkc instead of plain /spark.
Install spark safely
Download spark from the official project page or your loader/plugin marketplace. Use the build that matches your server software: Paper/Purpur plugin, Fabric mod, Forge/NeoForge mod, Velocity plugin, or BungeeCord plugin.
After restart, confirm it loads:
/spark health
/spark tps
Give staff only the permissions they need: spark.healthreport, spark.tps, spark.tickmonitor, spark.profiler, spark.gc, spark.heapsummary, and spark.heapdump. Avoid giving heapdump access to random helpers because heap dumps can contain sensitive data.
Use tickmonitor before profiling
Normal profiling averages everything together. That hides one-tick spikes. The official spark lag-spike workflow starts with tickmonitor because it separates slow ticks from normal ticks.
/spark tickmonitor --threshold-tick 50
If your chat fills too fast, raise it to 75 or 100. If players feel spikes but spark prints nothing, lower it. When the spike appears, note the rough tick duration, then profile slower ticks only.
/spark profiler start --only-ticks-over 100 --timeout 120
/spark profiler stop
Use a threshold lower than the bad tick but above normal tick time. For example, if spikes hit 250ms, --only-ticks-over 100 catches them without filling the report with healthy ticks.
How to read the spark viewer
| What rises to the top | Likely cause | First fix |
|---|---|---|
| Chunk generation or world noise | Players exploring new terrain | Pregenerate world, lower view distance, add world border |
| Entity AI/pathfinding | Mob farms, villagers, too many Pokemon/entities | Entity caps, farm rules, region cleanup |
| Plugin listeners | One plugin doing heavy work on events | Update, reconfigure, replace, or report with profile link |
| Storage saves | Slow disk or massive region saves | Move to NVMe, check backups, reduce sync-heavy tasks |
| Garbage collection | Heap too large, memory leak, wrong flags | Right-size RAM, use Java 21, inspect /spark gc |
| Network/ping not TPS | Player route or DDoS issue | Check /spark ping, move host closer, add protection |
Do not blame the first plugin name you see. Open the hot path and look for the deepest repeated work. A plugin can appear because Minecraft called it during the real bottleneck.
Modded server checklist
For ATM10, Cobblemon, Create-heavy packs, and public SMPs, run a spark profile while players do the thing that hurts: exploring, battling, opening storage, flying, running farms, or loading a town.
- Profile during real lag, not an empty server.
- Keep the run short: 60-180 seconds is usually enough.
- Save the viewer link before changing settings.
- Change one thing, restart, profile again.
Useful follow-up guides: ATM10 lag fix, Cobblemon server optimization, and Minecraft server requirements.
