Folia Documentation

repository·ver/26.2.x·Indexed 25 days ago

https://github.com/papermc/folia

A high-performance fork of Paper that implements regionised multithreading to scale Minecraft servers. It replaces the single main thread with multiple independent region threads to improve CPU utilization. Documentation covers thread allocation, the 'folia-supported' plugin flag, the use of Region, Entity, Async, and GlobalRegion schedulers, and known broken APIs such as Scoreboards and teleportation.

Tokens
1.1K
Snippets
1
Records
7
Agent score
38%

What's inside Folia

  1. Overview of Folia's Regionised Multithreading

    ver/26.2.x
    Folia is a fork of Paper that implements regionised multithreading. Instead of a single main thread, Folia groups nearby loaded chunks into 'independent regions'. Each region has its own tick loop running at the standard Minecraft tickrate (20TPS), and these loops are executed in parallel on a thread pool. This architecture allows the server to scale effectively for player-distributed environments like Skyblock or SMP.
  2. Configure Folia Thread Allocation

    ver/26.2.x

    To optimize Folia, you should pre-generate your world to reduce chunk system worker requirements. When configuring threads, aim to keep total thread allocation below 80% of available CPU cores to leave room for unpredictable plugin or system threads.

    Rough estimation for thread allocation (based on ~300 players):

    • Netty IO: ~4 threads per 200-300 players
    • Chunk System IO: ~3 threads per 200-300 players
    • Chunk System Workers (if pre-generated): ~2 threads per 200-300 players
    • Tick Threads: Allocate remaining cores (up to 80% total) to threaded-regions.threads in the global config.

    Note on GC: When calculating available cores, account for concurrent GC threads using the -XX:ConcGCThreads=n flag. Do not include -XX:ParallelGCThreads=n in your calculation as those only run during pauses.

  3. Add Folia API to Maven Project

    ver/26.2.x

    To use the Folia API in your development environment, add the following to your pom.xml:

    <repositories>
        <repository>
            <id>papermc</id>
            <url>https://repo.papermc.io/repository/maven-public/</url>
        </repository>
    </repositories>
    
    <dependencies>
        <dependency>
            <groupId>dev.folia</groupId>
            <artifactId>folia-api</artifactId>
            <version>[26.1.2.build,)</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <repository>
        <id>papermc</id>
        <url>https://repo.papermc.io/repository/maven-public/</url>
    </repository>
    
    <dependency>
        <groupId>dev.folia</groupId>
        <artifactId>folia-api</artifactId>
        <version>[26.1.2.build,)</version>
        <scope>provided</scope>
    </dependency>
  4. Plugin Compatibility and the 'folia-supported' Flag

    ver/26.2.x

    Folia breaks most standard Paper plugins because it removes the single main thread. To prevent instability, Folia will only load plugins that have been explicitly marked as compatible.

    To mark a plugin as compatible, add the following to your plugin.yml:

    folia-supported: true

    Warning: Regions tick in parallel, not concurrently. Code running in one region must not access or modify data in another region, as this will cause data corruption. Use the provided schedulers to ensure code runs in the correct thread context.

  5. Known Broken APIs in Folia

    ver/26.2.x

    The following APIs are currently broken or non-functional in Folia:

    • Scoreboards: All scoreboard API is broken (global state issue).
    • Teleportation: Entity#teleport is broken. Always use teleportAsync instead.
    • Portals/Login: Most APIs interacting with portals, player respawning, or player login are broken.
    • World Management: World loading and unloading is currently broken.
  6. Use Folia Schedulers for Task Execution

    ver/26.2.x

    Because Folia lacks a single main thread, you must use specific schedulers to run tasks in the correct thread context (the region that 'owns' a location or entity).

    Available Schedulers:

    • RegionScheduler: Schedules tasks to the next tick of a specific region.
    • EntityScheduler: Schedules tasks to the next tick of the region owning a specific entity (retrieved via Entity#getScheduler()).
    • AsyncScheduler: For asynchronous tasks.
    • GlobalRegionScheduler: For tasks that should run on the global region.

    Thread Context Rules:

    1. Commands: Entity/Player commands run on the region owning that entity/player. Console commands run on the global region.
    2. Events: Single-entity events (e.g., breaking a block) run on the region owning the entity. Target-based events (e.g., entity damage) run on the region owning the target entity.
    3. Synchronicity: All events fired from regions or the global region are considered synchronous within that context; the async modifier for events is deprecated.
  7. Check Thread Ownership with isOwnedByCurrentRegion

    ver/26.2.x
    To ensure your code is running in the correct thread context before accessing data, use Bukkit#isOwnedByCurrentRegion to test if the current ticking region owns the specified positions or entities.