What happened to paper.yml?
This Paper config generator writes the two files that replaced paper.yml: paper-global.yml and paper-world-defaults.yml. Use the "File" select above to switch between them, set the values, and download each file. The rest of this page explains what goes in which file, the settings worth changing, and the mistakes that most often keep a Paper server from starting or let players join past the proxy.
Up to Minecraft 1.18, Paper kept its settings in one file, paper.yml, in the main server folder. From 1.19, Paper split it into a config/ folder:
| File | Scope |
|---|---|
config/paper-global.yml | Settings for the whole server: proxies, chunk loading, messages |
config/paper-world-defaults.yml | Default settings for every world: anti-xray, entities, redstone |
<world folder>/paper-world.yml | Overrides for one world only |
Guides and forum posts from before 1.19 still say "edit paper.yml". The settings in them mostly still exist, just in one of the new files and sometimes under a new name. If an old paper.yml is still in the server folder when you update to 1.19 or later, Paper moves its settings into the new files on the first start, so you do not have to copy them over by hand.
Paper still reads bukkit.yml and spigot.yml as well, because it is built on Spigot. Settings such as entity activation range, item merging and hopper speed stay in spigot.yml, and mob caps stay in bukkit.yml. The spigot.yml generator and the bukkit.yml generator write those.
paper-global.yml
paper-global.yml holds settings that apply to the server as a whole. You can not override them per world.
Proxy forwarding
This is the section most people open the file for. A backend server behind a proxy has to trust the proxy to tell it each player's real IP address and UUID. Without forwarding, every player appears to connect from the proxy's IP, and the backend gives every player an offline UUID made from their name instead of their real one, which breaks permissions, bans and inventories.
For Velocity with modern forwarding, the recommended setup:
proxies:
velocity:
enabled: true
online-mode: true
secret: "paste the contents of forwarding.secret here"
The secret is in the forwarding.secret file in the Velocity folder. It has to match exactly. Paper can also read it from the PAPER_VELOCITY_SECRET environment variable, which keeps it out of the file. Also set online-mode=false in server.properties on the backend, because the proxy handles authentication, and leave bungeecord: false in spigot.yml. The Velocity config builder sets player-info-forwarding-mode = "modern" on the proxy side, and the Behind Velocity preset here sets up the Paper side.
For BungeeCord or Waterfall, forwarding is turned on with bungeecord: true in spigot.yml, and proxies.bungee-cord.online-mode in paper-global.yml should match online_mode in the proxy's config.
proxy-protocol is a different thing. It reads the HAProxy PROXY protocol header that some load balancers and TCP shields add. Turn it on only if something in front of the server sends that header, or every connection fails.
Chunk loading
chunk-loading-basic limits how fast each player gets chunks, in chunks per second:
player-max-chunk-send-rate(default 75): chunks sent over the network. Lower it if players on slow connections time out while joiningplayer-max-chunk-load-rate(default 100): chunks read from diskplayer-max-chunk-generate-rate(default -1, no limit): new chunks generated
A generate rate limit is useful on servers where players fly with elytra into new terrain. Generating chunks is the most expensive thing a server does, and a limit of 20 to 40 per player keeps one fast flyer from lagging everyone else. The better fix is to pre-generate the world, which pre-generating chunks with Chunky covers step by step.
chunk-system.worker-threads and io-threads set how many threads Paper uses for chunk work. The default of -1 lets Paper pick from the CPU count, which is right for almost every server. Raise them only if you have measured a chunk loading bottleneck and have spare cores.
Joining, messages and the console
misc.max-joins-per-tick (default 5) limits how many players are let in per tick. After a restart, a whole network's worth of players can reconnect at once, and this spreads them out.
messages.no-permission and messages.kick.connection-throttle are the texts players see for a denied command and a throttled login. They use MiniMessage, Paper's text format, so colors are written as tags such as <red> or <gold> instead of &c codes.
collisions.enable-player-collisions: false stops players pushing each other. Spawn areas and lobbies where players stand in a crowd are the usual reason to turn it off.
Packet limiter and watchdog
The packet limiter kicks clients that send too many packets. The default, 500 packets per second averaged over 7 seconds, stops most crash exploits and packet spam without affecting normal play. Raise it only if legitimate players get kicked with "exceeded packet rate", which some modded clients and heavy building tools trigger.
The watchdog prints a thread dump when a tick takes longer than early-warning-delay milliseconds (default 10 seconds) and repeats it every early-warning-every milliseconds. That dump is what you need to find the plugin or chunk behind a freeze, so keep it on. How to fix Minecraft server lag explains how to read one.
Unsupported settings
Paper fixes several vanilla bugs that technical players use on purpose: TNT, carpet and rail duplication, headless pistons, and breaking bedrock and end portal frames. The unsupported-settings section turns the fixes off again. Anarchy and technical survival servers often enable piston duplication so TNT dupers work. Paper's team does not support servers that change these, so expect less help in their Discord if something breaks.
paper-world-defaults.yml
paper-world-defaults.yml holds settings that apply to every world. To change a setting for one world only, create a paper-world.yml in that world's folder with just the keys you want to change. A common example is anti-xray for the Nether, which needs different blocks and a higher max-block-height.
Anti-xray
Paper's anti-xray hides ores in the chunk data sent to players, so X-ray clients and resource packs can not see them. It works in three modes:
- Engine mode 1 replaces hidden ores with stone (or deepslate, netherrack or end stone). It is cheap for the server and the client. Ores next to air, in caves, stay visible
- Engine mode 2 fills hidden areas with fake ores at random, so an X-ray user sees ores everywhere. It blocks X-ray better but sends more data, and players with weak PCs may notice
- Engine mode 3 works like mode 2 but randomizes per chunk layer instead of per block, which Paper says can cut network load when players join by about half
The generator writes Paper's recommended hidden-blocks and replacement-blocks lists for the mode you pick, from Paper's own anti-xray guide. Adding air to the hidden blocks in mode 2 or 3 also fills caves with fake ores, which beats cave-finder tricks but can lower players' FPS. max-block-height: 64 covers diamonds and most ore spawns. Iron and copper also generate higher, so raise it if those matter on your server. use-permission lets players with paper.antixray.bypass see real blocks, which is useful for staff.
Anti-xray does not stop every cheat. Players can still see ores exposed to air in mode 1, and seed-cracking tools can predict ore positions from the world seed. Pair it with a logging plugin such as CoreProtect, covered in the best anti-grief plugins, so you can check who mined what.
Entities and spawning
per-player-mob-spawns gives each player their own mob cap instead of one shared cap. It is on by default and should stay on. With it off, a single player's mob farm can use up the cap for everyone nearby.
despawn-ranges sets how far from the nearest player mobs despawn. Past the soft range (vanilla 32 blocks) mobs despawn at random, and past the hard range (vanilla 128 blocks) they despawn at once. Lowering the hard range to about the simulation distance in blocks (simulation distance times 16) clears mobs the server is no longer ticking, which frees mob cap for mobs near players. The Performance preset uses 28 soft and 96 hard. The generator writes the same range for every mob category. Paper also accepts separate horizontal and vertical values per category if you want to edit the file further.
collisions.max-entity-collisions (default 8) caps how many collisions each entity handles per tick. Dropping it to 2 saves a lot of CPU in crowded animal pens and mob farms and is hard to notice in play.
chunks.entity-per-chunk-save-limit caps how many entities of a type are saved per chunk. Limiting arrows, snowballs, ender pearls, fireballs and experience orbs stops projectile lag machines from growing each time the chunk loads. 16 per type is plenty for normal play.
Armor stands tick every tick by default. On servers with hundreds of them for decoration, turning off armor-stands.tick and do-collision-entity-lookups saves CPU. Armor stands that do not tick are not pushed by water or pistons, so check any builds that move them.
Redstone, explosions and hoppers
misc.redstone-implementation picks the redstone engine:
VANILLA: the game's own implementationEIGENCRAFT: an older optimized version that removes many redundant updatesALTERNATE_CURRENT: a newer rewrite that is much faster for redstone dust
Both alternatives change the order in which some blocks update. Most builds work the same, but some technical contraptions that rely on vanilla's update order behave differently. Alternate Current is the usual choice on survival servers, and the Performance preset uses it. On a technical server, test your players' builds first or keep VANILLA.
environment.optimize-explosions caches entity lookups during explosions. TNT cannons and creeper farms get much cheaper, with slightly different results from vanilla.
The hopper section adds Paper's hopper options on top of the Spigot ones. cooldown-when-full (on by default) makes a full hopper wait before trying again. disable-move-event skips the Bukkit event fired for every hopper transfer, which saves CPU but stops plugins such as protection and shop plugins from seeing those transfers. Only turn it on if no plugin needs the event.
Chunks and tick rates
delay-chunk-unloads-by keeps a chunk loaded for a while after the last player leaves, so a player walking back and forth does not load it again and again. prevent-moving-into-unloaded-chunks stops players and vehicles from entering chunks that have not loaded, which blocks some lag machines and fast-travel exploits.
tick-rates slows down a few block updates. Grass spread at 4 is hard to notice and saves CPU across every loaded chunk. Mob spawners at 2 halve the cost of spawner farms. Leave container-update at 1: higher values delay inventory updates and have caused duplication glitches.
Recommended values by server type
| Server type | paper-global.yml | paper-world-defaults.yml |
|---|---|---|
| Small SMP | Defaults | Defaults, anti-xray mode 1 if X-ray is a problem |
| Busy SMP | Chunk generate rate 30 | Performance preset, anti-xray mode 2 |
| Backend behind Velocity | Velocity forwarding with the secret | As for the server type |
| Technical survival | Piston duplication on if players want it | VANILLA redstone, explosions not optimized |
| Creative or lobby | Player collisions off | Max entity collisions 2, armor stands not ticking |
Measure before and after each change. Understanding Minecraft TPS explains how to read TPS and MSPT, and a Spark profile shows what is using tick time. If you are still choosing a server jar, Paper vs Spigot vs Fabric vs Forge compares them.
Common mistakes
- Editing paper.yml on 1.19 or later. Paper ignores the old file once it has migrated it. Edit the files in
config/ - Velocity enabled with no secret, or the wrong one. With no secret, Paper logs an error and turns Velocity forwarding off, and a wrong secret kicks every player with "Unable to verify player details"
- Velocity forwarding and
bungeecord: trueboth on. Use one forwarding method. For Velocity modern forwarding,bungeecordinspigot.ymlstays false - Leaving the backend port open to the internet. With forwarding on, anyone who connects to the backend directly can claim to be any player. Firewall it so only the proxy can reach it
- Alternate Current on a technical server without testing. Some redstone builds break in ways that are hard to trace
- Setting a
_versionfrom another server. Paper refuses to load a config with a version newer than it knows. The generated files leave_versionout, and Paper fills it in with the right value on the next start
How to install the generated files
- Stop the server.
- Back up the
config/folder. - Download both files: pick
paper-global.ymlin the "File" select, download it, then pickpaper-world-defaults.ymland download that. - Upload them into the
config/folder, replacing the existing files. To keep settings this tool does not cover, copy only the sections you changed into your existing files instead. - Start the server. Paper prints a warning that the files had no version set and fills in the version and every key the files left out.
- Check the console for YAML errors, then join and test.
For the other files, the server.properties generator writes the vanilla settings and the JVM arguments generator gives you start flags. For managed hosting, check out ChunkPod.