The Costing Mistakes That Compound Quietly

Why this matters

A costing mistake that shows up as a bad number gets fixed. The dangerous ones show up as a good number. Six specific errors in how a shop captures and rolls up cost will make a losing job type read as a winner, and because that reading feeds the next estimate, the shop then bids the type more aggressively and loses more on it. That is what compounding means here: the error does not sit still, it gets written into the template and multiplied by next year's volume. Every one of the six below is common, none of them look like a mistake from the outside, and all six have a detection test you can run in an afternoon.

What makes a costing mistake compound

An ordinary mistake costs you once. A compounding one has three properties: it biases in a consistent direction rather than randomly, it is invisible in the summary report, and its output is an input to a future decision. Random noise averages out over enough jobs. Directional bias does not. It survives every average you take, and the more data you collect the more confident you become in the wrong number.

The tell is always the same. Something real happened, and the cost of it landed somewhere other than the job that caused it.

Drive time that never lands on a job

Most shops book drive time to a shop or travel overhead code rather than to the job. That is a defensible bookkeeping choice for cost allocation, and it is a separate question from whether the time is paid, which it usually is once the workday has started. It stops being defensible the moment you use job-level labor hours to judge estimating accuracy, because the estimate almost certainly included getting there.

It compounds because drive time is not evenly distributed. Your dense-route job types shed almost none of it and your scattered, out-of-area types shed a lot, so the job types that are genuinely worst on travel look identical to the good ones. Bid a few more of them and you have bought the problem at scale.

Detection test: take five jobs of one type from last month and reconstruct round-trip drive from dispatch times or vehicle records. If the average is a meaningful fraction of the estimated job hours, and you cannot find those hours anywhere on the job record, they are landing in overhead.

Parts costed at catalog instead of what you paid

A parts file with prices in it is a convenience that ages badly. Every job costed against a stale file understates actual parts cost by exactly the amount the file has drifted, on every single job that uses that part, forever, until someone updates it.

This one is nastier than it looks because it does not just misstate the job. It misstates margin by job type in a way that tracks how parts-heavy the type is, so your most material-intensive work, usually your largest tickets, is the most overstated. It also survives a switch to a new estimating tool, because the stale file gets imported.

Detection test: pull the nine or ten most-used parts, compare the file price against the last supplier invoice you actually paid, and note the date the file was last touched. Snapshot the paid cost onto the job at the time of use rather than reading it live, so a later catalog update cannot rewrite a closed job's margin.

Time rounded in one direction

Techs round. That is not the problem. The problem is that rounding is almost never symmetric in practice. Someone who finishes at 47 minutes past the hour and logs the half hour has dropped 17 minutes. The same person finishing at 8 minutes past logs the hour and drops 8. Neither entry ever rounds up. The loss is small per job and relentless, and the direction is the whole problem.

It compounds because it scales with the number of time entries, not the size of the job. Job types made of many short visits lose proportionally far more than a single long install, which quietly makes short-visit work look more efficient than it is, which is exactly the work most shops are already underpricing.

Detection test: for one week, have two techs log to the minute alongside their normal rounded entry. The gap between the two totals, expressed as a percentage of the rounded total, is your rounding bias. If it is directional rather than near zero, fix it by rounding to the nearest increment instead of the previous one, and pick a smaller increment. This one is not only a costing question: under 29 CFR 785.48(b) a rounding practice is permissible only where it averages out over time so employees are paid for all time actually worked, so a practice that consistently rounds down in the employer's favor is a wage-and-hour exposure as well as a bad number. That is why "round to nearest" is the fix rather than "round down less."

Jobs dropped from the report because they have no data

A job with no time entries is not zero hours. It is an unknown, and most reports treat it as absent, which silently removes it from every average. The jobs missing data are not a random sample. They are disproportionately the jobs that went badly, ran late, ended at 7 in the evening, or got handed between two people, which is to say the ones that would have moved your median most.

Detection test: count completed jobs in the period, count jobs with at least one time entry, and state the difference as a percentage of completed jobs. Then look at what the missing ones have in common. If they cluster on a tech or a shift, you have a logging problem to fix before you have a costing problem to analyze.

Jobs excluded because they "weren't typical"

The deliberate version of the previous error, and harder to argue with because a person made a judgment. The job that ran three times its estimate gets pulled out of the review as an outlier caused by a customer nobody could have predicted.

Sometimes that is right. Usually it is not, because "atypical" is being defined after the fact by the result rather than in advance by a condition. If a job type produces one three-times-estimate job every quarter, those jobs are not outliers, they are a feature of the type, and their hours belong in the number you bid against.

The honest version of this rule is set in advance: define the exclusion condition before you see the result. Something like "excluded if the customer changed the scope in writing mid-job, and the change was priced separately." That is a condition. "It was a weird one" is not.

Detection test: look at every job excluded from the last two reviews and ask whether the stated reason would have been knowable before the job ran. Any that would not have been go back in.

Corrections stacked on corrections

The subtlest of the six and the one that only appears in shops that are already doing this well. You measure a job type at 10% over, multiply the template's labor line by 1.10, and deploy it. Next quarter the same type measures 3% over. The correct move is to multiply the current template by 1.03, giving a cumulative factor of 1.10 x 1.03 = 1.133 against the original. The wrong move, and it is an easy one, is to apply 1.10 again because that is the number in your notes, giving 1.21 against the original, which is about 7% above where the evidence says the template should sit.

It compounds by definition. Two or three cycles of stacking and the type is priced well out of the market, the win rate drops, and nobody connects the lost bids to a spreadsheet habit.

Detection test: for each job type, keep the cumulative multiplier against the original baseline written down next to the current template, and make every variance measurement explicitly against the version of the template that was live when the job was bid.

A worked case: one job type, four of the six

A shop reviews an equipment replacement type. Template estimate is 10.0 labor hours per job. Twelve of them ran in the quarter, so 120.0 estimated hours committed.

The report shows ten jobs with time logged, totalling 92.0 hours, an average of 9.2 hours against 10.0 estimated. Read straight off the screen, that is 8% under estimate, and the owner's first instinct is that the type has room to be bid tighter.

Four corrections, in order:

Drive time. Round-trip drive on this type averages 0.8 hours per job and is currently booked to a travel overhead code. Adding it back to the ten reported jobs: 0.8 x 10 = 8.0 hours, bringing the reported total to 100.0 hours.

Rounding. A one-week to-the-minute check found this crew losing an average of 0.3 hours per job to rounding down. Adding it back: 0.3 x 10 = 3.0 hours, bringing the total to 103.0 hours.

The two missing jobs. Neither had time entries and both were silently dropped by the report. Reconstructed from dispatch records and the site sign-off times, they ran 14.3 and 14.8 fully loaded hours, adding 29.1 hours.

Total actual labor across all twelve jobs is 103.0 + 29.1 = 132.1 hours, an average of 11.0 hours per job against the 10.0 estimated. The type is running about 10% over estimate, not 8% under. The reported figure and the real one sit about 18 percentage points apart, and every one of those points came from a bookkeeping choice rather than from the field.

Parts. Separately, the parts file backing this type was last updated 14 months ago. A spot check of nine recent supplier invoices found paid cost averaging 6% above the file, so the type's parts line is understated by roughly that much on top of the labor gap.

Now the fifth error is available to make. Having found 10% over on labor, the shop multiplies the template's labor line by 1.10 and moves on. Next quarter it measures 3% over, and the whole value of this case is that the second correction has to be 1.03 applied to the already-corrected template, not another 1.10.

The afternoon audit that finds all six

Run these in this order, on one job type, and you will have a defensible number by the end of the day.

  1. Count the gap. Completed jobs in the period against jobs carrying at least one time entry. Anything missing goes on a list, not into the average.
  2. Reconstruct the missing ones from dispatch, sign-off, or vehicle records rather than dropping them.
  3. Pull five jobs and add back drive from the same records, and decide once, in writing, whether drive lives on the job or in overhead for costing purposes. Either is workable. Switching between them by accident is not.
  4. Check three parts against their last paid invoice and note the file's last-updated date.
  5. Review the exclusions from the last two reviews against the knowable-in-advance test.
  6. Write the cumulative multiplier down next to the template before you change anything, so the next person to touch it knows what has already been applied.

Steps 1 through 4 change the number. Steps 5 and 6 stop the number from being wrong again next quarter, which is the part that actually pays.

References

  • U.S. Small Business Administration (SBA), small business financial recordkeeping guidance
  • IRS, recordkeeping requirements for business expenses (Publication 583 concepts)
  • Trade-standard practice for job cost capture and production-rate maintenance
  • See related: The Job Costing Data a Small Shop Actually Needs, How to Read Your Own Job Costing Data, How to Capture Actual Costs Without Slowing the Crew, Why Small Consistent Misses Cost More Than Big Rare Ones