Minecraft 1.20.1 · Fabric · v0.20.0

Chorus

Your server has 16 cores. Minecraft uses one.

Drop-in multithreaded server software for modded Minecraft. It ticks block entities in parallel, moves pathfinding, spawning and world I/O off the main thread, and runs your Bukkit plugins while it does it. One jar — rename it over the one your pack already starts.

Pre-1.0. What ships, what's experimental, what's still research.


~5 min → 104s Full server boot, warm gauntlet 3/3, 555-mod pack
97.7% Class transforms served from cache 37,755 hits, warm boot
6.5 → 4 GB Resident memory auto-tune v2, live
3.8 / 780 Dependency depth vs units per tick 250-mob pen, probe

Density is the problem

Folia, ShreddedPaper and the MCMT family all partition the world: a region of chunks per thread. That holds until the server is actually under load — forty players at spawn, one megabase, a mob farm in a hundred-block cube. All of that is one region, and one region is one thread. Chorus partitions the work instead.

Parallel block entities

Furnaces, hoppers, machines and cables are block entities, and vanilla ticks all of them on one thread. Chorus ticks them across a worker pool — per-thread RNG streams, straggler demotion, and deferred block updates so nothing renders half-applied.

Intra-cluster waves

A knot of machines that all touch each other is what forces region-based servers back onto one thread. Chorus splits the knot into dependency waves and runs each wave wide, instead of splitting the world in space.

Conflict cartographer

Chorus does not guess what can run together from mod names or block types. It records which block entities actually touch each other and builds the map from your base. /chorus clusters prints it.

Async pathfinding and LOS

The two largest per-entity costs. Both compute off the main thread against a main-captured chunk grid, and the main thread steals work rather than parking on queue latency.

Async saves, spawning, tracking, locate

Cold chunk saves serialise off-thread while hot chunks stay on the vanilla-safe path. Spawn selection, entity tracking and /locate scans leave the tick loop. Each is a switch you can flip back.

Bukkit plugins, on a modded server

Chorus embeds a Bukkit/Spigot/Paper API implementation for Fabric. Plugins go in plugins/ next to your mods and keep the single-main-thread contract they were written against.

How each of these actually works →


Boot: the fastest work is deleted work

On a 447-mod pack the server thread spent 195 of its 204 seconds preparing spawn regions for 30+ dimensions nobody was standing in — regions Chorus releases two minutes later anyway.

So it stopped doing it. The idle-dimension set persists across restarts and their spawn prep is skipped; they stream back when someone walks in. That phase is now 9.0 seconds, and 70,000 chunks never load at all.

Then a learning class cache records what each boot really loads, a parallel transformer pre-warms it on worker threads, and a content-addressed cache serves 97.7% of a warm boot's class transforms. End to end on the production pack: a boot that took about five minutes now takes 104 seconds.

Memory: give it back

Every modded dimension pins a 47×47 chunk region loaded forever, whether or not anyone has been there. Thirty dimensions of that is usually the largest single thing in the heap. Chorus releases it once a dimension is empty and restores it — ramped, so a joining player isn't starved.

It also evicts idle structure templates and rewrites your JVM flags so G1 returns memory to the OS. With stock flags a Minecraft server commits its way to -Xmx and never gives a byte back.

Same pack: 6.5 GB → ~4 GB resident.

One jar. Rename it. Start the server.

Chorus installs itself into mods/, adds what your pack is missing, creates plugin support, benchmarks your disk and tunes the JVM — inside the JVM your existing start script already launched. Windows, Linux and macOS behave identically.