Your Gross Margin % Looks Fine — Your Dollars Are Falling
Your Gross Margin % Looks Fine — Your Dollars Are Falling
In 2019, I pulled the P&L of a 14-truck residential HVAC shop that Atlantic Comfort Partners was preparing to acquire. The owner had been running it for eleven years. Knew his techs by name. Had a service agreement base his competitors talked about. His blended gross margin was sitting at 36-37%, and everyone in the deal process moved on.
I didn't move on. I got into the job-level data.
He had been losing money on every install for three years. Not losing margin percentage — losing dollars. The installs were running negative contribution after overhead allocation. The service volume was carrying the business, and the service volume wasn't growing fast enough to close the gap. The percentage had been showing him 36-37% the entire time. It had shown him nothing useful.
That shop is why I write about this.
The Number You're Watching
Gross margin percentage is a ratio. A ratio can hold flat while the dollars underneath it shrink — if both revenue and direct cost fall proportionally, the percentage doesn't move. Your P&L reports the percentage. Your bank account holds the dollars. Those are two different things, and QuickBooks presents them with equal confidence.
The same confusion shows up with markup versus margin. A 40% markup on a $1,000 equipment cost produces a 28.6% gross margin on the sale. I've sat across from shop owners who've been writing "40%" in their pricing notes and believing they were running 40-point margin for years. They weren't. The number they were watching was not the number they thought it was.
Gross margin percentage has the same seductive quality. It stays in range. It confirms you're doing about what you've always done. What it cannot show you is whether "what you've always done" still generates the dollars your overhead requires.
How Job Mix Moves the Dollars Without Touching the Percentage
The mechanism is arithmetic.
Take two months, same total revenue of $400,000 each. In the first month, your revenue splits 60% installs and 40% service. Blended gross margin is 38%. Gross profit dollars: $152,000.
In the second month, installs slow — a competitor cut prices, the spring rush didn't arrive, whatever the reason. Revenue splits 35% installs and 65% service. Your techs are running diagnostic and service calls all day, keeping trucks moving. Your blended margin actually ticks up to 40%, because service carries better labor efficiency on a percentage basis when you're not absorbing equipment cost into the ticket. Your QuickBooks P&L shows a two-point improvement.
Gross profit dollars: $160,000. That sounds better.
Here's the problem. A residential changeout, when priced to cover its costs, generates substantially more gross profit dollars per job than a service call. An equipment margin plus a labor margin on a $10,000 invoice is a different animal than a repair ticket. You replaced high-dollar-contribution work with high-percentage-but-lower-dollar work. The percentage went up. The total dollars improved by a small amount. But your capacity to cover fixed overhead — the same trucks, the same warehouse, the same insurance — didn't improve with it. Whether the dollars are enough is a question the percentage cannot answer.
I watched this at Bayview Mechanical in Sunnyvale, where I ran service calls for four years. The service tickets kept us busy. The install weeks were what kept the lights on. At Caldera, on the commercial side, I saw the same pattern from the other direction — service agreements looked great on a margin percentage basis until you compared the dollar contribution per truck per day against what the overhead actually cost.
Service tickets are bounded. The dollar contribution per call is real, but there is a ceiling set by what a customer will pay for a repair. Installs are where the equipment margin and the labor margin stack. That stacking is why the percentage can look thinner on installs while the dollars are doing more work.
Your P&L reports the percentage. Your bank account holds the dollars. Those are two different things, and QuickBooks presents them with equal confidence.
When a shop drifts toward service volume without tracking contribution by job type, it can spend months watching a percentage that looks fine while its actual ability to cover fixed costs quietly erodes. It doesn't announce itself as a crisis. It shows up as cash pressure that feels like a receivables problem. It is a job mix problem wearing a receivables problem's clothes.
The SEER2 Transition Made This Worse for Shops That Weren't Watching
SEER2 didn't hurt every shop the same way.
Shops that repriced their install proposals when equipment costs moved — that built new price floors from actual current invoice prices and passed the increase through — those shops are largely fine on install margin dollars. Their gross profit per changeout looks similar to 2021.
The shops that absorbed the equipment cost increase without repricing are not fine. In the shops I've worked with directly since 2022, more did the latter than the former. They held price because a competitor held price, or because they didn't want the conversation with a customer already writing a large check. And often because their flat-rate book didn't update and nobody noticed.
That last one is worth saying plainly. The flat-rate pricing books sold by the major industry vendors are designed to produce consistent ticket revenue. Consistent revenue per ticket is not consistent margin dollars per ticket — especially when your equipment cost moved and the book didn't. The book told you what to charge. The charge covered less cost than it used to. You got predictable revenue and structurally lower dollars. The vendors' commission doesn't depend on your margin.
For shops that absorbed the equipment cost increase, SEER2 created two problems at once: compressed install margin dollars on the cost side, and declining install volume as the post-pandemic replacement demand cooled. Service volume held percentage. Install dollars fell. The blended margin looked passable. The dollars told a different story.
What the P&L Actually Showed at the 14-Truck Shop
Back to the 2019 audit.
Revenue was $4.2 million. Gross profit on paper was $1.51 million — a 36% margin, enough to look like it was covering overhead with room remaining.
When I separated install revenue from service revenue at the job level, the install segment had been declining as a share of total revenue for three consecutive years. Consistently, not dramatically — maybe four or five points of mix per year. The overhead structure hadn't followed. Same truck count. Same warehouse footprint. Same equipment inventory carrying cost. The business was still sized for the install-heavy mix it had run when that overhead was built.
The cost-of-doing-business calculation this owner was using — anchored to the job mix from three years earlier — no longer matched reality. When I rebuilt it against the actual current revenue split, the install segment wasn't generating enough gross profit dollars to cover its allocated share of fixed cost. The service segment was subsidizing it. The service segment didn't have the volume or the ticket size to sustain that role.
What specifically had drifted: the dollar contribution per install job had fallen as equipment costs rose, the install volume had declined as a share of the mix, and the overhead per truck per day had stayed constant. Three things moved. The blended percentage absorbed all three and showed 36% throughout.
The only way to see it was to stop blending and start segmenting.
The Metric You Should Actually Be Running
Gross profit dollars by job category. Not blended.
The cost-of-doing-business worksheet I use in every engagement produces a per-job-type dollar contribution figure — what each category of work is generating in gross profit dollars, and whether that contribution covers its proportional share of overhead. You need to know your overhead before you can evaluate whether any job type is carrying its weight.
For a residential HVAC shop, the categories I'd separate: maintenance agreements, diagnostic and service calls, equipment changeouts, and add-on work (accessories, IAQ, anything sold alongside a primary job). If you do light commercial, give it its own bucket. Residential and commercial have different overhead allocation profiles and very different DSO behavior. Blending them produces a number that describes neither.
DSO matters here in a way most contractors don't account for. If you've drifted toward maintenance agreement billing on net-30 terms, your gross profit dollars in that segment may be real on paper and sitting in receivables for six weeks in practice. A residential install paid by credit card at point of service and a commercial maintenance invoice due in 30 days show identical gross margin percentages on your P&L. The cash conversion cycle is completely different. A shop carrying $200,000 in gross profit at 45-day DSO and a shop that converted that same $200,000 to cash last week are not in the same position, regardless of what the percentage says.
Watch the dollars. Watch when they arrive. Those are two separate questions.
What to Do Monday Morning
This takes one to two hours if your invoicing system has a job type or category field.
Pull the last 90 days of invoices. Sort by job type: service call, maintenance visit, equipment changeout, add-on. If you haven't been tagging job types, sort by invoice amount — not a perfect proxy, but sufficient to show you the shape of the problem. ServiceTitan users: the job type report in the revenue analytics module gets you there without manual sorting. Jobber users: filter by job category in the work orders export.
For each bucket, calculate total revenue and total direct cost separately. Direct cost means technician labor for that job type, parts and materials used, and equipment cost on the install bucket. No overhead allocation yet. Calculate gross profit dollars and gross margin percentage for each bucket independently. Write both numbers down.
Then calculate your overhead per truck per day: total overhead for the period — including your own compensation at what you'd pay a working journeyman with your skill set — divided by working days, divided by truck count. Compare that against what each bucket generates per job. If a full day of service calls on one truck generates $600 in gross profit dollars and your overhead per truck per day is $850, the margin percentage on those calls is beside the point. You have a math problem. It requires higher pricing, more volume, or both — and now you can see which.
Gross profit dollars per ticket by job type, compared against overhead cost per truck per day. Run that comparison. The percentage has been keeping that number from you.
FAQ
My gross margin percentage has stayed around 38% for two years. Why would I be concerned?
A stable percentage tells you the ratio of profit to revenue hasn't changed. It doesn't tell you whether the dollars are sufficient to cover overhead, or whether your job mix has shifted in ways that are reducing total contribution. If install volume dropped and service volume filled the gap, the percentage can hold at 38% while gross profit dollars fall by $40,000 or more. Less than enough to see on a monthly P&L glance. More than enough to create a cash problem by Q4.
How do I separate my P&L by job type if my accounting software lumps everything into one revenue line?
Start at the invoice level. QuickBooks and Xero both support classes or tags at the invoice level — if you haven't been using them, you can go back 90 days and tag manually. It's an afternoon. Going forward, set up job type classes before the next billing cycle. If you're on ServiceTitan, the job type segmentation is in the revenue analytics module. If you're on Jobber, filter by job category in the work orders export. The data is usually there. It just hasn't been surfaced.
Is it always bad if my business shifts toward more service and less install volume?
Not automatically. A service-heavy model with a strong maintenance agreement base has real advantages: more predictable scheduling, lower per-visit customer acquisition cost compared to cold replacement leads, and better retention data. The problem isn't the shift. The problem is when a shop built for install-heavy volume absorbs that shift without adjusting overhead allocation, pricing, or truck utilization targets. A service-heavy model can be profitable. It has to be built for service volume — not inherited from an install-heavy cost structure that hasn't been repriced.
How does SEER2 equipment pricing factor in if I'm buying equipment at different costs than two years ago?
Directly, on the install side. Your direct cost per changeout is higher than it was in 2021 for most equipment categories. If your install pricing didn't move proportionally, your gross profit dollars per install fell — even if your percentage held, because you may have passed through part of the increase and absorbed the rest. Rebuild your install cost from the actual invoice price on your last ten equipment purchases. Not from memory. Not from a price book that hasn't been updated since the transition. The gap between what you're paying now and what your price book assumes is where the dollar compression is sitting.
What's a reasonable gross profit dollar target per job type for a residential HVAC shop?
I won't give you a universal number — your overhead, market, and truck count determine the floor, and I'd rather you run the cost-of-doing-business calculation than use my number as a substitute for yours. What I can tell you is the method: calculate your overhead per truck per day, then determine how many jobs of each type a truck runs per day on average, and set your gross profit dollar floor per job so that the math clears. That floor is your shop's number. It will not match your neighbor's and it shouldn't.
If my installs are underfunded, do I raise prices or cut costs?
Start by identifying which cost is the problem. If your install gross profit dollars are thin because equipment cost went up and your price didn't follow, that's a repricing fix — rebuild your price floor from current invoice costs and adjust proposals. If your dollars are thin because direct labor hours per install have crept up — new equipment types your techs are slower on, jobs running longer than estimated — that's a field efficiency problem and a pricing model problem together. Pull actual labor hours from your last 20 install jobs and compare against your estimate. If jobs are consistently running longer than you quoted, you're underpricing labor regardless of what the equipment margin looks like. Fix the estimate before you fix the price.
Enjoyed this article?
Get articles like this in your inbox every Monday. Free, no spam.
