Case study · TickWatch

Your server says 20 TPS. It still feels awful.

TPS is the number everyone checks, and it's the number that hides the problem. Here's what I measured, and how I tested a diagnostic that names the cause instead of guessing at it.

27.87
milliseconds of a 50 ms tick budget, burned by one misbehaving plugin — while TPS sat at a perfect 20.00 and every dashboard stayed green.

The thing nobody tells you about TPS

A Minecraft server gets 50 milliseconds to finish each tick. Do it in time, twenty times a second, and TPS reads 20.00. Nobody asks how much of the 50 ms you actually used.

So I built a test rig, broke a server on purpose in the ways servers actually break, and measured both numbers side by side. Here is the whole story in one picture — every bar is the same tick budget:

Idle, nothing wrong · TPS 20.00
0.25 ms
Plugin abusing the scheduler · TPS 20.00
8.23 ms
File I/O on the main thread · TPS 20.00
27.87 ms
0 ms50 ms budget
Measured on the TickWatch test bench — same server, three states. Read the bar lengths, then read the TPS beside each name: it never moves.
Same numbers as a table
Measured on the TickWatch test bench. Same server, three states. The tick budget is 50 ms.
Server stateTick timeTPS
Idle, nothing wrong 0.25 ms 20.00
A plugin abusing the scheduler 8.23 ms 20.00
File I/O running on the main thread 27.87 ms 20.00

More than half the tick budget was gone. Every dashboard said green. The players said it was stuttering. They were both right.

This is why TickWatch triggers on either TPS or tick time, not TPS alone. I didn't decide that from a blog post. I decided it because the bench showed me a server can be halfway to falling over while the headline number never moves.

What the tool actually does

Three parts, and the third is the one that matters.

A collector plugin sits on the server and watches tick health. When things degrade it captures the evidence by itself — profiler data, plugin list, configs — and ships it. You don't have to be awake, and you don't have to catch it happening.

An analysis pipeline takes that bundle apart and produces a diagnosis in plain language. Not a flame graph. Not a stack trace. Which plugin is doing what, and what to change.

A review layer that's allowed to say no. Six checks run against every diagnosis before it's released. If the evidence is thin, the output is withheld — you get told it doesn't know, rather than a confident guess with a plugin's name on it.

That last part cost the most to build and is the only reason I'd put my name on the first two.

How I know it's right

Anyone can produce a tool that emits confident-sounding diagnoses. The question is whether they're correct, and almost nobody publishes an answer to that. Here's mine.

9 of 10
held-out faults diagnosed correctly
0
false accusations on healthy servers
$4.05
total cost of 91 diagnoses

Held-out means the pipeline had never seen those faults while it was being built. Ten unseen breakages, nine named correctly.

The zero is the number I care about more. Run it against a healthy server and it says "no server fault" — it doesn't reach for the nearest plausible plugin to blame. A diagnostic that invents a culprit is worse than no diagnostic, because you'll go rip out something that was fine.

And the costs are measured, not estimated. Building and validating the whole thing — 91 diagnoses across three different model tiers — came to $4.05. On the configuration that actually passed the gate, a single diagnosis costs 5.5¢. I know what this costs to run before I quote anyone a price for it, and I quote from the higher number, because that's the one that's real in production.

Being straight with you about what this is. Those numbers come from a test lab I built and broke on purpose — not from paying customers, because TickWatch doesn't have any yet. I'd rather show you measurements I can prove than testimonials I don't have.

What you actually get

Enough describing it. This is a real diagnosis the pipeline produced, start to finish, with the server and plugin names changed. Nothing has been tidied up for the website.

TickWatch diagnostic report

A plugin is making the server wait on something slow

Server: a Paper 26.2 survival server

What is happening

One of your plugins is doing slow work — a database query, a web request, or reading a file — at the moment the server is trying to run the game. The server can only do one thing at a time, so while it waits, everything stops: mobs, blocks, players. It usually looks fine when nobody is online and gets worse the more people are doing things.

In your case it is WarehouseSync, which accounts for almost all of the time the server spent working (95%) during the period we measured.

What we measured

  • What triggered the capture: ms-per-tick stayed at or above 25.0 for 15s (peak of 27.03, TPS still 18.19)
  • Speed: 19.84 of 20 ticks per second on average, dipping to 18.19 at its worst (20 is full speed).
  • Worth understanding: the tick rate above still looks close to normal, and that is exactly why this needed measuring. A Minecraft server has 50 ms to do each tick. Yours was spending most of that budget fighting this problem while still reporting a nearly full speed — so it looks healthy on any normal monitor right up until it tips over. That is what we caught.
  • Longest single freeze: 254 ms (anything much over 50 ms is a visible stutter).
  • Players online at the peak: 0.
  • Measured over 90 seconds.

What to do

The plugin needs to do that slow work in the background instead of during the game loop. That is a change for whoever wrote it — most authors fix this quickly if you show them. In the meantime, check the plugin's settings for anything that controls how often it talks to a database or a website, and slow it down.

What we ruled out

Worth saying explicitly, so you know this was not a guess:

  • Too many mobs or items — the number of creatures and dropped items stayed level (304 throughout), so nothing was piling up.
  • Too much world loading — the loaded area of the world barely moved (about 289 chunks the whole time), so it was not being loaded and dropped repeatedly.

Before you change anything

Two questions. If either answer surprises us, the diagnosis is wrong and we would rather find that out now than after you have pulled something out:

  • Does this plugin connect to a database, a web service, or write files while players are online?
  • Did the lag start around the time this plugin was installed or updated?

This is a real report from a real diagnosis, produced on the test bench described above — not a customer's server. The server and plugin names have been changed; every number is exactly as measured.

Two things in there are the whole product. It tells you what it ruled out, so you can see it considered the alternatives instead of grabbing the first plausible culprit. And it ends by naming the two answers that would prove it wrong — before you go pull a plugin out on its say-so.

What it sees of your server

IPs, chat, and credentials are stripped on your machine, before anything is sent anywhere. That's not a promise in a privacy policy — a redaction self-test ships inside the plugin, and it prints how many checks ran and how many failed. Run it yourself and read the number off your own console.

And the collector — the part that actually runs on your server — is open source under the GPL. You can read every line before you install it. If you're the kind of admin who doesn't install closed binaries from strangers on the internet: correct, and here's the source.

If you don't run a Minecraft server

This page is about tick times, but it isn't really about Minecraft. It's how I approach anything I build with AI in it: measure the thing, test the answers against faults the system has never seen, and give it a way to say "I don't know" out loud.

Plenty of people can generate a plausible-looking tool in an afternoon now. What's left — and what I actually do — is the boring part that proves the output is right. If you run a business instead of a server, that same discipline shows up as the Busywork Audit: measure what the chore really costs you, and say honestly which ones aren't worth automating.

Server lagging and nobody can tell you why?

That's the exact problem this was built for. Tell me what you're seeing.