Skip to the page
calcite

Benchmarks

Every benchmark runs the release build on one machine: an i9-13900K with 24 cores and 32 threads, 48 GiB of memory and Windows 11. Each number below is a recorded run, with the commit it ran at, and each benchmark runs again with one command. CI runners are too noisy to compare, so none of these come from CI.

100 players

This one runs on every commit that might change the tick or the network. 100 bots join a flat world, 20 a second, then walk outward in their own directions so each keeps being sent new chunks, and chat to everyone every 10 seconds, for 45 seconds. View and simulation distance are 10. The numbers are the median of 5 runs.

Tick, mean0.419 msof the 50 ms a tick has, on Windows
Tick, p991.112 msand 1.644 ms at the most
Joining549 msfor a bot to have all its chunks, the median
Memory70 MiBat the most, with all 100 in
Windows 11Linux, WSL 2
Tick, mean0.419 ms0.472 ms
Tick, p991.112 ms1.259 ms
Tick, longest1.644 ms1.853 ms
Ticks a second20.0020.00
Tick while joining, mean1.164 ms6.135 ms
Joining, median549 ms552 ms
CPU time, all threads3.03 s2.92 s
Peak memory70.0 MiB68.3 MiB
Chunks sent80,25180,362

The tick times come from the server itself, over the steady part of the run. A single run's mean moves by about 10% with whatever else the machine is doing, so a result more than 5% worse than the recorded one is run ten more times before anyone looks into it. Ticks while players join are slower on Linux than on Windows on the same machine, and the cause isn't known yet. The same load on Paper, Folia and Pumpkin is measured in Phase 8.

Recorded in bench/results/bots-windows.json at commit 565d961.

Joining and flying

Bots wait for the server, but a real client asks for chunks as fast as it can take them, so this one uses Mojang's own 26.3 client at render and view distance 32, on a new world. It joins, waits, and then flies straight ahead for 30 seconds. A relay between them counts, four times a second, how much of the circle of 32 chunks around the player the client has.

Joining, 95%2.98 sfor the client to have 95% of the 3,725 chunks in its view
Joining, all3.10 sfor all 3,725 of them
Flying at 25×97.9%of its view the client had on average at 269.1 blocks a second, and never less than 90.7%
Memory365 MiBwith one player standing still at view 32; 77 MiB idle and 1,117 MiB at the most
At 25×, 269 blocks a second% of the view · higher is better
At 100×, 1,075 blocks a second% of the view · higher is better

At 25 times vanilla's flying speed the client has nearly all of its view the whole way, and what it's missing is at the edge: the nearest chunk it doesn't have is 30 chunks away, at the median. At 100 times it flies 67 chunks a second. The circle ahead of it then needs more new chunks each second than 32 threads can generate, and within seconds the player has outrun them, while the server keeps sending 1,193 chunks a second.

The whole table
25×100×
Joining, 95% of the chunks2.98 s2.98 s
Joining, all of them3.10 s3.09 s
Flight speed, blocks a second269.11,074.9
Chunks sent a second1,116.91,192.8
View the client had, mean97.9%12.5%
View the client had, least90.7%0.4%
Tick while flying, mean4.88 ms5.95 ms
Tick while flying, p9914.89 ms11.37 ms
Memory, idle76.6 MiB76.6 MiB
Memory, one player still365.0 MiB366.1 MiB
Memory, at the most1,117 MiB1,126 MiB

Recorded in bench/results/client-windows.json at commit 565d961.

Worldgen with data packs

C2ME publishes a benchmark that generates a world with Terralith and Terratonic, beside Paper and vanilla. Calcite runs it with its own pregen, and vanilla, Paper and C2ME run it with Chunky, on the same machine and set up as C2ME's is. Calcite made 1.64 times as many chunks a second as C2ME on one thread, and 1.28 times as many on 32.

Chunks a secondhigher is better
Threads

32 threads · Calcite 1.28× the next fastest

Calcite
878.6
C2ME
687.1
Paper
312.5
Vanilla
112.9

chunks a second · higher is better

CPU time for the whole launchseconds, warm-up included · less is better

1 thread

Calcite
279 s
C2ME
545 s
Paper
532 s
Vanilla
685 s

8 threads

Calcite
419 s
C2ME
684 s
Paper
565 s
Vanilla
815 s
threadsCalciteC2MEPapervanillaCalcite's memory, MiB
180.148.852.837.9767
8414.8312.5313.798.0946
16610.2484.4308.5103.91,101
32878.6687.1312.5112.91,309
  • The packs are Terralith 2.6.5+26.3 and Terratonic 3.0.31, on C2ME's seed, 114862964781274189.
  • Each launch starts on a new world with a 512-block warm-up around the origin, then measures a 1,024-block radius around 1,000,000, 1,000,000: 16,384 chunks.
  • The Java servers run on JDK 25 with C2ME’s flags and a 16 GiB heap touched up front, so their peak memory is that heap and isn’t compared.
  • On a long run, vanilla with Chunky fills its heap, so it’s given vanilla’s own save-all flush every 120 seconds, which costs it about 8%. C2ME’s benchmark gives vanilla a patched Chunky that isn’t published.
  • Calcite at 565d961. Vanilla on Fabric 0.20.1, Paper 26.3-238 and C2ME 0.4.2-alpha.0.115, each with Chunky 1.5.3, at 868e0a0.
  • Paper used the 16 and 32 worker threads it was given, as its log says, and made no more chunks than with 8. Vanilla made about 100 a second at every count from 8 up.
  • The rig checks a sample of 264 of the chunks Calcite generates with the packs, and every one has what must be vanilla’s.
  • C2ME’s own benchmark uses a 3,072-block radius, which takes vanilla hours on one thread. This one is smaller, so the whole comparison takes about an hour and a half.

Recorded in bench/results/terralith-windows.json at commit 565d961.

Vanilla's worldgen

The same benchmark without the packs, through the whole server, the way a player's chunks are made: each chunk is generated, lit, saved to its region file and compressed, and kept until it's let go. The dotted line is the same runs at 868e0a0.

Chunks a second, by threadshigher is better
now, at 565d961at 868e0a0
Peak memoryMiB · less is better
1 thread
498 MiB
8 threads
644 MiB
16 threads
762 MiB
32 threads
915 MiB
threadschunks a secondsteadyat 868e0a0CPU time, smemory, MiB
1150.6153.0136.3149498
81,014.11,147.8832.1181644
161,559.4–1,286.4224762
322,022.1–1,689.8272915

The steady rate counts from 10% done to 90%. At 16 and 32 threads the run is over before there are two progress lines between those, so it has none.

Recorded in bench/results/worldgen-windows.json at commit 565d961.

Light

The rig runs its light probe on vanilla's server and on Calcite, 15 times each after a warm-up, on three workloads, and checks that the two engines give every block the same light level, from 0 to 15. They did in every run.

A flat world's light is the sky's, one level at a time, so there's little work either way. Terrain is where the difference shows.

Milliseconds to light, median of 15less is better

Flat, 9×9 chunks · Calcite 1.1× as fast

Calcite
3.72 ms
Vanilla
4.10 ms

Terrain, 7×7 chunks · Calcite 1.78× as fast

Calcite
141.70 ms
Vanilla
252.40 ms

Terrain, 7×7 chunks, 5,000 edits relit · Calcite 1.6× as fast

Calcite
194.70 ms
Vanilla
311.10 ms

Run by rig/runner/light_timing.py at commit 565d961. The results are in bench/README.md.

Running them

From the repo, with Python 3.10 or later and nothing else. Each one builds the release server with Calx first. The client benchmark needs a desktop with Minecraft 26.3 installed.

# 100 players
py -I bench/run.py --record
# a real client, joining and flying
py -I bench/client.py --record
# worldgen with the packs: Calcite, then vanilla, Paper and C2ME
py -I bench/terralith.py --record
py -I bench/others.py --record
# vanilla's own worldgen
py -I bench/terralith.py --no-packs --record
# light, beside vanilla's engine
py -I rig/runner/light_timing.py

bench/README.md has how each one is set up, and the history of every number. On Linux, use python3 in place of py. The site reads the results files when it's built, so a newly recorded run shows up here with the next deploy. What gets measured next