Why Your Overhead Allocation Is Lying to Your P&L
Why Your Overhead Allocation Is Lying to Your P&L
In 2019, I sat in a conference room in Tysons Corner with a printed P&L from a 14-truck residential HVAC shop. The owner had grown revenue 22% over three years. He ran a maintenance agreement program with around 800 active customers. His service department showed a 31% gross margin. Consistent quarter over quarter.
Then my team rebuilt the job-level numbers with a different allocation method. The install department had been losing money for three years. Not trimming margin. Losing money. The overhead spread had made installs look marginally acceptable and service calls look like profit centers, so the owner had spent three years doing exactly what the P&L seemed to recommend: cut install crew hours, push service volume, double down on agreements. Rational decisions. Wrong inputs.
The acquisition didn't close. He was reading a document that described a business he didn't recognize when we showed him the corrected numbers, and at that stage of the process there was no time to reprice and retest. That one still bothers me.
How the Standard Method Produces the Wrong Story
The revenue-percentage method is how most small shops allocate overhead, and it's easy to understand why. Take total overhead for the period, divide by total revenue, get a percentage, apply it to every job.
It is also systematically wrong in a way that is nearly invisible until the damage compounds.
The distortion lives in the allocation layer underneath the numbers owners check. That layer silently determines whether job A is subsidizing job B. When the allocation method is disconnected from how costs actually behave, the P&L confidently tells you the wrong story about which work is making money.
Revenue-percentage allocation punishes your high-ticket jobs and flatters your low-ticket ones. A $12,000 install absorbs three to four times the overhead of a $3,000 repair ticket under this method, regardless of whether it actually consumed three to four times the company resources. In residential HVAC, that split almost never reflects reality.
Not All Overhead Behaves the Same Way
Overhead is not a single category. Treating it as one is where the error begins.
Three classifications:
Time-based costs accumulate while a truck is in the field and a technician is on the clock. The operating cost per billable hour of a vehicle is the most important number here, and most shops either don't calculate it or use a national average they found somewhere. The national average is a fiction. A Sprinter running 80 billable hours a month in a high-density metro carries a completely different cost structure than one logging 110 hours in a smaller market with shorter drive times. Fuel spend per mile, commercial auto insurance premiums, scheduled maintenance intervals — all of it varies by vehicle and by geography. The number has to be yours.
Commercial auto premiums have risen sharply since 2021. In the shops I've worked with, the increases have been significant enough that a shop setting its vehicle cost allocation in 2020 and never updating it is running on math that understates the real current cost — sometimes by enough to flip an install from marginal to negative. That gap doesn't show up as a line item. It shows up as margin compression you can't locate.
Job-based costs are costs that a specific job caused. A permit pulled for a specific install belongs on that install's job cost, not spread across the company. A linebreak fitting ordered on a return trip, a disposal fee for the condemned unit, a crane rental for a rooftop application — these are job-caused expenses. Spreading them as general overhead is how a complicated $9,000 job subsidizes a straightforward $9,000 job that required none of those costs.
Fixed period costs accrue whether you run one job or forty. Rent, business insurance, administrative salaries, software subscriptions, the owner's market-rate compensation. These get spread across a denominator, but the denominator should be chosen deliberately — total billable hours in the period, or total job count, depending on which tracks more closely to how the cost is consumed.
The three cost types don't behave alike. Forcing them through a single allocation method is like doing a load calc by square footage when you have a house with a cathedral ceiling, a finished basement, and four exposures of west-facing glass. The math closes. The number is wrong.
What Revenue-Percentage Allocation Actually Does to Your Job Mix
Here's the specific distortion. Under the percentage method, a $14,000 split-system install absorbs roughly four to five times the overhead of a $3,000 diagnostic-plus-repair ticket. If your company overhead rate is 28% of revenue, that install carries $3,920 in allocated overhead. The service call carries $840.
Now look at what actually happened in the field. The install took two technicians eight hours, two truck dispatches, and a return trip for a linebreak fitting. The service call took one technician 1.4 hours and one dispatch. On a time-based allocation, the install consumed roughly 2.5 times the time-based overhead of the service call. On a job-based allocation, the install also carried the permit and the disposal costs the service call never touched.
The revenue-percentage method charged the install more than double the time-based overhead it actually consumed and cut the service call's charge to less than half of what it should have carried. The install looked like a margin problem. The service call looked like found money.
This intersects with Manual J. A correctly-sized system on a proper load calculation might produce an install revenue line of $11,500. A system sized by rule of thumb (still happening on a majority of the jobs I review) might produce $13,800 because the equipment is bigger. Under percentage allocation, the oversized job absorbs more overhead even if it took identical truck hours and crew time as the properly-sized one. Oversizing is already a margin problem at the equipment cost level. The allocation method turns it into a double distortion.
The flat-rate pricing books from the major industry vendors don't help here. They're calibrated to produce predictable revenue per ticket — useful for the vendor, because their commission tracks to revenue. They don't produce predictable margin per ticket, because your overhead structure isn't what the book was built around. A shop pricing service off a vendor flat-rate book and allocating overhead by revenue percentage is pricing off two disconnected inputs simultaneously. The revenue per ticket looks stable. The margin lands wherever it lands.
The Fix: Match the Allocation Method to the Cost Behavior
The answer most consultants reach for here is activity-based costing software. For shops under 25 trucks, that's usually the wrong tool. The implementations are time-consuming to configure, require data entry discipline most small shops don't have the administrative capacity for, and produce reports that are only as good as the cost driver assumptions baked in at setup. If the cost classification is wrong, the software calculates the wrong number with impressive consistency.
The fix is a cleaner classification on a spreadsheet, reviewed quarterly.
Time-based costs get allocated by billable hours on the job. Pull actual fuel spend, actual insurance premiums, actual scheduled and unscheduled maintenance costs for each vehicle over the trailing 12 months. Divide by actual billable hours logged per truck over the same period. That is your time-based cost per billable hour for that truck. Apply it by hours on the job, not by revenue the job produced.
When I walk shops through this calculation, the gap between what's sitting in their pricing model and the actual number is almost always larger than the owner expected — and I've been doing this long enough that I don't give them a range anymore before they run it themselves. The shops that are furthest off are invariably the ones that set the vehicle cost figure in 2020 or 2021 and haven't touched it.
Job-based costs get assigned directly. A permit is not a company overhead item. This is a bookkeeping discipline, not a software problem. It requires whoever is entering job costs to capture those expenses at the job level before they hit a general overhead account.
Fixed period costs get spread by a chosen denominator — I use total billable hours for costs that scale with activity, total job count for costs that are more per-engagement in nature. The denominator gets reviewed every quarter. Businesses change shape underneath a static assumption faster than owners expect.
In the shops I've moved through this process, install gross margin almost always drops on paper once the time-based costs are properly allocated — and service margin rises, because the service calls were previously absorbing overhead they didn't cause. Nothing changed in the business. The corrected numbers describe what was already happening.
A Story: The Shop That Thought Installs Were the Problem
Back to that 14-truck shop.
The owner had been in business 11 years. He knew his market, ran a tight service operation, and had built the maintenance agreement program from about 200 customers to over 800 over four years. He responded to cash pressure the way his P&L told him to: cut install crew hours, push service calls, use the agreement program to smooth revenue. Sensible moves. His service fee was $89 — he told me it hadn't moved since 2016, because service kept showing up as the profitable side of the business.
When my team rebuilt the job-level P&L with time-based allocation for truck and technician costs, and pulled job-based costs off the overhead pool onto the specific jobs that caused them, the picture reversed. Install margin on AHRI-matched split systems came out at negative 3% after overhead. Service looked better than the original model showed — not because the service margin improved, but because it stopped absorbing install overhead it hadn't caused.
The acquisition didn't close because of the install margin. Negative 3% on a job type representing 40% of revenue wasn't something the investment committee was going to step over, and there was no time left to reprice. The seller was genuinely surprised. He had been reading a P&L that described a business where installs were a modest drag and service was carrying the operation. Neither statement survived the corrected allocation.
He was a capable operator. The math was just wrong.
What to Do Monday Morning
You don't need new software. You need three hours and a clean 12 months of actuals.
Step one: classify last quarter's overhead into the three buckets. Go line by line through your overhead accounts. For each item: does this cost accumulate with time in the field, did a specific job cause it, or does it accrue regardless of job volume? Run that classification yourself — the proportions will tell you something about your business that a category average won't.
Step two: calculate your actual truck operating cost per billable hour. Fuel spend, insurance premiums, oil changes, tires, repairs, registration — per truck, trailing 12 months. Divide by billable hours logged for that truck over the same period. Compare to whatever rate is in your current pricing model. The gap between those two numbers is what you've been absorbing on every job since you last updated the figure.
Step three: run one install and one service call through the corrected allocation. Pick typical jobs, not outliers. Allocate time-based costs by hours, assign job-based costs directly, spread fixed period costs by billable hours. Write down the gross margin. Compare it to what your current method shows.
One additional item. If you're carrying receivables past 30 days on commercial accounts, your days sales outstanding is adding a cash drag to jobs that already look profitable at close. DSO and corrected job margin belong in the same conversation — they together tell you which work is funding the business and which work is just moving through the P&L.
FAQ
My CPA does our job costing — why would the allocation be wrong if a professional is handling it?
Your CPA is almost certainly doing this correctly for tax purposes, which is a different objective than management accounting. Tax-basis job costing follows rules designed to produce a defensible return, not to tell you which jobs are making money. The CPAs I've seen working with small contractors in this size range use revenue-percentage allocation because it's straightforward and defensible to the IRS — not because it's accurate at the job level. The tax return and the management P&L should be two separate documents serving two separate purposes. If you're only running one, it's doing one job.
We use ServiceTitan and it has a job costing module. Isn't this already solved?
The module is only as accurate as the cost classification and the data entry behind it. If your overhead pool is being allocated by revenue percentage inside the platform — ask your implementation consultant how it was configured at onboarding, because that's the setting I find most often — the module is calculating inaccurate numbers quickly and presenting them well. Review the overhead allocation configuration. If you can't find that documentation, assume revenue-percentage and start from there.
How do I handle overhead allocation for a job that runs longer than estimated?
Time-based allocation actually handles this correctly by design. If you allocate truck and technician overhead by hours, a job that runs 10 hours instead of 7 automatically picks up the additional time-based overhead. Your gross margin on that job gets hit, which is accurate — you consumed more field resources than priced. Under revenue-percentage allocation, the overrun is invisible because the revenue didn't change. Time-based allocation connects scheduling discipline directly to margin, which is where it belongs.
Should I recalculate my truck cost quarterly or annually?
Quarterly is better if your insurance premiums are actively moving, which they have been since 2021. Annual is the floor. The shops I've seen with the largest gaps between their pricing model assumption and reality are almost always ones that set the vehicle cost number at initial model setup and treated it as permanent. Commercial auto premiums, fuel, and maintenance costs have moved enough since 2021 that a rate set that year is likely understating current cost. Build the recalculation into your quarterly close.
What if I don't have billable hours logged per truck? How do I even start?
Start with the next 90 days. Have your dispatcher or your field service platform begin logging actual hours per truck per job. You don't need historical perfection to improve the current allocation. Even a rough estimate of billable hours per truck per month — job count times average job duration by type — is better than revenue percentage. Get 90 days of clean data, then recalculate. The number doesn't have to be perfect to be more useful than what you're using now.
My installs are almost always flat-rate priced. Does overhead allocation even matter if the price is already fixed?
It matters more, not less. Flat-rate pricing on installs means you've already committed to the revenue number. The only variable that determines whether that job made money is cost, including overhead cost. If your overhead allocation is overstating install overhead — which it usually is under revenue-percentage — you're reading a margin that's worse than reality, and you may be walking away from competitive work or raising prices based on inaccurate data. The flat-rate price was set at some point using some cost assumption. Knowing whether that assumption is still accurate is how you avoid discovering the answer by running out of cash.
Enjoyed this article?
Get articles like this in your inbox every Monday. Free, no spam.
