Record server activity with Spark
Paper documents Spark as the preferred profiler and bundles it starting with 1.21.
A profile records where the server spends time. You can also share the report with a plugin author when investigating a problem.
Before you start
Profile only when the issue is happening. A profile recorded without the lag may not capture its cause.
Step 1: Confirm the lag signal
Run:
/spark tps
This gives you the immediate health view and tells you whether you are dealing with sustained low TPS, spikes, or mostly normal behavior.
If you do not currently have practical admin access, set up RCON and console access in Docker first.
Step 2: Start a timed profile
Paper's own example is:
/spark profiler start --timeout 600
That records for ten minutes and then returns a report URL.
Ten minutes is long enough to catch:
- repeating scheduled tasks
- heavy chunk exploration
- farms under real player load
- longer GC patterns
Step 3: Reproduce the actual problem
While the profiler is running, do not leave the server empty unless emptiness is the problem. Let players keep doing the thing that caused the lag:
- exploring new terrain
- using a farm
- entering a busy base
- running a minigame
You want the profile to capture the expensive behavior, not the quiet aftermath.
Step 4: Read the report in the right order
Check:
- overall tick health
- top hot paths or heavy tasks
- plugin-specific or chunk-specific concentration
If one plugin, one subsystem, or one region dominates the report, that is your first real lead.
Step 5: Turn findings into one concrete change
Good first actions are specific:
- lower
simulation-distance - disable one plugin feature
- limit a farm design
- pre-generate chunks before an event
Choose the change from the profile, then repeat the measurement under the same load.
Docker-specific note
Spark runs inside the Paper server process, so Docker does not change the profiling method much. What Docker does change is how you access the console and logs.
Useful commands around a profiling session:
docker compose logs -f mc
docker exec mc rcon-cli "spark profiler start --timeout 600"
Common mistakes
| Mistake | Why it hurts | Better move |
|---|---|---|
| Profiling an idle server | Report misses the real bottleneck | Profile under active load |
| Making many fixes at once | You never learn what mattered | Apply one high-confidence change first |
| Ignoring chunk and entity context | The hot path stays abstract | Relate the report to in-game behavior |
| Treating every red number as equally important | Smaller costs distract from the main bottleneck | Look for dominant consumers first |