Benchmarks

What happens during a full benchmark, the 26 built-in tests and where they run, how voxelbench.com turns the results into a VoxelScore, and the other ways to run them: custom mode, multi-run and custom profiles.

How Benchmarks Work

A VoxelBench benchmark measures your Minecraft server's performance through a series of automated tests. Each test simulates a specific kind of server load and measures how well your hardware and server software handle it.

Benchmark Flow

What happens after /bench start:

  1. Checks: the command must come from a connected player, no other test may be running, and the local cooldown between benchmarks must have expired (30 minutes by default).
  2. Pre-flight (unless confirmation.require-confirmation is false): VoxelBench looks for risks: a pinned world that is not flat or not a voxelbench_* world, no pinned world while benchmark.auto-temp-world is false, other players online, server already under load, free hosting detected, plugins likely to interfere. Without a pinned world, the run uses a temporary flat world, which is not checked. If it finds any risk, an inventory screen lists them and asks you to confirm (see Benchmark Worlds).
  3. Preparation: in every loaded world, the weather is cleared and the time set to noon with the day-night cycle stopped. On Paper and Spigot, the mobs, animals, villagers, golems, dropped items, projectiles, minecarts and boats of voxelbench_* worlds are removed; nothing is removed from any other world, nor on Folia (see Safety Guards). Then test zones are generated and the player's position and game mode are saved.
  4. Phase 1 - Hardware: disk, network and memory, while the JVM warms up.
  5. Phase 2 - Gameplay: Minecraft workloads (chunks, hoppers, explosions, redstone, entities...).
  6. Phase 3 - CPU: single-core then multi-core, last, once the JVM is fully warmed up.
  7. Report: the report is saved locally, then sent to voxelbench.com, which computes the score; the score is shown in chat and written into the local report.
  8. Cleanup: blocks and entities created by the tests are removed, the weather and the day-night cycle of every world come back as they were (the clock is not turned back), and the player is restored.

During a Benchmark

  • You may be moved to the test zones; you are brought back afterwards
  • The server lags during intensive tests - this is expected
  • A progress bar and a scoreboard show the current test and the overall progress
  • /bench stop aborts the run: the running test removes what it spawned, and the weather and day-night cycle are given back. Nothing else is removed outside voxelbench_* worlds
  • The animals, villagers and items of your own worlds stay where they are: outside voxelbench_* worlds, VoxelBench only removes what its tests spawned

Test Catalog

VoxelBench ships 26 built-in tests, in three categories. Extensions can register more (see Extending VoxelBench). Every test can be run on its own with /bench test <id>; the last column shows which ones the standard /bench start runs.

Hardware

TestWhat it MeasuresIn /bench start
diskSequential and random 4K read/write throughputYes
networkNBT serialization throughput (inventories, tile entities, entity data)Yes
memoryRAM throughput and latency on sequential and random accessYes
multiCoreParallel CPU work across all coresYes (phase 3)

Single-Core CPU

TestWhat it MeasuresIn /bench start
singleCoreBenchmarkOperations per second on the server main thread over a fixed durationYes (phase 3)
singleCoreMaxTime to complete a fixed workload on a dedicated thread, over several passesNo

Single-thread performance is the main limiting factor of a Minecraft server.

Gameplay

TestWhat it MeasuresIn /bench start
chunkLoadingGenerating and loading new chunksYes
hopperItem transfer through hopper linesYes
worldSaveImpact of a full world saveYes
explosionTNT explosions and block destructionYes
redstonePistons driven by redstone circuitsYes
blockPhysicsFalling block physicsYes
chunkTickingRandom ticks (crop growth, etc.) at a raised tick speedYes
lightingUpdateLight engine recalculationYes
tickingTileEntityFurnaces, hoppers and spawners tickingYes
mobAIA village of trading villagers, then a hostile invasion (pathfinding, combat, fleeing)Yes
boneMealGrowthSapling and crop growthYes
mobSpawnSpawning and managing many mobsNo
entityCollisionCollisions between many dropped items and mobsNo
mobPathfindingMob pathfindingNo
villagerTradingVillager AI in a village with housesNo
liquidPhysicsWater and lava flowNo
combatSimulationLarge fight between zombies, skeletons and pillagersNo
projectileStormWaves of arrows, fireballs and snowballs in flightNo
entityCrammingMobs, animals and items packed into small cellsNo
playerWorldLoadActive player areas: loaded chunks, block breaking and placing, areas moving aroundNo

Some tests need a connected player and cannot be started from the console; see Commands.

Where /bench test runs

Every gameplay test except worldSave writes to the world: it builds and clears test zones far from spawn, spawns mobs, or generates chunks that stay in the world files. /bench test therefore never runs these tests in the world you are standing in:

  • if a world is pinned with /bench world set, they run there, and build and clear their test zones in it. playerWorldLoad, which breaks natural blocks around x=0, z=0 and up to 8,000 blocks away, gives every block it changed its original state back at the end (orientation and door halves included), and never touches blocks with contents (chests, spawners, signs, beds);
  • otherwise /bench test creates a temporary flat world (voxelbench_temp_<timestamp>), even if you are in the main world, and deletes it at the end, including after a failure or /bench stop. Creating it takes a few seconds per test: pin a world (for example one made with /bench world create) to skip that;
  • if no temporary world can be created (benchmark.auto-temp-world: false, or the creation failed), the test is refused instead of falling back to the main world.

The hardware and CPU tests and worldSave (a save of the world as it is) do not write to the world: they still run in the pinned world, or the world you are in.

Tests that need you on site (mobAI, villagerTrading, mobPathfinding, entityCollision, liquidPhysics, combatSimulation) take the player who launched them to their zone in spectator mode, and bring them back to where they were, in their game mode, when the test ends, fails or is stopped, as /bench start does. If you disconnect during the test, you are sent back as you leave, so you reconnect where you were (on Folia, you are brought back just after your next login); the same goes if the server stops during the test. mobSpawn spawns its mobs in scattered zones without moving you, and headless tests (hopper, lightingUpdate, chunkTicking...) move nobody: they keep their chunks loaded with tickets.

On Folia, a world cannot be created while the server runs, so these tests need a pinned world and are refused without one. Only a world the server loads at startup can be pinned there; pinning your main world means these tests build and clear their zones in it, as /bench start does on Folia.

Only /bench test follows this rule: the command, the test GUI, and auto-bench jobs in test mode. /bench start, /bench stresslimit, /bench tier and custom profiles keep following the pinned world, then benchmark.auto-temp-world, and drop no test. A custom benchmark profile first follows its own options.auto-temp-world, which can turn the temporary world off but not on (see Custom Profiles). The one exception is playerWorldLoad in a custom profile: outside the pinned world or a voxelbench_* world, the step is skipped with the reason benchmark_world_required.

In a temporary world the terrain is flat, so results no longer depend on your map. They match what /bench start measures in its own temporary world, but are not comparable with earlier /bench test runs made in your own world (notably chunkLoading, which generated real terrain there).

VoxelScore

After a full benchmark, your server receives a VoxelScore, a single number summarizing its overall performance. The score is computed by voxelbench.com from the submitted results, not by the plugin. The plugin shows what the backend returns:

  • the total VoxelScore and a rank
  • three category sub-scores: Single-Core (40%), Gameplay (40%) and Hardware (20%)
  • a synergy bonus

The sub-scores do not follow the categories of the test catalog above. On voxelbench.com, Single-Core is made of redstone and blockPhysics; Hardware of memory, disk and multiCore; Gameplay of chunkLoading, chunkTicking, lightingUpdate, mobAI, hopper, explosion, tickingTileEntity, worldSave and boneMealGrowth. network, singleCoreBenchmark and singleCoreMax count in no sub-score. The score screens of /bench gui say so: they list under Single-Core the tests the site counts there, and mark network and singleCoreBenchmark Not counted in the site's score (see Reports).

Scoring rules and rank thresholds are defined on voxelbench.com and may evolve. Runs of custom profiles are stored by the backend but receive no VoxelScore.

Standard vs Custom Mode

Standard Mode (Default)

benchmark-mode: standard

All test parameters are fixed so results are comparable between servers. /bench start runs the 16 tests marked "Yes" above.

Custom Mode

benchmark-mode: custom

/bench start reads several test parameters from config.yml instead of using the fixed values, and the gameplay phase also runs mobSpawn, entityCollision, liquidPhysics and combatSimulation. The report is tagged as a custom-mode run. See Configuration.

Multi-Run Mode

For more reliable results, run several benchmarks in a row:

/bench start 5
/bench start warmup 3

The first command runs 5 benchmarks. With warmup, one extra benchmark runs first and its results are discarded. Before the first run the chunks around the test zones are pre-loaded; every run reuses the same zones, and runs are 10 seconds apart. In a voxelbench_* world the test regions are reset between runs; in any other world nothing is deleted. See Commands.

Best practices for accurate results:

  • Run 3-5 benchmarks and compare
  • Ensure the server is idle (no players, no farms running)
  • Use standard mode for comparable results
  • Benchmark in a dedicated flat world (/bench world create, then /bench world set)

Custom Profiles

A custom profile is a YAML file describing your own benchmark: which tests, in which order, with which parameters. Profiles live in plugins/VoxelBench/custom_benchmarks/. VoxelBench copies its bundled profiles there when the folder is created, and a profile added by a later version once. A bundled profile you delete stays deleted (the folder's .bundled-profiles file remembers it). An unmodified copy of an older version is replaced by the current one; a copy you edited is never touched.

FileKindContent
example.ymlbenchmarkQuick smoke test: hardware plus a couple of gameplay tests
standard.ymlbenchmarkReplica of /bench start, as a starting point to fork
showcase.ymlbenchmarkCommented reference covering every test ID and parameter
free-host.ymlbenchmarkLightweight profile for free hosting tiers
low-memory.ymlbenchmarkScaled-down standard for 2-4 GB heap servers
hopper-heavy.ymlbenchmarkHopper test at 100 lines per zone, ten times the standard load
stress-redstone.ymlstresslimitRedstone only, fine ramp
stress-monster.ymlstresslimitSix stress types (all but villagers), aggressive ramp
stress-freehost.ymlstresslimitGentle ramp and low ceilings for small hosts

A benchmark profile looks like this:

name: "Storage Suite"
description: "Disk and chunk generation"
author: "you"
version: 1
tags: [storage]
submit: false          # false (default) = not sent to voxelbench.com

tests:
  - id: disk
    params:
      threads: 4
      fileSizeMb: 1024
  - id: chunkLoading
    params:
      chunksToLoad: 200
      dispersedZones: 4
  • kind: selects the profile type: benchmark (default) or stresslimit (see Stress Limit). When omitted, a file with a stress: section and no tests: section is treated as a stress profile.
  • An unknown test id rejects the whole profile when it is loaded; an out-of-range parameter is clamped, with a warning.
  • With submit: true, the run is sent to voxelbench.com as a custom profile run: private at first, never scored or ranked.

Commands:

/bench custom list
/bench custom info storage-suite
/bench custom run storage-suite
/bench custom reload

The profile name is the file name without .yml. /bench custom run must be used in-game, requires a linked server (even with submit: false) and is subject to the same cooldown as /bench start. Profiles currently run a single iteration. Custom Profiles is the full reference: every key, the parameters of each test, validation and the profile hash.

Comparing Results

Visit voxelbench.com to:

  • Compare your server against others with similar hardware
  • Track performance over time
  • Identify bottlenecks in specific test categories
  • Share your results with your community

You can also browse and compare local reports in-game (/bench reports, see Reports).

On Folia, the TPS and MSPT of lightingUpdate, tickingTileEntity and playerWorldLoad measured by VoxelBench 2.0.2 and earlier did not follow the regions these tests worked in: compare them only with results from later versions (see Folia Support).