The 23 Hours That Were Never Actually Worked

9

min read

9.9.26

A multi-department HVAC company migrating off a manual payroll spreadsheet caught its new system quietly crediting non-job hours that were never worked, 71 hours corrected down to 48 for one technician alone. Here's how running two systems side by side caught the gap before it reached a paycheck.

The Hours That Were Never Actually Worked

A multi-department HVAC company running install, service, and warranty crews across several dozen technicians was in the middle of a project a lot of growing shops eventually take on: moving pay calculations off a manually maintained spreadsheet and onto an automated system that pulls straight from the field service software everyone already uses every day. Only one of their departments synced cleanly enough with ServiceTitan to run fully automated. Everyone else was still living on a "bucket" spreadsheet, dollar amounts and category tags typed in by hand, department by department, every single pay period.

That's not a criticism of the company. It's just where a lot of multi-department field service businesses actually are. The office runs on Tuesday and Thursday deadlines, someone owns the spreadsheet because they've always owned the spreadsheet, and the whole system works, in the sense that people get paid roughly the right amount roughly on time. But "roughly right" and "verifiably right" are two different things, and the gap between them only becomes visible once you build something that forces a direct comparison.

That comparison is exactly what surfaced the problem here. As part of migrating one technician's numbers over to the automated system, the team pulled a metric called "non-job paid time," essentially the hours a technician gets paid for that aren't tied directly to a billable job: think drive time, warranty callbacks, recall visits, the kind of legitimate but non-revenue-generating hours every field service company has to account for somehow. For one technician, that number came back at 71 hours for the month. Once the underlying rule logic got corrected, the real number was 48 hours. Twenty-three hours, worth of pay, that had been sitting inside a single technician's check for time that was never actually non-job paid time at all.

It's worth pausing on how normal this kind of hybrid setup actually is, because it's easy to assume that any company still running part of its payroll off a spreadsheet is behind in some way. It isn't behind. It's mid-transition, which is a completely different thing, and mid-transition is where most growing field service companies actually spend their time. A ten-person shop can run everything off one spreadsheet and one person's memory. A company with several departments and dozens of technicians across install, service, and warranty work usually can't, not cleanly, and the move to automation rarely happens as a single flip of a switch. It happens department by department, integration by integration, with some crews syncing cleanly on day one and others staying on the manual process for months while the underlying data gets cleaned up enough to trust.

Twenty-three hours on one technician, one month, is real money. It is also, and this is the part that should get any multi-location owner's attention, exactly the kind of gap that is functionally invisible from the outside. Nobody was falsifying anything. No technician was gaming the system. The number simply came out wrong because of how a category was being classified underneath the report, and a wrong number that looks plausible is far more dangerous than a wrong number that looks obviously broken, because nobody has a reason to go check it.

Essential KPI Guide [Free Download]: We put together a guide + template of the top 20 essential KPIs used by thousands of successful businesses to boost efficiency and increase profits. Get the guide now →  

Why A Correct-Looking Number Can Still Be Wrong

The root cause traced back to how certain job events were being tagged. Some events that should have counted as regular paid job time, work a technician did that was tied to an actual billable job, were instead getting classified under the non-job paid time bucket. Every one of those misclassifications nudged the total upward by a little, and a little, repeated across a busy month across warranty visits, recall callbacks, and a handful of miscellaneous unassigned entries, adds up to twenty-three hours before anyone notices a pattern.

"We caught it because we were building the automated version side by side with the old spreadsheet, not because anything looked broken on its own," the operations lead said. "The number by itself looked completely reasonable."
A breakdown of one technician's non-job paid time by category, warranty callbacks, recall visits, and miscellaneous entries, with the total correcting from 71 hours to 48 hours.

That's the uncomfortable truth about a lot of payroll and incentive errors in field service businesses: the number that's wrong almost never looks wrong. Seventy-one hours of non-job paid time for a busy technician across a full month, spread across warranty work and recalls and the normal friction of a real job site, doesn't jump out as an outlier the way a $50,000 miscalculation would. It reads as plausible. It only becomes visible as an error when there's a second, independently built number sitting right next to it that disagrees, which is exactly what happened here, and exactly why the company was running the two systems in parallel in the first place rather than just cutting over and trusting the new automation on day one.

The fix had two parts, and they matter for different reasons. First, the underlying rule got rewritten so that events tied to a genuine paid job stopped being swept into the non-job bucket, closing the specific misclassification that produced the twenty-three hour gap for this technician. Second, the company added clean, structured category dropdowns for the events that legitimately do belong in that bucket: was this a technician-fault callback, which nets against their pay, or a technician-fixed visit, which doesn't. That second piece matters just as much as the first, because a vague, loosely tagged "non-job paid time" bucket is exactly the kind of category that drifts out of alignment again in six months if nobody gives the people entering the data a clear, constrained way to categorize what they're looking at. A dropdown with defined categories is a small, unglamorous fix. It is also one of the more effective ways to keep a number honest over time, because it removes the guesswork from the moment the data gets entered instead of trying to catch the error after the fact.

"A technician-fault callback and a technician-fixed visit should never net out to the same number in the report," the operations lead said. "Once we forced people to pick one or the other at entry time, the ambiguity that was causing the drift basically disappeared."

It's worth being specific about why that ambiguity was so costly. Under the old, loosely defined bucket, a callback where the technician made an error that required a redo, and a callback that happened purely because a part failed with no fault of the technician's, could end up tagged identically. One of those should reduce a technician's non-job paid time, because it represents rework the company shouldn't be absorbing as neutral. The other shouldn't touch their number at all, because the technician did nothing wrong and showing back up to fix a defective part is simply part of the job. Collapsing that distinction into one vague bucket doesn't just introduce a bookkeeping error. It quietly removes a signal the company actually wants: which callbacks are genuinely preventable, and which ones are simply the cost of doing business in the field. Separating them back out didn't just fix the hours number. It gave ownership a cleaner read on where rework was actually coming from.

Profit sharing

made simple.

Give your team a stake in the company’s success. ShareWillow helps you create and manage profit-sharing programs that motivate employees and drive business results.

Get a demo

What A Real Multi-Department Migration Actually Requires

The company didn't stop at fixing one technician's number and calling it done. Because the same misclassification logic almost certainly touched other technicians across the same period, a full historical audit got queued to check for the same pattern company-wide, not just going forward but backward through the periods the manual spreadsheet had already processed. That's the difference between patching a symptom and actually closing out a risk. A technician-by-technician fix that only applies going forward leaves open the question of whether anyone was already shorted, or overpaid, in a way that eventually surfaces as an awkward conversation nobody wants to have.

There's a real lesson here for any HVAC or field service company in the middle of migrating incentive or payroll calculations from a manual process to an automated one, especially a multi-department shop where only some crews sync cleanly with the field service software everyone actually uses day to day. The instinct is understandably to move fast: the manual spreadsheet is slow, someone always ends up chasing down last month's numbers on payroll day, and automation promises to fix all of that in one move. That promise is real. But the safest path to it runs the automated version alongside the existing process for at least one full cycle, ideally more, and checks every technician's number against the old method rather than sampling a few and calling the migration validated.

That discipline is what caught this particular gap. Nobody was auditing for fraud. Nobody suspected a specific technician of anything. The company was simply building a new report next to an old one, technician by technician, and noticed the two didn't match closely enough to explain away as normal variance. A plausible-looking number sitting alone on a payroll report will pass review almost every time, because there's nothing to compare it against. The same number sitting next to an independently calculated twin gets caught within minutes, which is exactly what a real incentive pay platform should make easy to do, not as a one-time migration step but as an ongoing habit.

Multi-department HVAC companies in particular tend to accumulate this kind of risk quietly, because growth usually happens department by department rather than all at once. One crew gets a clean ServiceTitan integration early and everyone assumes the rest will follow the same pattern. They usually don't, at least not on the same timeline, and the departments still running on spreadsheets are exactly the ones where a misclassified category can sit unnoticed the longest. The fix isn't to rush every department onto automation at the same moment. It's to treat each department's cutover as its own small audit, with the old and new numbers compared side by side until they agree closely enough to trust, technician by technician, before the spreadsheet gets retired for good.

There's also a people side to this worth naming directly. A technician who gets overpaid because of a classification error rarely complains, and that's exactly what makes this category of mistake more dangerous than the more familiar problem of someone getting shorted. An underpaid technician tells you something is wrong, usually the same week it happens, because the mismatch between hours worked and dollars paid is something they can feel directly. An overpaid technician has no reason to say anything at all, and the company can carry that quiet cost for months, across an entire department, before a side-by-side audit like this one happens to surface it. Building the habit of checking in both directions, not just watching for technicians who seem underpaid but actively auditing for the ones who might be getting more than they should, is what keeps an incentive system fair and financially sound at the same time.

None of this is a story about a company that did something wrong. It's a story about a company that did the migration the careful way, and the carefulness is exactly what paid off. A faster, less cautious rollout would have pushed the automated numbers live without the side-by-side comparison, and the twenty-three hour gap on this one technician, multiplied across however many others were quietly affected the same way, would have kept compounding silently for months. Instead, it got caught, categorized correctly, and closed before it ever reached a single paycheck.

Conclusion

An overpaid technician rarely complains, which is exactly why you have to audit for it instead of waiting to be told.

Create incentives
that
drive results

You shouldn't need complex equity plans to align your team. ShareWillow makes it simple to create transparent profit-sharing programs that motivate employees and grow your business.

See the product

Incentive plans to help
small businesses thrive.

"I was able to leverage the knowledge of the ShareWillow team to learn how other companies were designing their bonus plans. The template was extremely helpful."

Brian Tustin
Owner, First Rate Movers

Download for Free

Related Articles

A before and after reveal showing tracked tune-ups jumping from 6 to 46 once a broken job-type filter was corrected.

The Dashboard That Only Saw One In Eight

A multi-trade HVAC, plumbing, and electrical company wanted to trade rising base pay for real performance pay, until it found its new dashboard was only tracking one tune-up in eight a technician actually completed. Here's how three silent bugs nearly undermined the whole strategy before a single paycheck went out.

Continue reading

September 9, 2026

Motivate employees to act like owners, without complicated equity

Book a performance pay audit today, and let us show you how ShareWillow can help your business increase efficiency, reduce callbacks, and grow profits.