When a Minecraft server experiences degradation and Ticks Per Second (TPS) drops below the stable 20.0 target, administrators frequently attempt unguided optimizations, blindly reducing render distance or removing plugins. True performance tuning requires empirical profiling of the primary server tick loop. The Spark profiler is the modern industry standard performance diagnostic tool across Paper, Purpur, Fabric, and Forge servers, replacing the deprecated Timings suite.
This guide covers installing Spark, capturing CPU sampling snapshots on the main server thread, interpreting MSPT metrics, and isolating concrete performance bottlenecks such as hoppers, entity pathfinding, and redstone clocks.
Why Spark Outperforms Legacy Timings#
The legacy /timings utility suffered from two major architectural shortcomings: it imposed measurable CPU profiling overhead on the active tick loop, and it aggregated runtime metrics into broad Bukkit task buckets rather than granular Java call stacks.
Spark advantages:
- Low-Overhead Sampling: Spark leverages native JVM profiling hooks (Async-profiler on Linux), interrogating execution call stacks at microsecond intervals without freezing server ticks.
- Focus on MSPT (Milliseconds Per Tick): TPS is a lagging indicator that remains frozen at 20.0 as long as a frame completes within 50 milliseconds. MSPT exposes true frame latency: an increase from 18 ms to 45 ms warns you that the server is nearing an imminent tick drop, even while TPS reads 20.0.
- Deep Garbage Collection and Heap Inspection: Spark tracks memory allocation churn and Stop-The-World pause durations, pinpointing leaky third-party plugins.
Installing Spark and Capturing CPU Samples#
Download the latest production build of the Spark plugin for Paper/Purpur into the plugins/ directory:
cd /opt/minecraft/plugins
wget https://spark.lucko.me/download/bukkit -O spark.jar
Restart the daemon to initialize the plugin:
sudo systemctl restart minecraft
sudo journalctl -u minecraft -n 30 --no-pager | grep -i "spark"
For an immediate health check of the server environment, execute:
/spark health --memory
This command reports 5-second, 1-minute, and 15-minute TPS trends, average and maximum MSPT figures, and active Java heap utilization.
To capture actionable performance metrics, run the sampler during peak player concurrency:
/spark sampler --timeout 180
This initiates profiling for 3 minutes (180 seconds). Once sampling completes, Spark outputs a secure web URL linking to an interactive flame graph viewer.
Reading Spark Profiles: MSPT Analysis and Call Trees#
Open the generated report URL in your browser. The initial overview presents an MSPT timeline across the sampling window:
- Values under 40 ms (green zone) indicate healthy headroom.
- Values between 40 and 50 ms (yellow zone) indicate high resource consumption.
- Values above 50 ms (red zone) signify missed ticks and noticeable player lag.
Navigate to the Call Tree tab and focus on the Server thread branch:
- Expand
net.minecraft.server.MinecraftServer.tickServer(). - Locate
net.minecraft.world.level.Level.tick()representing active world contexts (world,world_nether,world_the_end). - Check execution percentages: if a single world accounts for 85% of total tick time, the lag source is isolated to that specific dimension.
On an automated server management panel, MSPT trends and tick drop alarms are monitored continuously, notifying you of degradation before community members encounter rubberbanding.
Isolating Common Bottlenecks: Hoppers, Entities, and Redstone#
The Spark call tree clearly isolates the three most prevalent culprits of server lag:
Entity Ticking (
tickEntities):- If
net.minecraft.world.entity.animal.Villager.tick()consumes over 20% of the tick, villager trading halls and pathfinding AI are overwhelming the thread. Limit villager densities viapaper-world-defaults.yml. - High time inside
Entity.move()indicates overcrowded mob farms colliding inside tight spaces.
- If
Item Hoppers (
blockEntities / Hopper):- Empty hoppers constantly searching for floating item entities cause heavy CPU overhead, visible as
HopperBlockEntity.tick(). - Optimize hoppers inside
paper-world-defaults.yml:hopper: cooldown-when-full: true disable-move-event: true
- Empty hoppers constantly searching for floating item entities cause heavy CPU overhead, visible as
Redstone Clocks and Chunk Loaders:
- Dominant
RedstoneWire.updateSurroundingNeighbors()methods indicate massive redstone circuits or rapid-firing pulse generators.
- Dominant
Inspecting Garbage Collection and Heap Leaks#
If the report displays sharp MSPT spikes exceeding 200–500 ms at regular intervals, JVM Stop-The-World garbage collection pauses are the culprit.
Analyze heap allocations and GC cycles directly:
/spark heapsummary
/spark gc
The heapsummary command reports which Java classes retain the largest byte shares in RAM. If millions of instances belong to a third-party plugin, update or replace it. Pair this with Aikar's JVM flags to guarantee low-pause G1GC execution.




