Build note

Catching payroll errors three days before the money moves

13 September 2026 ยท about 6 minutes

Payroll is the only process in people operations where a mistake lands in someone's bank account. Most other errors are recoverable in a way that payroll errors are not: you can fix a wrong job title on Monday and nobody's rent is affected.

Every payroll team I've worked with knows this, and every one of them reviews the register before approving it. The problem is that the review is a human reading a few hundred rows of numbers that mostly look like last month's numbers, looking for the four that don't. It's the exact task humans are worst at.

So I built something to do the looking.

What it actually does

Three days before the pay date - T-3, which is far enough ahead that a fix is still calm rather than urgent - the agent takes the draft register and the previous cycle's final register, and compares them line by line. It doesn't try to understand payroll. It tries to answer one question per employee: what changed, and is there a reason on file?

The checks it runs, in rough order of how often they catch something real:

  • Gross pay moved more than a threshold without a corresponding change in the HRIS. A raise that never got recorded, or a raise recorded twice.
  • Someone appears who wasn't there last cycle, and has no start date in the HRIS. Usually fine. Occasionally a rehire with a duplicate record.
  • Someone disappeared who has no termination date. This is the one that matters most. A person who left the register without leaving the company is a missed payment.
  • Hours outside the plausible band for their contract type. Nine hundred hours in a two-week cycle is a decimal in the wrong place.
  • Deductions that stopped. Benefits, garnishments, retirement contributions. These fail quietly and nobody notices for two cycles.
  • Tax jurisdiction changed without an address change on file, or an address changed without the jurisdiction following it.
  • Net pay of zero or negative. Rare and always worth a look.
  • Bank details changed since last cycle. Legitimate most of the time. It's also exactly what payroll diversion fraud looks like, so it gets flagged every time.

The output is a single page: what changed, for whom, what the system says about why, and a confidence marker. Nothing is auto-corrected and nothing is auto-approved. A person still signs off - they just sign off on eight flagged rows instead of scanning four hundred.

The design decision that made it useful: it flags on change without a reason, not on absolute thresholds. A $14,000 gross is not suspicious. A $14,000 gross for someone who was at $6,000 last cycle, with nothing in the HRIS to explain it, is the whole job.

Why the boring checks earn their place

When people imagine automating payroll review, they usually imagine anomaly detection in the statistical sense - a model that learns normal and flags outliers. I tried a version of that. It was worse.

Payroll data is small, seasonal, and full of legitimate irregularity. Commission months, bonus cycles, a company that hired fifteen people in one quarter. A statistical model spends most of its time being confidently wrong about things that are fine, and a reviewer who gets ten false flags stops reading the flags.

The deterministic checks above are unglamorous and they catch nearly everything that actually costs money. The missing-termination check alone has justified the whole thing more than once. There's a version of this problem where machine learning helps, and it's at a scale most companies under 500 people will never reach.

Where the data comes from, and the part that's annoying

The comparison is only as good as what the HRIS knows. That turned out to be the real work.

In most companies the HRIS and the payroll system disagree, quietly, about a handful of people. Someone's termination was entered in one and not the other. A department change happened mid-cycle. A contractor is in payroll but not in the people system at all, or the reverse.

So the first run of this against real data is never a payroll review. It's a reconciliation: here are the 23 employees where your two systems tell different stories. That's uncomfortable to look at and it's the most valuable output of the whole exercise, because every one of those 23 is a future error waiting for the right month.

If your HRIS and your payroll register disagree about who works for you, no amount of review automation will help until that's fixed. It's also usually a three-week job, not a three-month one.

What it takes to build

For a company under 500 people on a mainstream HRIS, this is roughly a three-week build: a week reconciling the two systems and agreeing what the source of truth is for each field, a week on the checks and thresholds against real historical registers, and a week of running it in parallel with the existing manual review to see what it misses and what it over-flags.

Running it in parallel matters. The first version of any check like this is tuned wrong, and the only way to find out is to compare its output against what a person who knows the payroll would have caught.

The expensive mistake is building the checks before doing the reconciliation. I've watched that happen. The flags come out meaningless, everybody loses faith in it by week two, and the underlying data problem - the actual problem - is still there.

If you're thinking about this for your own payroll

Two questions worth answering before anything else:

  1. Can you export the register as structured data? Most systems can. Some only give you a PDF, which is workable but adds a week.
  2. Do you trust your HRIS to know who currently works for you? If the honest answer is "mostly", start with the reconciliation and treat the review agent as phase two.

If the answer to the second one made you wince, that's normal, and it's the most common finding in this work rather than a sign that something is unusually wrong with your company.

Payroll and HRIS data that disagree

Reconciling the two systems and documenting what the source of truth is for each field is the HRIS Cleanup Sprint - three to four weeks, USD 10,000, fixed price.