Folia and its Forks

On Folia and its forks (Canvas…), each group of loaded chunks is a region with its own tick. VoxelBench measures every region and the global region, lists them in game with /bench regions, and says which region its TPS and MSPT figures describe.

Regions in a Few Words

Folia splits each world into regions: groups of nearby loaded chunks, with the players and entities in them. Each region ticks on its own, on one of the threads of Folia's region scheduler, so one region can lag while the others run at 20 TPS. Regions merge when their chunks come close and split when they move apart; each one has an id, which changes with every merge or split.

The global region is separate: it runs what belongs to no chunk (time, weather, global tasks, the console's commands). It owns no entity, so it cannot count a world's entities or chunks itself.

A single "server TPS" therefore means little on Folia. VoxelBench reports:

  • the worst region, the median region TPS and the number of regions lagging (under 18 TPS);
  • the global region: its TPS, the average duration of its ticks and its utilisation;
  • the utilisation of each region and the total, against the capacity of the scheduler's threads (one thread = 100 %). Utilisation is the share of the time a thread spent running the region, tasks between two ticks included — the figure Folia's own /tps shows. It can exceed 100 % by a hair.

Seeing the Regions

/bench regions [world] [page]
/bench regions tp <id>
/bench regions gui

/bench regions prints the summary (regions, lagging regions, worst and median TPS, global region, utilisation over the capacity, the TPS of the region you are in), then every region, worst first, 8 per page: id, world, center block (the coordinates Folia's /tps shows), players, entities, chunks, TPS, average / 95th-percentile / worst tick time and utilisation. Add a world name to list only its regions, and a page number to move through the list (or click the arrows). The figures cover the last 15 seconds.

A player with voxelbench.regions.tp sees a [Teleport] link after each region: it runs /bench regions tp <id>, which teleports to the center of that region, standing on the highest block (in the Nether, in the first free space under the bedrock roof). The spot must be safe: no liquid at your feet or head, solid ground that is neither lava nor magma. Over an ocean, a lava lake or the End's void there is none, and the command says so instead of teleporting. A region that merged, split or unloaded since the list was printed is refused with a message: run /bench regions again; a teleport the server refuses is reported too.

The same content is available as a screen: /bench regions gui, the [Open the screen] link, or the Regions (Folia) button of the Monitor tab of /bench gui. The summary sits at the top, then one item per region, colored by TPS; clicking one teleports there (with voxelbench.regions.tp).

On Paper and Spigot, which tick every world on a single main thread, /bench regions and its screen say the server is not regionized and show its TPS and MSPT over the last minute.

Permissions: voxelbench.regions to see the regions, voxelbench.regions.tp on top of it to teleport (it is not a child of voxelbench.regions). See Permissions.

How VoxelBench Measures the Regions

  • Tick by tick. Folia fires its tick event at the end of every region tick, on the region's thread. VoxelBench's single tick listener asks Folia which region is ticking and adds the tick to that region's window: TPS, average, 95th-percentile and worst tick time, ticks over 50 ms, seconds under 18 TPS. Regions without players (farms, chunk loaders) are measured like the others.
  • From Folia's reports. Utilisation, the global region's tick time and the thread count come from the reports Folia keeps for its /tps command, read every 15 seconds — never during a tick.
  • Always on. The measurement runs from startup, whether remote monitoring is on or not. A region that merged, split or unloaded is forgotten, not reported as frozen; a living region that stops ticking shows 0 TPS.
  • Bounded memory. At most 512 regions are tracked at once; each keeps a fixed-size histogram of its tick times (the 95th percentile is within 3.2 % of the exact value; the average and the worst tick are exact). Beyond 512, a region is only counted, and /bench regions says how many.

Folia exposes no public API for its regions: VoxelBench reads its internal classes. They were checked on Folia 26.1.2 and 26.2 and on Canvas 26.1.2 (whose scheduler is also Folia's "EDF" scheduler). Each value is read on its own: if a fork lacks one, only that value is missing. If the regions themselves cannot be read, /bench regions says so and shows the global region only, and the console logs it once.

What the Other Views Show on Folia

ViewOn Folia
/bench tps, /bench msptThe server's own figures are those of your region when a player types the command, of the global region from the console; VoxelBench's monitor measures the global region. Both are labelled, the worst and median regions are added, and a player's region is not compared with the global region (they tick on different threads).
Boss barsTPS and MSPT of the worst region (the global region while no region is measured), labelled (worst region) / (global region).
Web dashboard and /api/metricstps and mspt of the worst region; entities and chunks counted by Folia per region (no breakdown by category); a Regions section with the summary and the table of regions.
Placeholders%voxelbench_tps% and %voxelbench_mspt% of the worst region, entities and chunks counted by Folia, and the region_* placeholders below. tps_avg, tps_min, tps_max and mspt_avg, mspt_min, mspt_max cover the global region only (see below).
/bench info, information screens, text reportTPS and MSPT of the worst region; entities are the sum of the regions (no breakdown by type).
voxelbench.com dashboardEvery region in each snapshot, the worst / average / median values, the global region, the thread count and the total utilisation.

A value that is not measured shows N/A, never an invented 20.0 TPS or 50.0 ms. VoxelBench never reads World#getEntities() from the global region on Folia: those entities belong to other threads.

Placeholders

With PlaceholderAPI:

PlaceholderValue
%voxelbench_region_tps%TPS of the player's region over 15 s, from Folia's public API (_5s, _15s, _1m, _5m, _15m for another window)
%voxelbench_region_count%, %voxelbench_region_lagging%Regions measured, and those under 18 TPS
%voxelbench_region_tps_worst%, %voxelbench_region_tps_median%, %voxelbench_region_tps_avg%Worst, median and average region TPS
%voxelbench_region_mspt_worst%Highest average tick time of a region, in ms
%voxelbench_region_global_tps%, %voxelbench_region_global_mspt%, %voxelbench_region_global_util%Global region: TPS, tick time, utilisation
%voxelbench_region_threads%, %voxelbench_region_util_total%, %voxelbench_region_util_capacity%Region threads, total utilisation and capacity, in % of one thread

They cover the last 15 seconds and return N/A on Paper and Spigot.

%voxelbench_tps_avg%, %voxelbench_tps_min%, %voxelbench_tps_max% and %voxelbench_mspt_avg%, %voxelbench_mspt_min%, %voxelbench_mspt_max% are not region figures: they come from VoxelBench's tick monitor, which on Folia only sees the global region. A lagging region does not show there; use the region_* placeholders, or %voxelbench_tps% / %voxelbench_mspt% (worst region).

Profiling on Folia

/bench profile works on Folia: the tick threads it samples are the region threads. A profile also says where they worked — the share of the tick samples taken in each region, with its world, its center and who ran there, and the share outside any region tick (the global region). The ring buffer's automatic dump watches each region's own ticks as well, so a lag that shows on one region is caught and the profile names that region (garbage-collection pauses of the whole JVM are told apart). See Profiling — By Region, on Folia and Automatic Dump on Lag. A public share keeps the regions by number only, without their world or coordinates.

Benchmarks on Folia

Folia cannot create a world, and Canvas cannot remove one while it runs, which changes where benchmarks take place: on Folia, install the benchmark dimension once with /bench world install; on Canvas, VoxelBench creates voxelbench_bench at startup. See Benchmark Worlds — Folia. The TPS and MSPT of a test are read on the regions where it works (see Compatibility).

Limits

  • Region ids are not stable: a merge or a split gives the region another id, and a restart renumbers them.
  • With a single region thread (Folia's default scheduler starts with one), every region shares it: a heavy region slows the others down too. The thread count is shown next to the utilisation.
  • The TPS of the player's region (region_tps, the line in /bench regions) comes from Folia, over its own windows; every other figure is VoxelBench's measurement over the last 15 seconds.
  • On a fork that rewrote Folia's regions, they are not listed and remote monitoring measures the areas around players instead (see Monitoring).