Benchmark Report
Tick spikes · Mob AI
The worst ticks are several times the mean. Average TPS stays fine while players feel the stutter.
- mspt_avg = 101 ms
- mspt_p99 = 307.52 ms
- spike_ratio = 3.04 ratio
- sample_count = 88 count
Weakest test: Mob AI, 11.01 TPS on average. The 15 other tests hold at least 19.96 TPS.
Compared with other servers
The comparison with other servers uses reports scored with version 8.3.0 of the scoring rules. This report was scored with another version, so its score is not comparable.
What matters
Read from the measurements, never estimatedTick spikes
The worst ticks are several times the mean. Average TPS stays fine while players feel the stutter.
- mspt_avg = 101 ms
- mspt_p99 = 307.52 ms
- spike_ratio = 3.04 ratio
- sample_count = 88 count
Non-default server configuration
Compare with care against a server running default settings.
- view-distance 12 (default 10)
- simulation-distance 4 (default 10)
- spawn-limit.monster 50 (default 70)
+5 more modified settings
CPU quota
The JVM sees far fewer cores than the host advertises. Everything that parallelises is bounded by the container, not by the machine.
Likely cause: CPU quota
- host_threads = 20 cores
- usable_cores = 10 cores
- core_ratio = 2 ratio
›+2 more findings
memorynot measuredNo access latency was published, so the score assumed an unfavourable one. Publishing the measurement can only help.
- assumed_latency_ns = 180 ns
- reference_latency_ns = 120 ns
disknot measuredDirect IO was refused by the host, so the random part of the disk score rests on an assumption rather than a measurement.
- assumed_random_mbps = 90 MB/s
- reference_random_mbps = 150 MB/s
A finding stays silent rather than attribute a cause without evidence. An absent cause is an answer, not an omission.
Test by test
Problems first — select a row for the full test- Mob AIEntities11.01UnstableCritical
- Chunk LoadingExploration19.96ModerateHealthy
- Chunk TickingExploration19.96StableHealthy
- Memory PerformanceMemory & Storage19.98StableHealthy
- Block PhysicsSingle-Core Stress20.00ModerateHealthy
- Bone Meal GrowthMechanics20.00StableHealthy
- Disk PerformanceMemory & Storage20.00StableHealthy
- ExplosionMechanics20.00StableHealthy
- HopperMechanics20.00StableHealthy
- Lighting UpdateExploration20.00ModerateHealthy
- Multi-Core CPUCPU20.00StableHealthy
- Network (NBT)Network20.00StableHealthy
- RedstoneSingle-Core Stress20.00StableHealthy
- Single-Core (tick-aligned)CPU20.00StableHealthy
- Ticking Tile EntitiesMechanics20.00StableHealthy
- World SaveMechanics20.00StableHealthy
Settings your measurements justify
Each setting below is triggered by a measurement from this report, and names the test to replay to find out whether it helped.
Shrink the monster activation range
world-settings.default.entity-activation-range.monsters: 24Measured : mobAI.mspt.avg 101.0 ms (threshold 35.0 ms)
Mob AI costs more per tick than the budget allows. The activation range decides how far from a player a monster keeps thinking; shrinking it puts distant ones to sleep without removing them.
Test to replay : mobAI
These settings trade a little gameplay fidelity for tick budget. Apply one at a time and replay the named test: the effect stays a hypothesis until you have measured it.
Briefing for a language model
Paste this into the assistant of your choice to have it rewritten in prose. It already carries every number, so the model has none left to invent.
{
"format": "voxelbench.tuning.v1",
"instruction": "Rewrite each recommendation below as plain prose for a server operator. Every number you are allowed to use is already in this document: the measured value, its threshold, and the proposed setting. Do not compute, estimate or predict any other number, and never state an expected gain. Keep every setting name and value exactly as written.",
"server": {
"type": "purpur",
"minecraft": "1.21.11",
"java": "25.0.3"
},
"recommendations": [
{
"id": "spigot.portee-activation-monstres",
"family": "spigot",
"measure": "mobAI.mspt.avg",
"value": 101,
"unit": "ms",
"threshold": 35,
"control_test": "mobAI",
"file": "spigot.yml",
"setting": "world-settings.default.entity-activation-range.monsters",
"proposed_value": "24",
"current_value": null
}
]
}Java start-up line
The options this server was started with, checked against its Java version. Corrections fix what is certainly wrong; leads to test are settings to measure, never applied for you.
Current line (44 arguments)
Values of system properties, agents and file paths are never shown: they appear as <redacted>.
-Dterminal.jline=false -Dterminal.ansi=true -DIReallyKnowWhatIAmDoingISwear -XX:+DisableExplicitGC -XX:+ParallelRefProcEnabled -XX:+PerfDisableSharedMem -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:G1HeapWastePercent=5 -XX:G1MaxNewSizePercent=40 -XX:G1MixedGCCountTarget=4 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1NewSizePercent=30 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:G1ReservePercent=20 -XX:InitiatingHeapOccupancyPercent=15 -XX:MaxGCPauseMillis=200 -XX:MaxTenuringThreshold=1 -XX:SurvivorRatio=32 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -Xms256M -Xmx29491M
To correct
- DangerHeap too close to the container's limit
-Xmx29491MThe heap may use 29491 MiB of the container's 34406 MiB, which leaves 4915 MiB for everything else (code, threads, network buffers). Under load the server can be killed without any Java error. The corrected line keeps 5161 MiB outside the heap.
- NoteOption set more than once
-XX:+DisableExplicitGCThe JVM keeps only the last occurrence (-XX:+DisableExplicitGC); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:+ParallelRefProcEnabledThe JVM keeps only the last occurrence (-XX:+ParallelRefProcEnabled); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:+PerfDisableSharedMemThe JVM keeps only the last occurrence (-XX:+PerfDisableSharedMem); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:+UnlockExperimentalVMOptionsThe JVM keeps only the last occurrence (-XX:+UnlockExperimentalVMOptions); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:+UseG1GCThe JVM keeps only the last occurrence (-XX:+UseG1GC); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:G1HeapRegionSize=8MThe JVM keeps only the last occurrence (-XX:G1HeapRegionSize=8M); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:G1HeapWastePercent=5The JVM keeps only the last occurrence (-XX:G1HeapWastePercent=5); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:G1MaxNewSizePercent=40The JVM keeps only the last occurrence (-XX:G1MaxNewSizePercent=40); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:G1MixedGCCountTarget=4The JVM keeps only the last occurrence (-XX:G1MixedGCCountTarget=4); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:G1MixedGCLiveThresholdPercent=90The JVM keeps only the last occurrence (-XX:G1MixedGCLiveThresholdPercent=90); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:G1NewSizePercent=30The JVM keeps only the last occurrence (-XX:G1NewSizePercent=30); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:G1RSetUpdatingPauseTimePercent=5The JVM keeps only the last occurrence (-XX:G1RSetUpdatingPauseTimePercent=5); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:G1ReservePercent=20The JVM keeps only the last occurrence (-XX:G1ReservePercent=20); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:InitiatingHeapOccupancyPercent=15The JVM keeps only the last occurrence (-XX:InitiatingHeapOccupancyPercent=15); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:MaxGCPauseMillis=200The JVM keeps only the last occurrence (-XX:MaxGCPauseMillis=200); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:MaxTenuringThreshold=1The JVM keeps only the last occurrence (-XX:MaxTenuringThreshold=1); the earlier ones do nothing but mislead whoever reads the line.
- NoteOption set more than once
-XX:SurvivorRatio=32The JVM keeps only the last occurrence (-XX:SurvivorRatio=32); the earlier ones do nothing but mislead whoever reads the line.
Corrected line to copy
- Removed
-XX:+DisableExplicitGCearlier occurrence; the JVM keeps -XX:+DisableExplicitGC. - Removed
-XX:+ParallelRefProcEnabledearlier occurrence; the JVM keeps -XX:+ParallelRefProcEnabled. - Removed
-XX:+PerfDisableSharedMemearlier occurrence; the JVM keeps -XX:+PerfDisableSharedMem. - Removed
-XX:+UnlockExperimentalVMOptionsearlier occurrence; the JVM keeps -XX:+UnlockExperimentalVMOptions. - Removed
-XX:+UseG1GCearlier occurrence; the JVM keeps -XX:+UseG1GC. - Removed
-XX:G1HeapRegionSize=8Mearlier occurrence; the JVM keeps -XX:G1HeapRegionSize=8M. - Removed
-XX:G1HeapWastePercent=5earlier occurrence; the JVM keeps -XX:G1HeapWastePercent=5. - Removed
-XX:G1MaxNewSizePercent=40earlier occurrence; the JVM keeps -XX:G1MaxNewSizePercent=40. - Removed
-XX:G1MixedGCCountTarget=4earlier occurrence; the JVM keeps -XX:G1MixedGCCountTarget=4. - Removed
-XX:G1MixedGCLiveThresholdPercent=90earlier occurrence; the JVM keeps -XX:G1MixedGCLiveThresholdPercent=90. - Removed
-XX:G1NewSizePercent=30earlier occurrence; the JVM keeps -XX:G1NewSizePercent=30. - Removed
-XX:G1RSetUpdatingPauseTimePercent=5earlier occurrence; the JVM keeps -XX:G1RSetUpdatingPauseTimePercent=5. - Removed
-XX:G1ReservePercent=20earlier occurrence; the JVM keeps -XX:G1ReservePercent=20. - Removed
-XX:InitiatingHeapOccupancyPercent=15earlier occurrence; the JVM keeps -XX:InitiatingHeapOccupancyPercent=15. - Removed
-XX:MaxGCPauseMillis=200earlier occurrence; the JVM keeps -XX:MaxGCPauseMillis=200. - Removed
-XX:MaxTenuringThreshold=1earlier occurrence; the JVM keeps -XX:MaxTenuringThreshold=1. - Removed
-XX:SurvivorRatio=32earlier occurrence; the JVM keeps -XX:SurvivorRatio=32. - Changed
-Xmx29491M-Xmx29245Mleaves 5161 MiB outside the heap.
java -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Xms256M -Xmx29245M -jar server.jar noguiReplace server.jar with your server's jar. Paste the line where your server is started: the start-up parameters (or JVM arguments) of your hosting panel, or your start.sh / start.bat. Only the corrections above differ from your current line.
Your current line also carries 7 other arguments (system properties, agents): keep them between java and -jar. Their values are not shown here.
To test
Performance settings to try one at a time, then measure with a benchmark before and after. None of them is applied in the corrected line, and none comes with a promised gain.
Settings documented by PaperMC for Minecraft servers: they size G1's young generation for the game's very high allocation rate and start collections earlier. Initial and maximum heap at the same size, with AlwaysPreTouch, commit the whole heap at start-up: proposed only because that heap already stays under the memory limit.
-Xms29245MNo measurement of this run points to it: it stays a lead to measure.
sourceA collector with very short pauses for large heaps, at the cost of more CPU and memory. It replaces the current collector: remove the current collector option and its own tuning options, then measure. From Java 23 the generational mode is the default.
-XX:+UseZGCNo measurement of this run points to it: it stays a lead to measure.
sourceRe-run and compare
- Apply the corrected line where your server starts (panel start-up parameters, start.sh).
- Restart the server.
- Run a new benchmark:
/bench start - Compare the new report with this one.
This report is the before; add the new report to the comparison once it is in. A single run on each side says little: the gap between two runs of an unchanged server is noise.
Every measurement
Each test in full. Tests in trouble are open; the others fold to their summary line.
Single-Core Stress
RedstoneHealthy20.00 TPS3.3 ms34.9s
Single-core stress via intensive redstone circuit updates.
- Heavy garbage collection3 collections, 18ms total
Percentiles and stability
Raw data (12 fields)
Block PhysicsHealthy20.00 TPS17.2 ms24.9s
Single-core stress via falling-block physics.
- Heavy garbage collection5 collections, 77ms total
Percentiles and stability
Raw data (20 fields)
Exploration
Chunk LoadingHealthy19.96 TPS4.2 ms7.8s
Chunk generation and loading speed across dispersed zones.
- Heavy garbage collection5 collections, 226ms total
Percentiles and stability
Raw data (11 fields)
Chunk TickingHealthy19.96 TPS11.3 ms40.9s
Server performance when ticking many loaded chunks with random tick updates.
- Heavy garbage collection7 collections, 117ms total
Percentiles and stability
Raw data (14 fields)
Lighting UpdateHealthy20.00 TPS1.8 ms24.6s
Lighting recomputation throughput on block place / break.
Percentiles and stability
Raw data (5 fields)
Entities
Mob AICritical11.01 TPS101.0 ms30.3s
Complex mob AI behaviours (villagers, iron golems, hostile mobs).
- Unfiltered samples usedUsing unfiltered samples (filter rate: 31%)
- Heavy garbage collection15 collections, 230ms total
- The run did not hold steadyTPS avg=11.01<19, TPS P1=4.77<15, TPS StdDev=2.31>2, TPS min=4.77 (43% of avg)
Percentiles and stability
Raw data (30 fields)
Mechanics
HopperHealthy20.00 TPS2.3 ms19.2s
Intensive hopper chain item transfers.
- Heavy garbage collection2 collections, 65ms total
Percentiles and stability
Raw data (19 fields)
ExplosionHealthy20.00 TPS4.3 ms17.0s
Massive TNT explosions and block destruction.
Percentiles and stability
Raw data (60 fields)
Ticking Tile EntitiesHealthy20.00 TPS1.1 ms35.9s
Many ticking tile entities (furnaces, hoppers, etc.).
Percentiles and stability
Raw data (7 fields)
World SaveHealthy20.00 TPS1.2 ms5.0s
World save speed and TPS impact during save operations.
Percentiles and stability
Raw data (5 fields)
Bone Meal GrowthHealthy20.00 TPS1.5 ms23.3s
Rapid crop and tree growth via bone meal.
Percentiles and stability
Raw data (11 fields)
CPU
Single-Core (tick-aligned)Healthy20.00 TPS3.2 ms10.0s
Single-thread compute throughput measured on the main thread under the tick scheduler.
Percentiles and stability
Raw data (6 fields)
Multi-Core CPUHealthy20.00 TPS1.1 ms11.6s
Parallel computation throughput across worker threads.
Percentiles and stability
Raw data (7 fields)
Memory & Storage
Memory PerformanceHealthy19.98 TPS1.1 ms49.3s
RAM bandwidth and latency.
JVM measurements — do not reflect actual bare-metal performance.
- Heavy garbage collection4 collections, 43ms total
Percentiles and stability
Raw data (8 fields)
Disk PerformanceHealthy20.00 TPS1.5 ms16.7s
Sequential and random 4K read/write performance.
JVM measurements — do not reflect actual bare-metal performance.
- Heavy garbage collection23 collections, 227ms total
Percentiles and stability
Raw data (7 fields)
Network
Network (NBT)Healthy20.00 TPS23.6 ms20.0s
Serialisation throughput — proxy for the rate at which the server can ship world data to clients.
- Heavy garbage collection29 collections, 78ms total
Percentiles and stability
Raw data (9 fields)
›Machine and serverIntel(R) Core(TM) Ultra 7 265 · Purpur · 1.21.11
Score Breakdown
Detailed sub-category scores