public

Paper Chan's Little Guide to Minecraft Server Optimization!

Introduction / Background This guide is written in the style of a walkthrough, designed to expand on the information provided from the official documentation and putting additional emphasis on the gameplay

2 months ago

Latest Post Paperちゃん Project by EterNity public

Introduction / Background


This guide is written in the style of a walkthrough, designed to expand on the information provided from the official documentation and putting additional emphasis on the gameplay changes and potential side effects that come with optimizations. It aims to provide a deeper understanding on the inner working of a Minecraft server instead of just handing out pre-determined values which often do more harm than good. Hopefully this guide provides some useful insights to you!


Last updated: August 1st, 2022 for Paper Version 1.19.1 Build #101


Latest notable changes:

Our rat King SpottedLeaf has finished the second largest patch to-date on Paper with huge performance gains; however, the current patch is still in the Alpha stage and additional tests are required. If you would like to participate, please read the details on the link below!

Help us testing the upcoming Paper chunk rewrite!

Initial test has shown a 300% improvement over the old generation speed across the board and over 300 chunk per second with the latest 5950x CPU.

Table of Contents

Prerequisites
Getting Started
Configurations & Optimizations
Introduction
Pre-generate
View Distance
Entity Counts
Impacts of Alteration
Understand Mobspawn
server.properties
bukkit.yml
spigot.yml
Paper configs
Addendum
Timings tools
Common Mistakes
JVM Flags
Backup and Recovery Best Practice
Quality of Life Plugins & Tools
Things to Avoid
Hosting Options
Domain and Server Record
Closing Notes


Prerequisites🔗

Tools and Software for Windows Users

NotePad++ Notepad but better.
WinSCP SFTP client for file transfer.

Replace Tab with Space in NotePad++: Setting>Preference>Language>Replace by Space
Force Binary Mode in WinSCP: Options>Preference>Transfer>Binary


Getting Started🔗

Initial Setup
Install JAVA with this guide

Migrating from an existing Vanilla, Bukkit, or Spigot server
No additional action is required! Just replace the server jar with Paper.

Obtain official Paper jar
Download a server jar from Paper’s official download page

Launch the server
I. Launch through your terminal or with a startup script.
II. Generate a script with startmc.sh
III.Read more about the importance of JVM flags below
IV. Advanced read Prof_Bloodstone’s Guide


Configurations & Optimizations🔗

Before we start…

There is no singular setup that will work for every server. You should read and understand each available config option and tweak the numbers accordingly to fit your own unique circumstances. The optimal config for your server will vary based on server hardware, average player count, and the type of game mode running. Any value shown below is served as an example, please test and experiment, then come up with your own set of numbers.

💡
As your world ages and players progress into late game, the workload on the server would gradually increase over time so server optimizing is not a one-off task but a continuous effort.

With Modern Minecraft version, running on default (Vanilla) setting requires decent hardware and it may not be feasible for some small to medium sized servers where server resource are very limited. Aside from picking a reputable host and the right hardware, optimizing the configurations and making compromises to Vanilla gameplay becomes essential. Carefully read through the config options provided below and you will ensure a smooth operation!

Pre-generate Your Map🔗

Generating new chunks consumes a considerable amount of resources and it is recommended to pre-generate your map if you are launching a new map/server.

If you do not plan to set a world border, it is still a good idea to pre-generate 5~10k from your spawn as it will help ease the launch day stress on your server. Not to mention, it will catch any potential uncaught bugs on generation ahead of the actual launch day.

Grab Chunky and ChunkyBorder by pop4959
Chunky is the simplest pre-gen plugin and combined with ChunkyBorder, you can customize the border shapes to your liking.

💡
Please be reasonable when picking a border, the file size will grow exponentially the further you set the border and this may cause issues with storage and backup later on.

Picking the Optimal View Distance & Simulation Distance🔗

simulation-distance determines how much environment is active (ticking) around the player.
view-distance determines how many chunks (terrain) are visible to the player.

simulation-distance has a huge impact on the performance so having a lower value will help maintain a lagging-free environment. The default value for Vanilla Minecraft is 10 and most of the farm designs on YouTube are made based off this value. Lower this value will impact those farms, which we will go over later. Personally, I wouldn’t go lower than 5 so the gameplay experience is somewhat pleasant; however, if you are doing mini games or Skyblock, you can go much lower.

view-distance provides further chunks terrain view and is not as performance heavy as simulation-distance, but does occupies more RAM; increase the value incrementally to find your sweet spot on your server if you do decide to increase it.

Additionally, you can define individual values on a per world basis in spigot.yml to overwrite server.properties.
(We will cover how to proper set this up in per-world config section later)

Keeping Entity Count Under Control🔗

Entities are resource-intensive in the Modern Minecraft versions, even the top-of-the-line CPU in the current market would still be brought down to its knees if you do not keep entities under control.

Ideally, you want to maintain your overall entity ticks to be below 30%
(Assuming a reasonable amount of player activity is present and not just an empty server)
Timings is a great tool to find the source of lags and to compare the result of optimizations.

Be Aware of the Impacts of your Alteration🔗

With each alteration comes a compromise! Most of your players are just copying popular farm designs block by block without knowing how it actually works so it is important as a server owner to understand the impact of your alterations so you can explain them to the player better. In the following walk through, I will attempt to explain the impact of each change and how to combat compromises.


Understand Mob Spawn Mechanics🔗

Below is a demonstration on how mob spawning works around a player. The graph and indicated value is made based on Vanilla/Paper default.

Graph explanation 

  • The brown cylinders indicate the mob spawn range.
  • The red sphere indicates the mob spawning zone (inbetween 24 - 128 blocks).
  • The yellow sphere indicates the mob free zone as no mob will spawn that close to a player (24 blocks).
  • Any entity that falls under the 32 blocks ring (entity activation range) will be ticked at normal rate.
  • Any entity that resides in-between the 32 - 128 blocks ring will be ticked at a reduced rate.
  • Any entity that falls outside the 128th block is instantly despawned.
💡
Any alteration to the settings below requires you to adjust the farm’s overall size and its designated afk spot accordingly.

Vanilla / Paper default value

View Distance: 10 (chunks)
Simulation Distance: 10 (chunks)
Mob Spawn Range: 8 (chunks)
Despawn range (soft): 32 (blocks)
Despawn Range (hard): 128 (blocks)
entity activation range: 32 (blocks)

The 5 abovementioned config options are closely related to each other and it is crucial to ensure each value is setup correctly.

simulation distance determines the maximum possible size of a farm as area outside of this range will not be ticked.

mob spawn range also determines the maximum size of a farm as no mobs will spawn outside of this defined range.

Despawn Range (hard) or hard despawn-range is the furthest away a mob can exist without instantly despawning.

When troubleshooting why a farm is not working, be sure to go through every config mentioned above and make the necessary modifications to the farm design accordingly. Do not copy and paste from YouTube tutorials block by block without ever taking these configs into account.

Take a look at Paper Chan’s Little Guide to fix your Nether farm for a sample walkthrough on common troubleshooting steps.


New in 1.19, why is my farm built in older version slower now when nothing has changed?

Minecraft runs the spawn check between the lowest block and the highest block (ranging from Y0 to Y265 in 1.17) to check and see if the block is eligible for a spawn attempt, it then has a 24% change to successed at spawning at that particular Y position.
Farms are designed based on this rule and their ideal location is chosen accordingly.

Large perimeter – Making a large perimeter around your farm eliminates all other possible spawn locations but the designated spot on the farm platform. (This can be seen on the SciCraft server and in most farm tutorials that use void flat-world for demonstration)

Enderman farm at Y0 – Enderman farms are advised to be built at Y0 as it is the most effective location.

Nether Farm above Netherroof – Nether farm are usually built high above Netherroof as it is generally a pain to make a large perimeter due to the amount of lava present, and by going higher into the Netherroof, you move your despawn sphere high up in the sky to eliminate all possibilities of a mob spawning anywhere outside of your farm platform.

With that being said, your farm may be less effective now due to the world height change. Instead of checking for an eligible spawn attempt from Y0 to Y265, it’s now checking from Y-64 to Y320 to find the lowest & highest block to run spawn attempts. Your farm from 1.17 located on Y0 now has 64 more additional blocks below it, which slows down the mob spawning.

How to mitigate the issues…

Rebuild your farm at the lowest point of the world which is now Y-64.
(This is the most ideal solution but also the most painful).

Dig out an even larger perimeter & empty out everything below the farm from Y-64 to Y0 (air block only).

Mob spawn attempts are made on all loaded chunks with defined spawn-limits in bukkit.yml (or paper-world-defaults).

Accept & understand that mob spawning is inherently flawed in multiplayer servers and a more detailed explanation is provided in the per-player-mob-spawns section later.

💡
TL;DR The most effective farm location is at the lowest possible Y level with only air block above. Due to the world height change your farm is no longer at the most ideal location.

server.properties🔗

Essential configurations for server.properties

view-distance=10

This sets the view distance (terrain only) of the server unless stated otherwise in spigot.yml.

simulation-distance=10

This sets the simulation distance (ticking) of the server unless stated otherwise in spigot.yml.

Picking a suitable combination of view-distance & simulation-distance is extremely important.

If you decide to lower your view-distance & simulation-distance,...
Please refer to How Mob Spawn Works to ensure all other configs are adjusted accordingly.

If you wish to provide further terrain view to players, please note that each additional increase after 10, the total amount of loaded chunks around a player will increase exponentially.
The formula to calculate the total chunks loaded by a single player is [(View Distance +2)x2+1]^2

Although view-distance uses significant less resources compare to simulation-distance, please still be mindful on its performance impact especially on large server where every bit of resource saving helps.


allow-flight=true

This prevents players from getting kicked by the server for "flying" while riding a horse or climbing on scaffolding.

Having this option as false doesn't mean everyone can fly, it just means that players would not get kicked if the server thinks they are flying.


bukkit.yml🔗

Essential configurations for bukkit.yml

spawn-limits:
  monsters: 70
  animals: 10
  water-animals: 5
  water-ambient: 20
  water-underground-creature: 5
  axolotls: 5
  ambient: 15

This section determines the mob cap in your server. Lowering the value on monster has the most direct impact on server performance, as entities are one of the most resource intensive tasks the server has to tackle.

Changing spawn-limits requires you to look over other related config.
Refer to Understand Mobspawn section for more details.

💡
To help maintain the Perceived mob density consistent with Vanilla default, please also alter the mob-spawn-range in spigot.yml accordingly to achieve this illusion.

For a detailed explanation on how the calculation is done click here to expand...

For example, if I want to set my monster cap to 45 and also keeping the mob density roughly the same as before, I would solve the math equation below

(Default mob Cap) : (Default Spawn Area) = (New Mob Cap) : (New Spawn Area)

where the constants are as followed,

Default Mob Spawn Range = 8 chunks
Minimum distance where a mob can spawn = 24 blocks away from a player

Default Spawn Area = [ (Mob Spawn Range x2 x16) +1]^2 - ( 24 x2 +1 )^2 = (8x2x16+1)^2 - 49^2 = 66049 - 2401 = 63648

70:63648 = 45:b ; where b = New Spawn Area (in blocks)

63648 x 45 = 70b

b= 40916

Let a = New Mob Spawn Range, where b = [ (a x16 x2) +1]^2 - (24 x2 +1)^2, and b = 40916

(32a +1)^2 - 2401 = 40916

(32a +1)^2 = 43317

32a +1 = 208

32a = 207

a = 6.46


I will then set mob-spawn-range to 6 (or 7) in spigot.yml

Here is a cheat sheet with prefilled suggestions for those who are too lazy to workout the math or failed high school algebra, please read carefully and apply the config accordingly.

Overall Entity Count (%) Suggested spawn-limit in bukkit.yml Suggested mob-spawn-range in spigot.yml Actual Calculated Number
100% (Vanilla) 70 (default) 8 (default) 8 (default)
90% 63 7 or 8 7.6
80% 56 7 7.18
70% 49 6 or 7 6.74
60% 42 6 6.26
50% 35 5 or 6 5.75
40% 28 5 5.18
30% 21 4 or 5 4.55
20% 14 4 3.81
10% 7 3 2.89
3% 2 Please upgrade your server hardware My Samsung smart fridge can handle more entities

The suggested numbers above are for the purpose of keeping the mob density consistent with Vanilla, feel free to make up your own numbers that work for your server. Please do go over Understand Mobspawn section to validate other configs again as needed.

Please note that the required light level for monster to spawn has been changed to 0 in 1.18. It is increasingly common to run into a situation where the available spawnable area for monster is extremely small; as a result, they appear to be more concentrated on a dark spot, especially around the edge of your lighted base or underground in a closed cave. Adapt to this change accordingly and lower the number as you see fit for your server!

Analyze your timing report during the busiest time where the most players are online.

Every mob in the game falls under 1 of the 7 categories, click to expand the list for details...

  • monster category consists of blaze, cave spider, creeper, drowned, elder guardian, ender dragon, enderman, endermite, evoker, ghast, giant, guardian, hoglin, husk, illusioner, magma cube, phantom, piglin, piglin brute, pillager, ravanger, shulker, silverfish, skeleton, slime, spider, stray, vex, vindicator, witch, wither, wither skeleton, zoglin, zombie, zombie villager, zombified piglin.
  • animals or creature category consists of bee, cat, chicken, cow, donkey, fox, goat, horse, llama, mule, mooshroom, ocelot, panda, parrot, pig, polar bear, rabbit, sheep, skeleton horse, strider, trader llama, turtle, wandering trader, wolf, zombie horse.
  • ambient category consists of bat. Bat is useless.
  • water-animals or water_creature category consists of squid and dolphins.
  • water-ambient category consists of cod, pufferfish, salmon, tropical fish.
  • water-underground-creature or underground_water_creature category consists of Glow Squid.
  • axolotl category consists of Axolotl.

    Some categories have two different names listed due to Paper using the proper names in related paper configs while bukkit.yml still uses the old names.
💡
Each entity will show up individually on the timings report, you can make necessary adjustments accordingly based on their categories.
💡
Bat is the only entity in ambient and it has no gameplay functionality so it is safe to set ambient to zero for a no compromise performance saving there.

ticks-per:
  animal-spawns: 400
  monster-spawns: 1
  water-spawns: 1
  water-ambient-spawns: 1
  water-underground-creature-spawns: 1
  axolotl-spawns: 1
  ambient-spawns: 1
  autosave: 6000

This section determines the frequency of each category of entities making an attempt to spawn (value in ticks).

Minecraft will always attempt to spawn entities until it hits the spawn-limits on previous section. Altering the number here should be your secondary choice due to the fact that the mob cap will almost always be reached. All you are doing is just delaying the impending doom, please establish a proper entity cap on the spawn-limits mentioned previously first.

Calculating and validating mobspawn costs resources and it is always a better idea to reduce the overall entity cap on spawn-limits first, then increase ticks-per config here as a secondary buffer. Please utilize /paper mobcaps and /paper playermobcaps to monitor and ensure the mob cap is always being reached. If your mobcap cannot be reached in a timely matter, it's probably a sign that your spawn-limits is either too high and/or your mob-spawn-range is too short.

This option is a direct nerf to all mob farms yield rate, so picking an ideal number here is very important as it is a fine balance when it comes to optimizing and balancing gameplay experience.


spigot.yml🔗

Essential configurations for spigot.yml

view-distance: default
simulation-distance: default

This serves as an overwrite to the identical config in the server.properties

Putting a value here will overwrite the value inside server.properties
The value default instructs the server to use the value from server.properties

The value can be set per-world if an additional category is created.


mob-spawn-range: 8

Radius in chunks around a player in which server attempts to spawn mobs.

As mentioned previously in the bukkit.yml section, this value can be altered to adjust the perceived mob density.

This value should always be set to a maximum of (Simulation Distance - 1) with a minimum of 3, as any entity falling outside of the simulation distance and the bordering chunk wont be ticked.
(see note below)

If you are running with the Vanilla default simulation-distance of 10, you can adjust the number between 8~3 without following the above rule.

If your mob-spawn-range is higher than the simulation-distance for example, the perceived mob density would be lower due to the fact that monsters would attempt to spawn outside of your simulation-distance. It is crucial to have the correct value.

For example, if you have a simulation-distance of 6, your mob spawn range can be set between 3~5.

Technically, 3 is not the minimum value, but due to the fact that no mobs will spawn within 24 blocks around the player, it makes zero sense to go below 3 as it drastically reduce the spawnable area and mob cap may not be reached in extreme case.

Refer back toUnderstand Mobspawn section for full detail.


nerf-spawner-mobs: false

This setting removes AI from mobs spawned from a spawner. If your server allows players to relocate spawners, setting this option to true can reduce lag.

Please also toggle spawner-nerfed-mobs-should-jump to true in paper-world-defaults.yml if you do decide to enable this. It will allow mob to jump so certain farms will remind functional.


max-entity-collisions: 8

The value is the maximum amount of entities that should be included in collision lookups. The server will stop processing any additional entity collisions after this threshold.

Lowering this value will help with performance as the animal AI goes haywire trying to path-find away from each other in a small confined space.

Do not set the value lower than 3 as it will have game-breaking effects on things that rely on collisions in order to work properly.

This is not to be confused with gamerule maxEntityCramming.


entity-tracking-range:
  players: 48
  animals: 48
  monsters: 48
  misc: 32
  other: 64

entity-tracking-range determines how far away in blocks that an entity is tracked and sent to the client in order for players to see them.

Paper provides these options for you to decide how far away an entity should be tracked (display to client) instead of tracking everything up to bordering chunks (simulation-distance -1). This is an optimized solution to combat expensive entity tickings.

You can find related performance merits in your timings report listed under Chunk provider tick.
tracker stage 1 is tracking entities.
tracker stage 2 is broadcast entity tracking changes.

If Chunk provider tick is taking a significant amount of resource, you should first try to reduce overall entity counts, then lower simulation distance; and if all else failed, reduce tracking range as a last resort.

💡
For small scale survival servers or servers with decent hardware, you may increase some categories to enhance the gameplay experience for your players with an implied performance tradeoff.

entity-tracking-range categories


  • player consists of players.
  • monster consists of monster, raider, and flying monster.
  • animal consists of villager, water-animal, and animal.
  • misc consists of itemframe, painting, sign, dropped item, experience orb.
  • other consists of everything not listed above (I.E. armor stand).

The value is in blocks and should always be set to a maximum of (simulation-distance -1)x16 and no lower than 1.
(BONUS fact: Setting the value to 0, all entities will be hidden; setting the value to -1, all entities will essentially become ninja! PLEASE DONT DO THIS)

If you are experiencing invisible Ghast Ambush, it may be a symptom of your entity-tracking-range for monster is set too low.

💡
If you make changes to the entity-tracking-range, please also adjust and match the value in the corresponding category on entity-activation-range as well, so players do not see frozen entities.

entity-activation-range:
  animals: 32
  monsters: 32
  raiders: 48
  misc: 16
  water: 16
  villagers: 32
  flying-monsters: 32
  wake-up-inactive:
    animals-max-per-tick: 4
    animals-every: 1200
    animals-for: 100
    monsters-max-per-tick: 8
    monsters-every: 400
    monsters-for: 100
    villagers-max-per-tick: 4
    villagers-every: 600
    villagers-for: 100
    flying-monsters-max-per-tick: 8
    flying-monsters-every: 200
    flying-monsters-for: 100
  villagers-work-immunity-after: 100
  villagers-work-immunity-for: 20
  villagers-active-for-panic: true
  tick-inactive-villagers: true
  ignore-spectators: false

entity-activation-range determines how far away (in blocks) an entity should be activated.

Any entity falling outside of this zone will be ticked at a reduced frequency.

Those values should always be set to a maximum of (simulation-distance - 1)x16 and no lower than 16 if you are running extremely low simulation-distance/view-distance on your server.

💡
Altering activation range will impact all aspect of gameplay as many mechanic relies on this to function properly so tread carefully.

A value of -1 will disable this behavior and restore the behavior to Vanilla; however, this is a huge performance hit to your server. Do so at your own risk and only when absolutely necessary.

Reducing entity activation range should be the last resort...
You should lower the overall entity count & simulation-distance/view-distance first. Only alter this config if all other measures are proven insufficient to improve performance.

tick-inactive-villager could be changed to false if you do not wish to tick all villagers that are loaded but outside of activation range. In other words, only villagers that are within the activation range will be active.

If you are experiencing inconstancies with Minecart transfer rates while not on a rail, please change misc to -1 to remedy the issue. EAR may impose a negative effect and break redstone contraption in this particular use case.


work immunity and wake up inactive are implemented by Paper with the goal of bringing more liveness to the world by allowing certain entities to "wake up" and do some work for a set amount of time. It allows villager to restock, find work etc...

Change max-per-tick to 0 if you do not want this behavior.
Click here to read EAR Commit message on Github

To elaborate a bit more, we will use this snippet of wake-up-inactive below as an example to help you get a better understanding of this mechanic.

wake-up-inactive:
  animals-max-per-tick: 4
  animals-every: 1200
  animals-for: 100

The above setting translates into the following behavior...

For every 1200 game ticks, there is a chance of up to 4 randomly selected loaded animals to wake up for 100 ticks where they are able to do stuff and be immune from the freezing effect of being too far away from players.


merge-radius:
  item: 2.5
  exp: 3.0

Paper merges dropped items and exp orbs more aggressively to reduce the performance impact of having a large amount of dropped items on the ground.

The value is in blocks, adjust accordingly to your needs.

A value of -1 disables it. Do note that this is a degradation in performance.

Alternatively, you can adjust experience-merge-max-value in paper-wolrd-defaults.yml if you wish to still merge the exp orb but with a set amount of maximum value.

If you wish to restore Ender Dragon exp rain when defeated or just love seeing a bunch of exp orb coming towards you when you sit afk on your farm, you can disable this option with the implied performance tradeoffs.

💡
If you are having issues with experience orb not floating towards the player as they merge and bulk-up together, either enforce a max merge value as mentioned above or disable exp merging to remedy the issue.

Paper configs🔗

New in 1.19, the structures for paper config options has been improved.

A new config folder now stores the default & the global config files located on your Minecraft root folder.

paper-global.yml consists of all available global config.
paper-world-defaults.yml consists of the default config for all worlds.

A new per-world config file is generated in every world folder.

paper-world.yml can be edited to overwrite the config on a per-world basis and is located in /[world_name]/paper-world.yml

paper-world-defaults.yml🔗

Essential configurations for paper-world-defaults.yml

despawn-ranges:
  ambient:
    hard: 128
    soft: 32
  axolotls:
    hard: 128
    soft: 32
  creature:
    hard: 128
    soft: 32
  misc:
    hard: 128
    soft: 32
  monster:
    hard: 128
    soft: 32
  underground_water_creature:
    hard: 128
    soft: 32
  water_ambient:
    hard: 64
    soft: 32
  water_creature:
    hard: 128
    soft: 32

This value defines how far away a mob should have a chance to despawn (soft) or instantly despawn (hard).

Please refer to the bukkit.yml section to see what each entity falls under what category.

If you kept your simulation-distance as default 10, lowing the hard value will increase the perceived mob density with a cost of extra depsawn/spawn action on the server.

💡
No mobs will naturally spawn within 24 blocks or less around a player so it is not recommended to lower the hard despawn range below 32.

If your simulation-distance is set lower than 10, expand and read this!

The value of hard despawn-range should be (simulation-distance -1)x16 blocks and no less than 32 blocks. 

  • This ensures all entities have a chance to despawn before hitting the bordering chunk thus preserving natural mob density.
  • Altering this config will impact the default afk spot on farms as the range limit is enforced both horizontally and vertically. Adjust farm designs accordingly.
  • If you do chose to run the default value of 128 to keep the ideal afk spot persistence against Vanilla while running a lower simulation-distance and/or mob-spawn-range, you will experience odd mob density, extremely uneven mob spawning, and/or excessive amount of mobs over spawn-limits.

To help virtualize the side effect of keeping the hard despawn-range higher than ticking view-distance, please read the following scenario...

A player named BumbleTree is just chilling in his Minecraft base. He has made a simple mob grinder by his bed because he enjoys sleeping with the sound of zombie growling so he usually keeps a few dozen of them alive inside the grinder until he needs the experience.

On a Saturday night, BumbleTree decides to visit his Minecraft girlfriend Naomi so he leaves his base by foot. As he moves away from his base, all the zombies inside his grinder are unloaded with the chunk. While he is away, a player named Jerry happens to travel by his base and decided to steal some wheats from the chest. Jerry also noticed something weird! It's night time but there is hardly any mob spawning around him!?

This is because the mobcap is already reached with the zombies still inside the grinder. The zombies were never given a chance to properly despawn so when a new player visit the area and loaded the chunk, no new mob will spawn due to the fact that mobcap is already saturated thus creating an illusion that no mob is actually spawning. This is why it is crucial to ensure the hard despawn-range is in line with the suggested value above. It ensure all mobs are being despawned and redistributed properly.

Now that you understand the role of hard despawn-range, choose your own poison and choose wisely!

💡
The hard despawn-range should also always be equal to your mob-spawn-range in spigot.yml and never lower.

per-player-mob-spawns: true

Paper would attempt to spawn mobs more evenly across all players online.

Ensure this option is set to true. This is beneficial to the majority of servers.

When enabled, the global mob cap will scale based on the number of players online.
To access detailed breakdown of mobcaps, use the following commands...

/paper mobcaps for global mobcaps and total spawnable chunks.
/paper playermobcaps for player mobcaps.

💡
These two commands is especially useful for troubleshooting mobfarms. Run the command while standing on the afk spot of a farm, and if no mobs are spawning inside the farm while the mobcap is already full, it means that you have failed spawn-proofing.

Spawnable chunks are based on the number of loaded chunks and the spawn-limits as defined in bukkit.yml (or paper-world-defaults.yml). Please make adjustments when necessary, especially if you do not have it enabled prior.

Vanilla mob spawning is not only complicated, but also inherently flawed on multiplayer servers

For example, we have two players in the Nether dimension - Player A is AFKing high up on a Nether ceiling Piglin farm while player B is just chilling on Nether Waste biome.

Even though the spawn attempts are made on all loaded chunks around both players; a vast majority of the successful mob-spawn attempts will end up around the player with the most favorable spawning conditions.

In this case, player B will be getting most of the mobs while player A gets a little simply because there are more spawnable chunks around player B overall.


prevent-moving-into-unloaded-chunks: true

This prevents players from moving into an unloaded chunk which would otherwise cause a sync-chunk load.

When a player moves into an unloaded chunk, the server would make the task of loading the chunk with the highest priority, thus tanking the TPS.


redstone-implementation: alternate-current

Paper provides options to specify the redstone implementation the server uses.

The available options are vanilla, eigencraft, and alternate-current with Vanilla being the default.

alternate-current implementation is more efficient and recommended, but come with possible behavioral changes. Please use with caution!

For technical details on alternate-current, read more here.


treasure-maps:
  enabled: true
  find-already-discovered:
    loot-tables: default
    villager-trade: true

Paper provides options to further mitigate the performance issue around treasure maps.

By toggling the villager-trade option under find-already-discovered to true, it will reduce the performance impact of treasure maps. (map will no longer try to find undiscovered treasure instead returns the nearest one)

You could also completely disable the functionality of treasure mapss by setting enabled to false.

Due to how Vanilla Minecraft generate/lookup new loottable from treasure map found via cartography villager or dungeon loot chest, the server may stall due to the potentially large amount of lookup done when it attemps to locate a chest in undiscovered area (loot chest is only generated when a player opens it).

The issue can be mitigated by the two options provided above and with its own set of negetive impact to the Vanilla gameplay; however, it is sometimes necessary to prevent the huge lag spike or prolong server stall that results in server being killed by the watchdog.


fix-climbing-bypassing-cramming-rule: true

This fix the issue where climbing mobs bypass the cramming rules

Leave it false if you have farms that utilize this behavior (very unlikely).


keep-spawn-loaded: true
keep-spawn-loaded-range: 10

If your world spawn isnt frequently used, you can toggle this option to false.

The world spawn will not be loaded thus saving resources.

💡
This option can be defined per-world and is a good resource saving measure if you have added additional worlds that are not heavily utilized.

The range value is in chunks, and the formula for total chunks to be kept loaded is [((keep-spawn-loaded-range+1)x2)+1]^2

With keep-spawn-loaded-range at 10, [(10+1)x2+1]^2=529, you would constantly have 529 chunks loaded.


entity-per-chunk-save-limit:
  experience_orb: 50
  snowball: 20
  ender_pearl: 20
  arrow: 20
  fireball: 10
  small_fireball: 10
  dragon_fireball: 5
  egg: 20
  area_effect_cloud: 10
  llama_spit: 5
  shulker_bullet: 8
  spectral_arrow: 5
  potion: 5
  experience_bottle: 5
  trident: 10
  wither_skull: 10

This determines the maximum amount of each specified entity saved in a chunk.

The limit here is essential as it prevents the server from stalling when attempting to load a chunk that contains a large amount of these projectile entities.

It is especially critical to enforce them plus the additional additions listed above if you are running an extremely low simulation-distance.

(Sometimes projectiles are being fired into unloaded chunks intentionally by players to crash a server, or unintentionally by sheer luck. Both of which can be avoided with these limits set in place)


alt-item-despawn-rate:
  enabled: true
  items:
    cobblestone: 600
    cobbled_deepslate: 600
    netherrack: 600
    rotten_flesh: 900
    ender_pearl: 900
    leather: 900
    bone: 1200
    bone_meal: 1200
    cactus: 900
    egg: 900
    feather: 900
    gunpowder: 1200
    arrow: 900
    blaze_rod: 1200
    cod: 1200
    salmon: 1200
    string: 1200
    ink_sac: 900
    slime_ball: 1200
    phantom_membrane: 900

Enabling this option will allow you to despawn commonly dropped items/junk items faster

cactus is added on the list in an effort to reduce the impact of the common cactus farm in which many cactus would be left on the surface until they despawn due to the farm design.
egg is also listed here in an effort to prevent zombie from picking them up thus preventing them from desapwning. It is a common issue in survival servers where players may be afk for an extensive period of time and results in groups of zombie all holding commonly dropped items around the player bases.

The value is in ticks which means a value of 20 equals to 1 second of server time.

Additional items can be added to the list above and you should find your own reasonable value that suits your needs as every server has their own unique circumstances. For example, if a farm utilizes minecarts in a closed loop to pick up drops, you want to ensure the value isn't set too low, so the minecart is able to pickup items before they despawn.

To acquire the official Mojang item ID, simply use the hotkey F3+H in game.

Additionally, there is a similar config item-despawn-rate that controls all dropped-item despawn timer in spigot.yml; however, that is a very intrusive change that breaks the 5 minute de-spawn time promise that most Minecraft players are familiar with, hence why it is omitted here.

The goal of optimizing the server is to make the game more enjoyable for your players not to make them suffer!


tick-rates:
  behavior:
    villager:
      validatenearbypoi: -1
  container-update: 1
  grass-spread: 1
  mob-spawner: 1
  sensor:
    villager:
      secondarypoisensor: 40

Paper provides finer control options govorning certain ticking rates

Increase the value here will reduce the resource usage with some cost to their respective behaviors.

If your server is experiencing villager related performance issue, first try to play around with this config before moving onto a plugin solution.

For example you can increase secondarypoisensor to 240 and validatenearbypoi to 120 to save resources. The negative behavioral change is likely not noticeable.

Increasing grass-spread too high will result in many ugly dirt patches if you have a lot of animals around.


optimize-explosions: false

Setting this to true will reduce the impact of calculating a large amount of explosions.

The actual real world scenario that would benefit from this is minimum; however, if your friends love to blow things up with an unholy amount of TNTs, this setting may be right for you.

In case you do really love to blow things up and noticed that your TNT detonation does not behave like vanilla, increase the max-tnt-per-tick threshold located in spigot.yml to remedy the issue.

Please do note that the threshold is there to safeguard your server and increase the value would also increase the risk of your server crashing in the event of large amount of TNT detonation.


armor-stands:
  do-collision-entity-lookups: true
  tick: true

This decides whether armor stand should be ticked & accounted for collisions.

Setting these to false will...
completely remove any armor stand related lag machines.
break plugins that utilize armor stands.
break farms such as an automatic ice maker .


lootables:
  auto-replenish: false
  max-refills: -1
  refresh-max: 2d
  refresh-min: 12h
  reset-seed-on-fill: true
  restrict-player-reloot: true

Toggle auto-replenish to true if you plan on running a long-term survival server. It replenishes the chest once looted and would bring some life back to your old worlds.

max-refill sets the maximum refills, a value of -1 will make it unlimited.

refresh-min/max defines the amount of time passed before the chest is refilled.
This does not require the chunk to be loaded.

The units of measurement here are m for minutes, h for hours, d for days. m is NOT for months!!

reset-seed-on-fill will shuffle loot table seeds on each refill so the items inside the chest will always be different.

restrict-player-reloot will stop the same player from camping and looting the chest multiple times.

Scenario 1: If a player loots a chest once and comes back later, there will not be new loot.
Scenario 2: If player A loots a chest and then player B comes by later, the chest will be refilled and lootable for player A again.

The chest will refill regardless of the remaining items inside unless it is full.

Scenario 1: If player A opens the chest (generated the loot) and leaves the loot inside, player B that comes by later will get a set of newly generated loot plus whatever that was left by player A previously.
Scenario 2: if player A opens the chest and fill it up with diorite, player B who that comes by later will get nothing new (but diorite) because the chest is already, full thus no new loots will be generated.

💡
The lootables refill feature only works with the original world-generated chests. Please let your players know to not break them.

generate-random-seeds-for-all: true

Toggling this option to true will give seed cracker tools a harder time to determine your world seeds. It is a very useful feature if you aim to migrate the unfair advantages player may have if they manage to figure out your world seed.

Please note that this config covers features only, for generated structures, please manually alter the structure seeds in spigot.yml.

All structure seeds excluding Mineshafts, Ancient City & Bastion Remnant are available in spigot.yml.

Do note that this does not affect chunks that are already generated once. If you want to take full advantage of this feature, it will work the best on a brand new world.

To enable this feature properly, please expand and follow the steps within...

  1. Start the server in order for the paper-world-defaults.yml file to be generated then stop the server.
  2. Open up paper-world-defaults.yml located inside config folder and set generate-random-seeds-for-all to true.
  3. Open up spigot.yml and manually input the structure seeds to your liking.
  4. Start the server then you are good to go!
  5. BONUS: if you want to define individual feature-seeds, you can go back to paper-world-defaults.yml and set them manually.
  6. Remember to delete the world after for spawn region to be generated properly
    (or alternatively, set keep-spawn-loaded to false after step 3.)

To manually define world seed, add level-seed=[seed number] line onto server.properties or edit your level.dat with NBT Editor then perform the steps above.

Once the feature is enabled, you will find a new section with randomly generated feature-seeds listed in your paper-world-defaults.yml & paper-world.yml if you have any other per-world specific configs, be sure to add them under the corresponding categories.

💡
Please note that this may not prevent seed-crackers from brute forcing your world seed; however, this option does render the advantage of knowing the world seed useless, as locations of all features and structures will not line up with the world seed. However, the only real way to completely prevent seed-cracking is having custom world generation.

monster-spawn-max-light-level: -1

Paper provides an optional config to adjust the required light level for mobs to spawn.

A value of -1 follows the Vanilla default.

In 1.18 and later version, mobs can only spawn at light level 0.
In 1.17 or older, mob can spawn at light level up to 7.

The value can be any integer from 0 to 15.


paper-global.yml🔗

Essential configurations for paper-global.yml

chunk-loading:
  autoconfig-send-distance: true
  enable-frustum-priority: false
  global-max-chunk-load-rate: -1.0
  global-max-chunk-send-rate: -1.0
  global-max-concurrent-loads: 500.0
  max-concurrent-sends: 2
  min-load-radius: 2
  player-max-chunk-load-rate: -1.0
  player-max-concurrent-loads: 20.0
  target-player-chunk-send-rate: 100.0

Paper provides control over how chunk data is sent to players. The default values listed above should work for the majority of the server.

If you are troubleshooting chunk loading issues, please consult the #paper-help channel first for advice first, do not alter the values without fully understand what they do. Do not follow any random guide for recommended value, there is a lot of misinformation out there!

For servers with large concurrent player counts, if chunk loading is noticeably slower during the peak hours, try increasing max-concurrent-sends and global-max-concurrent-loads gradually to remedy the issue.

💡
Higher value in chunk-loading isnt always better. Minecraft client may glitch out if the server is sending chunk too fast. Please perform your own testing and come out with a set of value that works for your server.

logging:
  log-player-ip-addresses: true

Paper provides an option to toggle player IP address logging.

For those who wants to protect player privacy, you can toggle this option to false.

This is especially useful in times where log files need to be shared with a third party auditor, maintainer, or developer for general troubleshooting.


book:
  author: 8192
  page: 16384
  title: 8192
book-size:
  page-max: 2560
  total-multiplier: 0.98
display-name: 8192
lore-line: 8192
resolve-selectors-in-books: false

Paper provides the options to adjust the overall size of a book. This is an useful feature to prevent bookban either on purpose or by accident (unlikely).

The value of page-max is in bytes. It is safe to reduce the it by half or more to your liking (I.E. 640~1280)

Additionally, you can utilize a plugin to ban non-ASCII characters in a book which is listed in Quality of Life Plugins & Tools


Per-world Config🔗

New in 1.19!

All default config will now be stored inside config folder on your Minecraft root folder.
The per-world config can now be defined in paper-world.yml located in /[world_name]/paper-world.yml (The default file is empty)

Paper allows you to enforce a custom set of config in paper-world.yml to overwrite the default value in the paper-world-defaults.yml such as mob caps.

paper-world.yml file is located inside each of your world folders.

The following section serves as an example to help you virtualize the file structures...

Minecraft root folder/config/paper-world-defaults.yml
  spawn-limits:
    monster: 70
    creature: 10
    ambient: 15
    axolotls: 5
    underground_water_creature: 5
    water_creature: 5 
    water_ambient: 20

/world_nether/paper-world.yml
  spawn-limits:
    monster: 80
    creature: -1
    ambient: -1
    axolotls: -1
    underground_water_creature: -1
    water_creature: -1
    water_ambient: -1

/resource_world/paper-world.yml
  spawn-limits:
    monster: 5
    creature: 30
    ambient: -1
    axolotls: 10
    underground_water_creature: -1
    water_creature: -1
    water_ambient: -1
  keep-spawn-loaded: false

In the above example, by having a lower monster value in resource_world and have keep-spawn-loaded as false, you just made the resource world a bit safer for miners and also reduced the overhead on the server by not keeping the spawn chunks loaded because they are not actively being used.

💡
With some clever uses of per-world configs, you can save on server resources while keeping an optimal gameplay experience for your players.

Expand for additional notes...

Paper uses proper category names here as opposed to old Bukkit names for the categories.

  • creature is the same as animals in bukkit.yml
  • water_creature is the same as water-animals in bukkit.yml

default are options that apply to every world unless stated otherwise in the world categories.

  • world is overworld
  • world_nether is Nether dimension
  • world_the_end is End dimension
  • Additionally, if you have other custom worlds, they can also be added under world-settings.

A value of -1 means it will follow the value as defined by default. (in case of spawn-limits, by mob-cap in bukkit.yml)

YML file uses 2 spaces for indentations. Do not use tab.

Make sure the indentation is correct in tree-like structures. (two spaces for each step of indentation)

A proper yml editor will help ensure formatting isn't borked.

The console will puke up an error on startup if a mistake is made. Correct them accordingly.


Paper's own built-in Anti-Xray🔗

Paper has built in Anti-xray feature and if you do choice to enable it, please follow the below post carefully.

PaperMC Anti-Xray Documentation

Be sure to stop and start the server again for the new config to apply. Do not use /reload

If you spend the time to read the official documentation and still do not understand how this works, please read and use this

Please note that engine mode 2 works fine on majority of servers; however, on server with high concurrent player counts (100+), usage of engine mode 2 may sometimes saturated the network pipelines as more data is being sent to players.


Addendum🔗

There are many things I left out and that is not without a reason. Those other settings often introduce too much gameplay compromises or only have minimum performance improvements on a majority of small-to-medium size server. For a full list of available configs, check out the official PaperMC Documentation.

Modern Minecraft is resource demanding and there is only so much you can optimize until you gotta ask yourself, is this still worth the effort?

There is only so much you can take out of a car to make it go faster until you are left with nothing but a steering wheel and a bare chassis, the same applies to optimizing your server.

If tweaking the above-mentioned configs is not enough to help maintain a stable TPS (18~20) on your server, I will strongly suggest looking into a direct hardware upgrade as this will be the most direct way to see any further performance improvement. See Hosting Options below for more information.

At the time of writing, even with the latest hardware available, 60-80 players with close to vanilla default configs or 100 player with huge game player compromises is the hard ceiling. At that point, impose a reasonable max player limit on the server and start thinking about network expansions with multiple servers) and congratulation on your achievement!


Timings Tool🔗

Paper comes with a built-in profiler to help troubleshoot the performance issues.

Type /timings report in game or on console (without /) to generate a report.

You will be given a link that looks like this...
https://timings.aikar.co/?id=14a142949f42468f81bdb49613a2abdd

This report contains necessary information for you to troubleshoot problems.
Here is a video that goes over everything by our beloved Aikar

Tips for generating a meaningful timing report...

Avoid generating timing report right after server startup as the data will be skewed.

  • Allow the timings data to be recorded for a longer duration
    (The minimum is 10 minutes but the longer the better)
  • The ideal time to generate a report is during the peak player activities or right when the server is lagging.

Giant Red Number does not always mean your server is lagging.

💡
Timings page has Lag view and All view tabs. A few Red lagging tick out of a few thousand ticks overall is very much acceptable.

Common Mistakes🔗

Gigahertz Myth
When selecting CPUs for your Minecraft server, do not use the clock speed rating to compare two CPUs unless they are of same model and manufacture. Please refer to Gigahertz Myth for more info.
In short, select the latest cpu architecture and the highest single core thread rating model available.

Allocate more RAM =/= better performance
Server performance is largely dependant on your CPU, not RAM.
A majority of servers will be fine with 10GB allocated regardless of player/plugin count. Any host who claims more RAM would increase your server performance is trying to upsell you for their own profit gains. Do not fall for this trap.

RAM usage is not an indication of performance issues.
RAM usage reading gathered from panels/htop is very much meaningless on a properly setup JVM. Instead, monitor your GC intervals and durations for potential issues.

High memory usage =/= Memory leak
It may be a symptom of a memory leak but is not necessarily true in most cases.
Generate a heap report during the suspected period when you think the leak is occurring with /paper heap dump command then feed the report through Eclipse Memory Analyzer or other similar programs to troubleshoot the issue. You can also seek help in the Paper Discord.

TPS is not an accurate measurement of performance.
Instead you should pay attention to MSPT (milliseconds per tick). Minecraft runs on a fixed rate of 20 ticks per second, so as long as your MSPT is lower than 50, you will maintain 20 TPS.
A server could show a 20 TPS average but with a high percentage of TPS lost, players may still experience lag in this scenario.

The minimum recommended thread/core count for a Minecraft server is FOUR.
While it is true that Main game loop is all done on 1 thread, there are many tasks that can benefit from having multiple threads, such as Netty, plugins, SQL databases etc.
It is recommended to have at least 4 threads/cores for most servers. If you are shopping for a host, please take this into consideration and select your plan accordingly. A lot of the budget hosting plan is borderline unusabe.


JVM Flags (A Must Have)🔗

You should always opt to use Aikar's optimized JVM flags for your Minecraft server.

Generate a startup script with Aikar's flag with startmc.sh here

Ensure that Xms=Xmx. This allows the JVM to take full control of the allocate RAM and is beneficial to performance.

(I will personally fight any host that suggests otherwise. Setting xmx=xms hinders a host's ability to host more servers into a physical machine and cuts into their profit margins. See hosting suggestions below for more info)

What about other GC such as ZGC or Shenaaodoah?

In regards to ZGC, Krusic has a fantastic blogpost if you'd like to dig deeper.

ZGC, Shenandoah and other modern collectors alike are designed for highly threaded environments, which does not apply to Minecraft Applications, hence why they are generally not recommended. Anyone who claim otherwise should be taken with a huge grain of salt, especially if they do not have any data backing up their claims.

💡
Server startup time and idle MSPT are not useful metrics nor are they an indication of better alternative GC performance. There are tons of questionable claims using them as benchmark data points. This is a sign of incompetence and you should not trust their claims.

Backup and Recovery Best Practice🔗

Shit happens and you wouldnt wanna be stuck in the bathroom with a shitty pants, would you? It's important to have spare pair of undies with you! Make a backup today!

Having a backup and recovery plan in place is essential.

Unexpected crashes or improper shutdowns could cause world corruption or data lose to your server. Keeping multiple copies of backups both on-site and off-site is not only crucial, but an important aspect of running a long-lasting server.

The simplest way is to stop the server manually and create a tarball or zips...

tar -czvf backup_date.tar.gz /[path]/ on Linux.
Right Click Minecraft root folder>Send to>Compressed (zipped) folder on Windows.

There are advanced options such as Borg or rsnapshot if you would like to look into automate the backup task.


Quality of Life Plugins & Tools🔗

Here is my personally curated list of plugins where it would be beneficial for every server to have them.

Disclaimer: I am not sponsored by any individual or groups on the making of this list. This list is purely made with love with my personal experience with them.

LuckPerms
A must-have modern permission plugin that provides you with finer permission control without the risk of giving out the OP permission to your staff team.

EssentialsX
EssentialsX is a family of plugins that provide you with several essential features for your server.

EssentialsX-Discord
A lightweight bridge plugin that brings your MC drama from in-game chat to Discord.

Chunky
World pre-generation plugin.

ChunkyBorder
Worldborder plugin with more feature than vanilla worldborder.

PureTickets
A support ticket system to manage your server drama.

EntityDetection
A simple plugin to display entity locations on the server.
A helpful tool to locate problematic entities and illegal villager orgy parties.

Vanish No Packet
Allows you to vanish with style. It's free and open source.

OpenInv
Allows you to open any player inventory, even if they are not currently online.

MiniMOTD
Customize MOTD and server icons.

TabTPS
The original™ TPS bar integration with pretty RGB color.

AnnouncerPlus
Powerful and fully customizable announcer plugin.

WanderingTrades
Adds the ability to customize the wandering trader loot table.

AntiRaidFarm
A simple plugin to disable RaidFarm.

Maintenance
Enable/disable maintenance mode.

VanillaTweaks
Vanillatweaks datapack but as a plugin.

TreeAssist
The only tree faller / fast leaf decay plugin that doesnt take the server down with it.

WorldEdit
The classic world edit plugin.

WorldGuard
The classic Anti-grief plugin.

FarmControl
The solution to overpopulated farms.

MobLimit
Similar to Farm Control mentioned above. (You will only need one or the other)

Insights
An anti-redstone griefing and block limitor plugin.
An useful tool to locate potential lag machine.

spark
A profiler plugin that provides you with more insights on server performance.
This is a perfect aid in addition to timings to troubleshoot possible issues within your server.

BlueMap
A map plugin that provides a 3D render of your server.
(Warning; this plugin is very resource intensive)
For a real server demo IOE showcase

squaremap
A lightweight Vanilla-themed 2D map with fast render speed that is also highly optimized.

ViaVersion (also known as ViaVersion)
A useful plugin during each major Minecraft updates.
You can config this plugin to allow players from newer version of Minecraft to join the server while you wait for the stable Paper version to be published.

UnifiedMetrics
A feature-rich metrics collection plugin for Minecraft server made by a weeb.

DecentHolograms
A hologram plugin that does not put a hole in server performance.

AntiVillagerLag
A simple plugin to reduce villager lag without breaking restocking mechanic.

AntiBookBan
A simple plugin to disallow non-ASCII characters in books, thus preventing bookban exploits.

CoreProtect
A grief management plugin.

LWCX
Light weight single block protection plugin.

OreAnnouncer
An alternative to anti-xray, this plugin notifies you on blocks mined.

Vault
Abstraction Library.

Random Teleport
A random teleport plugin.

ChestShop
Simple chest shop plugin.

💡
A good plugin can bring in additional functionalities and improvements to your server; on the flip side, a poorly made plugin could single-handedly tank the performance or even cause permanent damage to your server. Please do your due diligence by looking into the history of the developer/organization behind the plugin prior to installation and properly test them before pushing them live to production.

Useful External Tools

MCA Selector
A tool to view, trim, and alter your chunk data offline.
Please ensure that you have a proper backup before you perform any action with this tool.

Amulet Editor
A modern Minecraft world editor that allows external edits of your world.

Web NBT Editor
A simple tool to view and edit NBT files.

World Size Calculator
A tool to estimate the file size of a given world.

Chunker Bedrock/JAVA world converter
An experimental tool to convert your world between the two version.

Moreover, there are client side mods that aim to improve the Vanilla gameplay experience and are highly recommended for players who may want to have the best gameplay experience possible. However, it does not align with the topic of this blog post, instead, you can check it out here Minecraft Client Optimization mods


Things to Avoid🔗

Avoid MobStacker plugin
Mobstacking is an inherently flawed idea. Spawning mob consumes server resources, with mobstacking enabled, the server would never reach mob cap and could potentially be stuck in the endless loop of spawning hell.
Combined with seemingly zero decently coded stacker plugins, stacking mob should be avoided at all cost.

Avoid lag removing or performance enhancing plugins
Fix the root cause of the performance problem instead of masking it.
Plugins such as ClearLagg or EntityTrackerFixer (ETF) introduce gameplay inconsistencies, create unnecessary work for already existing tasks (such as clearing ground items, and untracking entities), and would sometimes cause permanent damages to your world (ETF would remove AI from entities causing them to have permanent brain damage even after the plugin is removed).

Do NOT allow your players to relocate spawners
Being able to silktouch spawner is often requested by players; however, it is not a great idea considering spawners are basically a built-in lag machine when enough of them are gathered together. For the sake of server performance, do not allow your player to relocate spawners.

Do NOT use datapacks with repeat/recurrent functions
Datapack with repeating functions will impose a performance hit and should be avoided at all cost.
Find plugin replacement of the datapack features you wish to have.

Do NOT source your plugin from BlackSpigot, BuiltByBit (MC-Market), a random individual, or any other unknown sources
You wouldnt get your breakfast sausage from a random stranger on the backside of your local gas station, would you? Same thing applies to sourcing your plugins.

Obtain your plugins from reputable sites and practice your due diligence to audit the code base or the developer themselves.
To take it lightly, your server may take a huge performance hit due to a poorly coded plugin, or worse be invaded by griefers via built-in backdoors, even worse, your server itself may be taken over for other malicious activities.

Do NOT auto-update your Paper.jar
The Paper development cycle does not include a proper release/beta versioning scheme so occasionally a bad build may slip through the cracks on to release.

Automation provides convenience but you should not blindly download the latest Paper jar for use in any production environment.

The Famous Minecraft List of Shame by the popular Twitch streamer Kneny
Avoid everything in this list whenever applicable.


Hosting Options🔗

Disclaimer: I am not sponsored by any individual or groups on the making of this list. This list is purely made with love with my personal experience and community input

There are several available options when it comes to hosting a Minecraft servers. Please read and understand the limitations of each. Below is a list from the most powerful option to potatos.

Dedicated Server (Baremetal)

A whole dedicated machine all to yourself.

This is the most expensive option and also requires you to have basic Linux admin skills

OVH or Hetzner are often recommended.

Ideal for communities with a large number (50+) of concurrent players.

Premium Shared Host

A managed service where you are sharing resources with other Minecraft servers

You are welcome to ask in the Paper Discord for recommendation from the community.

Ideal for medium size communities (5~50 players) on select plans.

Try your best to find hosts that allow you to utilize Aikar's Flag by default and allow your JVM instance to claim the RAM in its entirety. It is by no mean a guarantee for performance, but it serves as an indication that they are probably not overselling their machine.

Oracle Cloud Free Tier

Free and very fast cloud instance with a catch.

ARM based A1 instance may not be available for your region due to the recent popularity spike.
However, it never hurts to try your luck.

Read this blog post carefully for more info

Ideal for small community or proof-of-concept testing servers.

If you do opt for this hosting option, please note that your instance will/may be disabled after 60 days from the beginning of the trial period. MAKE SURE YOU HAVE A BOOT VOLUME BACKUP READY and recreate the instance if it does get deleted.

VPS

Virtual Private Server

It may sound like a good deal on paper but VPS are often not as great of value as the above mentioned Shared Host, as the hardware tends to be dated and the whole VPS industry is more geared toward webhosting and other less CPU intensive workloads.

Ideal for... ugh your mileage varies. If you still prefer this option, find a host that specialized in high-end game server hosting instead of the general purpose one.

Budget Host

A cheaper alternative of shared host with much lower performance.

Similar to shared hosts above, but is a lot cheaper. They turn a profit by staffing as many servers as physically possible into one physical machine (this is called overselling)

Those types of hosts often spend the most on advertising and have extensive teams on social media to promote their service. Huge discounts or coupons are often offered to drive sales.

They often prey on uneducated users and here are a few easy ways to identify them in the wild.

  • If the CPU model is not clearly labeled on the plan.
  • If they are advertising plans based on maximum player count.
  • If they are upselling RAM as a performance booster.
  • If they offer unlimited storage.
  • If they have a discount deal all year round.
  • If Xms=128M is present in your JVM flags
    (You can locate this info on the timings report)

Ideal for 5~20 players.

Due to common overselling practice, the server may perform poorly during the peak hours where the machine may struggle to handle the workload.

Your server may also suffer sudden performance drop due to no fault of your own but simply being located in an overcrowded environment where another Minecraft instance may be overloading the machine.

Please do your due diligence to avoid "Summer Host"

The term "Summer Host" comes from the fresh/new hosting companies that appear during the summer school break where the demand for Minecraft servers peaks. Majority of the summer host will disappear or become inactive once the demand declines, only to be resurrected next year with a brand new name.

Free Host

If you are not paying for the product you are the product

Through clever marketing, some hosting companies are able to offer free servers with very limited resources to everyone.

They profit from the massive amount of user base they hold and outsource the risk of starting a server to those who dare to pay them for premium plans. Some have advertisements on their panels or inside your servers.

Free hosts often impose heavy restrictions to their service such as JVM flags, yml configs, plugins, and offer no ability to transfer the file out. You are buying into their ecosystem and you are the product they are selling.

Ideal for people with no money.

Self hosted

Hosting at home

If you could ignore the potential security implications of exposing your home IP to the public and the risk of being DDOS'd by your friends, this is a workable option. However, it is strongly discouraged.

If you still want to give it a try, check out Syscraft's helpful Guide by Larry on how to start.

Ideal for a private group of close friends. (heavily dependent on your hardware)

Raspberry pi

A perfect solution for those who prefer pain and suffering. In truth, A Raspberry Pi is just not powerful enough to run on modern Minecraft version without making tons of gameplay compromises.

Ideal for a small community with less than 5 concurrent players online.


Domain and Service Record (SRV)🔗

If you own a domain, you can set up an A record and a service record (SRV) to have a prettier and easier to remember server address.

Instead of having 192.168.1.1:25555 displayed as your server address, you can get minecraft.yourdomain.com.

To do this, you will need an A record and a SRV record.

In this scenario www.yourdomain.com is your domain and you want to create mc.yourdomain.com as your server address instead of 192.168.1.1:25555.

Step 1: Create an A record that points the hostname mc.yourdomain.com to your server's public IP address.

Step 2: Create a SRV record with the hostname _minecraft._tcp.mc.yourdomain.com

There will be options to set up priority, weight, port, and target.
You will set them as 0, 0, 25555, mc.yourdomain.com accordingly.

If you are running Minecraft on the default port (25565), only an A record is needed.
(The above example is provided for server that is on a shared host or is running on non-default ports)

Some ISP DNS do not honor SRV record, so your mileage may vary if you choose to run on non-standard 25565 port.

💡
Please note that DNS changes takes time to populate and the resulting link may not work right away. Be patient.

Closing Notes

Wow you made it this far, I hope you did not skip anything. The original idea of this guide was to make it as simple as possible for beginners who just step their foot onto the Minecraft server hosting. In the writing process, I tried to simplify things, please do let me know if something can be explained better or improved. I would love to keep this guide as accurate and as up-to-date as possible, so if you do find any mistake, please contact me via Discord @EterNity, or by email [email protected]


Special Thanks

kennytv to sit through entire guide for grammar errors.
Puremin0rez for structure and grammar corrections.
Aurora for early re-visioning and grammar corrections.
NoahvdAa for materials suggestions.


GitHub: https://github.com/PaperMC
Discord: https://discord.gg/PaperMC
Forum: https://forums.papermc.io
Wiki: https://docs.papermc.io
JavaDocs: https://papermc.io/javadocs
Donate: https://papermc.io/sponsors
Island of EterNity: https://eternity.community

EterNity

Published 2 months ago