Direct answer
Short spikes can disappear in averages. Capture the spike itself: use spark tick monitoring to identify the slow ticks, then profile the affected time window instead of relying on an idle sample.
How to check it
- Write down the clock time and trigger: player join, teleport, backup, save, large redstone activation or sudden mob spawn.
- Run
/spark tickmonitor --threshold-tick 100to report ticks above a chosen threshold; pick a threshold appropriate to your workload. - Use
/spark profiler start --timeout 300ahead of an expected spike. On spark versions supporting it,/spark profiler start --only-ticks-over 50samples ticks exceeding that threshold. - Check the viewer timeline and thread trees around the reported period. Look for chunks, entity AI, scheduled plugin tasks, synchronous disk operations or garbage collection.
- Compare with a control period without the trigger; save the report and server log timestamps together.
What to change
- If the spike correlates with chunk generation, test pregeneration or reduction of unnecessary chunk loads.
- If it correlates with a plugin task or save, adjust that specific workload and contact its author if necessary.
- For GC-related pauses, compare with actual JVM GC logs rather than assuming high heap use means a leak.
Software and version notes
Spark flags and sample labels can differ by installed version. Paper 1.21+ includes spark; on other software make sure an appropriate version is installed. Do not interpret one slow tick as a sustained low-TPS condition.
Verify the result
- Trigger the same action multiple times after a change.
- Compare spike count, duration and maximum/percentile MSPT, not only average TPS.
- Check the player-visible symptom as well as any profiling overhead.