Rule table
Every finding this tool can show, how it is detected, and where each tip comes from. Tips with no source are common sense, and are marked so.
How much to trust a finding
- Measured: read directly from the profile, such as time inside a plugin's classes.
- Likely: a fair reading of two numbers side by side, not proof.
- A guess: worth checking, but the data cannot confirm it.
A profile shows where the server spent time. It cannot show why a number is high or prove that removing something helps. Sampling also misses very short work, so small percentages are rough.
Mobs pushing into each other
Each mob checks every nearby mob for collisions, so packed mobs cost far more than spread-out ones. Pens, farms and breeders are the usual places.
Detected by: Tick time under entity ticking that sits in the push, move and collision code.
- Go to the crowded spots and thin the mobs out or give them more room. The busiest chunks are listed further down. General advice, no source.
- Lower the max_entity_cramming game rule (default 24). Mobs packed past the limit take cramming damage, so it will also kill crowded farms. Source: Minecraft Wiki: Game rule.
- Lower collisions.max-entity-collisions in the Paper world config (default 8). The guide suggests 2. 0 stops entities pushing, including players. (paper) Source: Paper docs: world configuration, YouHaveTrouble's Minecraft server optimization guide.
Mob brains and pathfinding
Mobs are deciding what to do and working out routes. This grows with the number of mobs that are active near players.
Detected by: Tick time under entity ticking in the goal selector, brain, sensor and path-finding code.
- Lower simulation-distance in server.properties. Mobs outside it are not updated. The guide starts at 4; the game default is 10. Source: Minecraft Wiki: server.properties, YouHaveTrouble's Minecraft server optimization guide.
- Lower spawn-limits in bukkit.yml and mob-spawn-range in spigot.yml so fewer mobs exist. Mob farms will produce less. (spigot) Source: YouHaveTrouble's Minecraft server optimization guide.
- Tune entity-activation-range in spigot.yml. Mobs outside the range tick less often. Very low values can break iron farms. (spigot) Source: Paper docs: spigot.yml reference, YouHaveTrouble's Minecraft server optimization guide.
- If most of them come from spawners, nerf-spawner-mobs in spigot.yml removes their AI. Those mobs will do nothing. (spigot) Source: Paper docs: spigot.yml reference, YouHaveTrouble's Minecraft server optimization guide.
Villagers
Villagers run the heaviest AI in the game: they look for beds, job sites and each other. Trading halls and breeders add up fast.
Detected by: Tick time inside villager classes and the point-of-interest code they use.
- Count the villagers listed here and cut any you do not need. General advice, no source.
- Set tick-inactive-villagers to false in spigot.yml so villagers outside activation range stop ticking. It can affect iron farms and restocking. (spigot) Source: YouHaveTrouble's Minecraft server optimization guide, Paper docs: spigot.yml reference.
- Paper's tick_rates section can slow individual villager behaviours and sensors. Test trading and breeding afterwards. (paper) Source: Paper docs: world configuration.
- Purpur has villager.brain-ticks and villager.lobotomize. The guide advises the second only if villagers really are the lag. (paper) Source: YouHaveTrouble's Minecraft server optimization guide.
Dropped items
Every item on the ground is an entity that ticks, falls and tries to merge. Farms without collection and mob grinders leave a lot of them.
Detected by: Tick time inside the item entity class, plus the item count in the profile when spark includes it.
- Find what is dropping them. The chunk list here is the place to start. General advice, no source.
- Raise merge-radius.item in spigot.yml (default 0.5) so stacks combine. Too high and items seem to vanish. (spigot) Source: Paper docs: spigot.yml reference, YouHaveTrouble's Minecraft server optimization guide.
- Use entities.spawning.alt-item-despawn-rate in the Paper world config to clear junk such as cobblestone sooner. (paper) Source: Paper docs: world configuration, YouHaveTrouble's Minecraft server optimization guide.
Entities in general
Entities are ticking, but no single part of that stands out. The total number is the thing to look at.
Detected by: Tick time under entity ticking that is not collision, AI, villagers or items.
- Compare the entity counts here with what you expect, and start with the biggest type. General advice, no source.
- Lower simulation-distance in server.properties. The guide starts at 4; the game default is 10. Source: Minecraft Wiki: server.properties, YouHaveTrouble's Minecraft server optimization guide.
Hoppers
Hoppers wake up constantly to look for items. The cost is per hopper, so big storage and sorting systems add up.
Detected by: Tick time inside the hopper block entity class.
- Put a composter, chest or other full block on top of hopper lines. The wiki calls the composter the best block for performance on Java Edition. Source: Minecraft Wiki: Hopper.
- Raise ticks-per.hopper-transfer in spigot.yml (default 8). Too high breaks hopper clocks. (spigot) Source: Paper docs: spigot.yml reference, YouHaveTrouble's Minecraft server optimization guide.
- Raise ticks-per.hopper-check in spigot.yml (default 1). It can break hopper clocks and item sorters. (spigot) Source: Paper docs: spigot.yml reference, YouHaveTrouble's Minecraft server optimization guide.
- Set hopper.disable-move-event to true in the Paper world config. It breaks plugins that rely on that event, such as protection plugins. (paper) Source: Paper docs: world configuration, YouHaveTrouble's Minecraft server optimization guide.
Blocks with a tick of their own
Furnaces, spawners, beacons and modded machines all run every tick. The list here shows which ones the profile saw.
Detected by: Tick time under block entity ticking, outside hoppers.
- Start with the class named here and find how many of those blocks the base or farm uses. General advice, no source.
- If it is a spawner, tick-rates.mob-spawner in the Paper world config slows every spawner (default 1). (paper) Source: Paper docs: world configuration.
Redstone
Redstone that never stops, such as clocks and observer chains, causes block updates every tick for as long as its chunks stay loaded.
Detected by: Tick time in redstone wire, observer, repeater, piston and neighbour-update code.
- Look for a running clock or a farm left on in force-loaded or spawn chunks, and turn it off to compare. General advice, no source.
- misc.redstone-implementation in the Paper world config can be set to ALTERNATE_CURRENT or EIGENCRAFT. Both change how dust behaves, so test contraptions first. (paper) Source: Paper docs: world configuration.
Scheduled block and fluid updates
Blocks and fluids that asked to be updated later: flowing water and lava, falling blocks, crops and farm machinery.
Detected by: Tick time in the scheduled tick lists, outside the redstone classes.
- Think about what changed lately: a big water or lava flow, or a large block farm. The profile cannot tell you where it is. General advice, no source.
Ticking loaded chunks
The server walks every loaded chunk near players for random ticks such as crop growth, ice and fire. More chunks in range means more of this.
Detected by: Tick time in the chunk tick loop, outside mob spawning.
- Lower simulation-distance in server.properties. The guide starts at 4; the game default is 10. Source: Minecraft Wiki: server.properties, YouHaveTrouble's Minecraft server optimization guide.
- Check for a raised random_tick_speed game rule (default 3). Source: Minecraft Wiki: Game rule.
Mob spawning
The server is looking for places to spawn mobs. It runs near every player, and costs more with more players and open space.
Detected by: Tick time in the natural spawner class.
- Lower spawn-limits in bukkit.yml and mob-spawn-range in spigot.yml. (spigot) Source: YouHaveTrouble's Minecraft server optimization guide.
- Lower simulation-distance in server.properties. Source: Minecraft Wiki: server.properties, YouHaveTrouble's Minecraft server optimization guide.
New chunks being generated
Someone or something is exploring land that does not exist yet. Generating terrain is one of the most expensive things a server does.
Detected by: Tick time in terrain generation code, or the server thread waiting on it.
- Pre-generate the world with Chunky while nobody is on, then set a world border so players cannot create new chunks. Source: Chunky on Modrinth, YouHaveTrouble's Minecraft server optimization guide.
- Check for elytra flight, boats or teleport commands taking players far out at the time of the lag. General advice, no source.
Waiting for a chunk
Something on the server thread asked for a chunk that was not ready, and the whole server stopped until it was. The chunk had to be read from disk or generated. Usually that is a plugin, a command or a teleport.
Detected by: Time in the chunk cache's blocking load path, on the server thread.
- If a plugin is named here, it is loading chunks on the main thread. Check its settings or tell the author. General advice, no source.
- Look for commands that touch far-away land, such as forceload or large fills. General advice, no source.
- Pre-generate with Chunky so new land does not have to be generated at that moment. Source: Chunky on Modrinth, YouHaveTrouble's Minecraft server optimization guide.
Chunks loading and unloading
The server is moving chunks in and out of memory. Players moving fast, teleports and high view distance all increase this.
Detected by: Tick time in chunk holder, ticket and chunk scheduling code.
- Lower view-distance in server.properties. The guide starts at 7; the default is 10. Low values show fog on clients. Source: Minecraft Wiki: server.properties, YouHaveTrouble's Minecraft server optimization guide.
- Pre-generate with Chunky, so that loading is not also generating. Source: Chunky on Modrinth.
Saving the world
Autosave is writing chunks to disk on the server thread. Slow disks make this show up as a regular spike.
Detected by: Tick time in save, region file and NBT write code.
- chunks.max-auto-save-chunks-per-tick in the Paper world config (default 24) spreads saving across ticks. A lower value means smaller spikes and longer saves. (paper) Source: Paper docs: world configuration.
- On Fabric or vanilla, set sync-chunk-writes=false in server.properties. Paper already forces this off. (fabric, vanilla) Source: YouHaveTrouble's Minecraft server optimization guide.
- Ask your host what kind of disk the server is on. General advice, no source.
Light updates
The server is recalculating light. Big builds, world edits and new chunks trigger it.
Detected by: Tick time in the light engine classes on the server thread.
- Check whether a large WorldEdit job or similar was running during the capture. General advice, no source.
Telling players about entities
The server sends each player what nearby entities are doing. It grows with players multiplied by entities in range.
Detected by: Tick time in the entity tracker classes.
- Lower entity-tracking-range in spigot.yml (defaults: players 128, animals and monsters 96). Too low and mobs pop in near players. (spigot) Source: Paper docs: spigot.yml reference, YouHaveTrouble's Minecraft server optimization guide.
- Cut the entity counts listed here. Fewer entities means less to send. General advice, no source.
Player connections
Handling packets from players and the work they trigger, such as block placing and inventory actions.
Detected by: Tick time in the connection and packet handling classes.
- Compare with the player count at the time. If this is high with few players, one player may be sending something unusual: a large book, a macro or a cheat client. General advice, no source.
Player inventories and advancements
Each online player's own tick: syncing inventories, checking advancements and handling actions. Mods that add advancements or big inventories increase it.
Detected by: Tick time in the player class, container sync and advancement trigger classes.
- Compare with the player count. If it is high with few players, look at what those players are carrying or using. General advice, no source.
Commands and datapack functions
Command blocks or datapack functions are running every tick. Selectors like @e over a large world are the usual expense.
Detected by: Tick time in the function manager, command dispatcher and command block classes.
- List your datapacks and repeating command blocks, disable them one at a time, and compare. General advice, no source.
- Narrow the selectors in any tick function. A selector with a type or a distance checks fewer entities than a bare @e. General advice, no source.
A plugin or mod
This code is not part of Minecraft. The time below was measured inside it, including whatever it called.
Detected by: spark labels each class with the jar it came from. Time inside those classes counts for that plugin or mod.
- Update it, then read its config for anything that runs on a timer or per player. General advice, no source.
- Remove it on a test copy and take another profile. That is the only proof it is the cause. General advice, no source.
- Send the author this profile link. They can read the exact methods. General advice, no source.
The server thread is waiting, not working
Code on the server thread stopped and waited for something: a sleep, a lock, a disk or a network call. The whole server stands still until it returns. Spare CPU will not help.
Detected by: The deepest frame is a sleep, lock, socket or file call, and it sits inside a tick.
- If a plugin is named, look for database, web or file features in it and move or disable them. General advice, no source.
- Report it to the author. Database and web calls belong on another thread. General advice, no source.
Java garbage collection pauses
Java stops to clean up memory. Long or frequent pauses freeze the server, and profile stacks will not show them.
Detected by: Average pause length and frequency from the collector statistics in the profile.
- Use Aikar's flags, with Xms equal to Xmx. They are tuned for Minecraft's high allocation rate. Source: Paper docs: Aikar's flags.
- Give the server at least 6 to 10 GB if the host has it, and leave 1 to 1.5 GB of the plan for overhead. Source: Paper docs: Aikar's flags.
Java memory nearly full
Heap use is close to the limit at the time of the capture. A full heap makes collections more frequent. One reading can be misleading, because heap use normally climbs until a collection runs.
Detected by: Used and maximum heap in the profile, along with the old generation collector count.
- Watch /spark health for a few minutes. Memory that never drops after a collection is the warning sign. General advice, no source.
- Give the server more memory, up to 6 to 10 GB. More than that has diminishing returns. Source: Paper docs: Aikar's flags.
Java start and maximum memory differ
The startup flags set different Xms and Xmx values. The Paper docs recommend making them equal.
Detected by: Read from the Java startup flags in the profile.
- Set Xms to the same value as Xmx. Source: Paper docs: Aikar's flags.
Small Java heap
The maximum heap is below the 6 GB the Paper docs suggest as a starting point. Small heaps collect more often.
Detected by: Maximum heap in the profile.
- Raise it if the host plan allows, leaving 1 to 1.5 GB for overhead. Source: Paper docs: Aikar's flags.
Something else is using the CPU
The whole machine was busy, but this server used only part of that. Other software or, on shared hosting, other customers may be taking the CPU. spark notes that CPU numbers can be wrong inside containers, so treat this as a lead.
Detected by: System CPU compared with process CPU, in the same capture.
- On your own machine, check what else is running. General advice, no source.
- On a host, send them these numbers and ask whether the node is oversold, or move to a plan with dedicated cores. General advice, no source.
No single cause stands out
The tick is slow, but the time is spread across normal work. Either there is simply a lot going on, or the CPU is slow per core or shared with others. The game tick runs on one thread, so per-core speed matters more than core count.
Detected by: No cause over a third of busy time while ticks are slow. This is a guess from what is missing, not a measurement.
- Look up this CPU's single-thread score and compare it with a recent desktop chip. General advice, no source.
- Take a second profile at a quiet time. If MSPT stays high with few players, the machine is the likely limit. General advice, no source.
- Try the same world on a different host or plan, if you can, before changing anything else. General advice, no source.
This looks like a virtual server
The CPU name is the generic kind a virtual machine reports. Virtual cores are often shared with other customers, and spark cannot see that. This is a lead, not a finding.
Detected by: CPU name in the profile matches names virtual machines report, such as QEMU, KVM or a bare 'AMD EPYC Processor'.
- Ask your host whether the cores are dedicated, and compare a profile at a quiet time of day. General advice, no source.
The machine is using swap
The system has moved memory to disk, which is much slower than RAM. If Java's memory ends up there, the server will stall. It may also belong to other programs, as the profile cannot tell which.
Detected by: Swap and physical memory use in the profile.
- Do not give Java all of the machine's RAM. Leave 1 to 1.5 GB for the system and everything else. Source: Paper docs: Aikar's flags.
The disk is nearly full
Over 95% of the disk is in use. Saving can fail when it runs out.
Detected by: Disk use in the profile.
- Clear old backups and logs. General advice, no source.
Spigot or CraftBukkit instead of Paper
The guide calls Spigot extremely outdated for performance, compared with Paper.
Detected by: Server brand in the profile.
- Move to Paper. Take a backup first. Source: YouHaveTrouble's Minecraft server optimization guide.
No Lithium on this Fabric server
Lithium is a general-purpose optimization mod that aims to keep vanilla behaviour. It is absent from this server's mod list.
Detected by: Mod list in the profile.
- Try Lithium on a copy first. Source: Lithium on Modrinth.
A ground item clearing plugin
The guide says these are not needed and often cost more than they save, since merge-radius and alt-item-despawn-rate do the same job.
Detected by: Plugin name in the profile's list: ClearLag, ClearLagg, NoLag, LaggRemover.
- Try the server settings instead, and compare with a profile. Source: YouHaveTrouble's Minecraft server optimization guide.
A mob stacker plugin
The guide says stackers are hard to justify, except on servers with many spawners. They change how farms and drops work.
Detected by: Plugin name in the profile's list: StackMob, WildStacker, RoseStacker, UltimateStacker.
- Compare a profile with it on and off before relying on it. Source: YouHaveTrouble's Minecraft server optimization guide.
High view or simulation distance
Simulation distance sets how far from players things keep running. It multiplies the cost of chunks and entities, so it is worth trying when they are the top causes.
Detected by: Values read from server.properties in the profile, when entities or chunk work are the main cost.
- Try simulation-distance 4 to 6 and view-distance 7. The effective distance is whichever is higher, so keep simulation low. Source: YouHaveTrouble's Minecraft server optimization guide.
- The game default for both is 10. Source: Minecraft Wiki: server.properties.
Short spikes, not steady lag
Most ticks are fast, with a few very slow ones. A normal profile averages those away, so the causes listed here may not be the spike.
Detected by: Median tick compared with the slowest ticks in the capture.
- Run /spark tickmonitor --threshold-tick 50 to see when spikes happen. Source: spark docs: Finding lag spikes.
- Then run /spark profiler start --only-ticks-over 100 so the profile has only the slow ticks. Pick a value below the spike length. Source: spark docs: Finding lag spikes, spark docs: Command usage.