First: decide which kind of lag you have
"Lag" describes at least three unrelated problems, and every one of them has a different fix. Establishing which one you are looking at takes thirty seconds and saves entire evenings.
| Low TPS | The server cannot finish its work in 50 ms per tick. Mobs stutter, blocks break slowly, time itself feels slow. This is what spark diagnoses |
| High ping, full TPS | The server is healthy; the path between player and server is not. Blocks break instantly for the server but the client sees delay |
| Periodic freezes, healthy average TPS | Usually garbage collection or chunk saving. The average hides a spike that players feel clearly |
| Cannot connect at all | Not a performance problem. Connection floods, bot attacks, or a routing failure |
Run `/spark tps` and `/spark health` before anything else. If TPS is 19.9+ while players complain, stop looking at the server — nothing in a profile will explain a network problem.
Running a profile
- Install spark as a plugin (or mod) and restart. It works on Paper, Purpur, Folia and proxies alike.
- Wait until the lag is actually happening. A profile of a healthy server tells you what a healthy server does — which is not useful.
- Start the profiler with `/spark profiler start`, and let it run for a couple of minutes through the problem.
- Stop it with `/spark profiler stop`. spark returns a link to a browsable report.
- Open the report and read from the top: the entries consuming the largest share of tick time are your candidates.
For memory questions rather than tick questions, `/spark heapsummary` shows what is actually occupying the heap — the fastest way to confirm or dismiss the "we need more RAM" theory covered in how much RAM a server needs.
Reading the report without a computer-science degree
The report is a call tree: each entry is a method, nested under whatever called it, with the percentage of sampled tick time it accounted for. You do not need to understand the code — you need to follow the percentages down until the name stops being generic.
The top entries will be server internals like the tick loop, which is expected and tells you nothing. Keep descending. The moment you see a plugin's package name, a world name, or something like entity or hopper handling taking a large share, you have found your answer. A plugin sitting at 40% of tick time is not a subtle finding, and that is the normal outcome — real lag causes are usually embarrassingly obvious once measured.
The usual suspects
- One badly-behaved plugin. By far the most common. Often something doing database or file work on the main thread rather than off it.
- Entity accumulation. A mob farm, an item-drop pile, or thousands of armour stands. Count entities before blaming anything else.
- Hoppers and redstone. Large hopper arrays and clocks are genuinely expensive, and their cost is concentrated in one chunk that one player built.
- Chunk generation. Players exploring new terrain generate world on demand. Bursty lag that follows a player around the map is this, and pre-generating the world fixes it.
- Garbage collection. Smooth server, periodic freezes, GC time visible in `/spark health` — that is a heap-shape problem, addressed in the JVM flags guide.
When the profile is clean
A healthy tick loop while players suffer is a real and common result, and it means the problem is not on the server at all. At that point look at the path: is it everyone or only players in one region? Only one region points at routing or peering rather than anything you can fix in a config file — and where your traffic is filtered geographically is what determines that.
The other clean-profile scenario is more urgent. If connections are failing, logins are flooding, or the server is fine right up until it abruptly is not, you are looking at an attack rather than a performance problem. A bot join-flood does not show up as a hot method — it shows up as thousands of connection attempts, and by the time the server is struggling, the damage is already done at the network layer. That is diagnosed here and solved upstream of the server entirely, because no amount of profiling makes a saturated uplink go away.
Common questions
How do I find out what is lagging my Minecraft server?+
Install the spark plugin and run a profile while the lag is happening: start the profiler, let the server run through a lag episode for a minute or two, then stop it and open the report link. The report shows which methods consumed tick time and attributes them to plugins, so you get a name rather than a hunch. Check /spark health first for a quick view of TPS and memory.
What is a good TPS for a Minecraft server?+
20 TPS is the maximum and the target — that is one tick every 50 milliseconds. Anything at 19.9 or above is effectively perfect. Below about 18 players start to notice mobs and blocks behaving sluggishly, and by 15 the game feels visibly wrong. TPS cannot exceed 20, so a server sitting at 20.0 has headroom you cannot see from that number alone.
Why does my server say 20 TPS when players complain about lag?+
Because they are describing a different problem. Full TPS with unhappy players almost always means network latency or packet loss between the player and the server, not server-side tick lag. Ping is what they are feeling. Check whether it affects everyone or only players in one region — the latter points at routing rather than anything running on your machine.
Does spark itself cause lag?+
Its overhead is low by design — it works by sampling rather than by instrumenting every call, which is exactly why it is safe to run on a live server under load. That matters, because a profiler you can only run on a test server is useless for a problem that only appears with 80 real players online.
How do I tell if lag is caused by a DDoS attack?+
Attack-driven lag has a distinct shape: server TPS often stays healthy while players cannot connect or are disconnected, and a bot join-flood produces a flood of login attempts rather than a hot method in a profile. If spark shows a fine tick loop while connections are failing, your problem is on the network path, not in the game loop.
Profile clean but the server still goes down? That is a network problem, not a tick problem. Start free with Arvoris — L4/L7 mitigation and antibot on every plan.