How Minecraft works (What causes lag?)
The key to understanding what is causing lag is to understand how Minecraft works. Minecraft server software all operate in a similar matter with one key problem: there is no multi-threading or timing limits for the main game loop. When the server goes to tic, it runs through every TileEntity update, entity update, block update, events and other processes until it's done. This all occurs on one thread, and the next loop cannot start until the current one finishes. The world will not update, players will not appear to move and entities will be frozen in place. Ideally each tic should take no more than 50ms to maintain 20 Tics Per Second (TPS). This can go as low as 55.55ms for 18 TPS with minimal issues. Any lower than this and you will begin to see lag.
Typical causes of lag
There are many things that can cause lag but a few of them will be the most likely culprit for most servers.
File usage: Any plugin that is constantly reading from player files, especially on events such as movement, damage or interact. A few examples would be some PVP flags or Glow plugins which will continuously read from player files.
Flat files as a database: When you have plugins that use large files to keep track of lots of data iterating through that file or in memory depending on how it is stored will take a long time. Many plugins do this and do not take precautions against how, when the databases become bloated, the processing time will affect the servers tic. You will see this a lot when loading up large MagicSpells configs, or using permissions systems that use YAML instead of a proper database such as PEX and GroupManager.
Too many operations: When a plugin spawns too many entities, or attempts to perform complex tasks on events such as movement, you will begin to see lag. Even if each run takes less than 1ms, when you are processing an event 20k times a second it becomes exponential. Plugins that can cause this are world editing plugins such as VoxelSniper and WorldEdit; or protection plugins such as Anti Cheats and World Protections.
Too many chunks loaded: One chunk is
16*16*256
. This might not sound like a lot but when multiplied out that means there are 65,536 blocks per chunk. Each player can have more than 200 chunks loaded around them, depending on your configuration. Thats upwards of 13,107,200 blocks. This takes up a lot of memory. Also, if even 1% of those are TileEntities that's 131,072 TileEntities loaded that need to update every tic. Mods are notorious for having slow processing times on TileEntities.Cascading WorldGen: This is when a plugin or mod generates structures outside of the chunk it is given. This causes the next chunk to load, generate and then trigger this all over again if it also begins to have structures overflow into the next chunk. This is bad design on behalf of the creators and any plugin or mod doing this should be removed immediately.
Tile entities: See LagGoggles section below.
Finding the cause of lag is generally a simple procedure nowadays as most Minecraft server software is built with profiling tools included.
Timings reports for Spigot/PaperSpigot
To get a detailed timings report you can use the follow command.
/timings on
You will want to wait a few minutes and let it lag while your timings are running. After a while, generate the report.
/timings paste
This will give you a link to a website with a nice breakdown of the report with easy options to sift through all the data you are getting. You can learn more on how to read these at Spigot's timing wiki.
You will want to turn timings off afterwards, as you do not want junk data clogging up your next reading, and timings adds additional time to the tic.
/timings off
Timings Reports for Sponge
To get a detailed timings report you can use the follow command.
/sponge timings on
You will want to wait a few minutes and let it lag while your timings are running. After a while, generate the report.
/sponge timings report
This will give you a link to a website with a nice breakdown of the report with easy options to sift through all the data you are getting. Since Sponge's timings system is based off of Spigot's you can learn more on how to read these at Spigot's timing wiki.
You will want to turn timings off afterwards, as you do not want junk data clogging up your next reading, and timings adds additional time to the tic.
/sponge timings off
You can also reset the timings.
/sponge timings reset
Steps to reduce lag
Use proper arguments for your script file to launch Minecraft. Learn more about the appropriate Java arguments here
Use LuckPerms or a Permissions manager that uses a proper database instead of a flat file
Avoid chunk loaders altogether
Remove anything that causes cascading world generation
Limit Anti Cheat plugins to not be overzealous
Limit the view distance of players in
server.properties
Clear hostile mobs after a set time period
Restart the server daily to clean up leaks from Java
NEVER reload the server, this causes leaks and other issues
Use FastAsync versions of plugins such as WorldEdit and VoxelSniper
Limit the size of your world so new chunks are not constantly being created
Limit the amount of plugins you use. Not all plugins are built well and the more you have the more issues you are going to encounter
LagGoggles
A big portion of lag on modded servers comes from tile entities. These are the entities created for blocks that are used for processing the block's functionality and events. If these take too long or there are too many it can increase the time per tic bringing down the total server TPS. A way to visualize these problems is to use a mod called LagGoggles. You can download this mod from CurseForge.
More Information
See our tuning guide: How to Optimize Your RCS Minecraft Server