Skip to content
← Back to Blog
Trades

How HVAC Shops Should Track Per-Job Profitability

Poof TeamUpdated 13 min read

## Why Per-Job Profitability Matters More Than Monthly Revenue

Most HVAC shop owners know their monthly revenue almost in real time. They can tell you what came in last week off the top of their head. But ask them which jobs actually made money and the answer changes — a long pause, a guess, and usually a hedge: "the big install was probably good."

That gap is expensive. When you cannot tell which jobs made money, you cannot price the next one correctly. You bid the same way you bid the last one, hoping the average works out. Sometimes it does. Often it does not, and the loss is invisible until it has compounded across dozens of jobs.

Per-job profitability is the single most useful number in a service business. Not monthly revenue. Not gross margin. The specific dollars and percent each completed job left behind after labor, materials, truck costs, and overhead came out. Once you have it, three things change:

  • Pricing on the next bid is grounded in evidence, not gut
  • You learn which job types and customer segments are worth chasing
  • You spot tech-level or crew-level profitability differences you cannot see in the P&L

This guide walks through how to set up per-job costing for a typical residential HVAC service shop doing $750K–$3M with 2–6 trucks. The tactics apply to plumbing and electrical service contractors too.

What Counts as a "Job" for Costing Purposes

Before you can cost a job, you have to decide what a job is. For an HVAC shop, the practical answer is usually one of three:

  • Service calls — diagnostic, repair, maintenance visits, often single-day
  • Replacements / installs — equipment swap-outs, one to three days
  • Commercial projects — multi-day, multi-phase, often invoiced in milestones

Each type behaves differently and costs differently. A maintenance call has near-zero materials and dominates on labor and truck cost. An equipment install has materials as the biggest line item. A commercial project has all three plus permit costs and longer payment terms.

Set up your job cost tracking to handle all three. If you treat them the same, the averages will hide the truth.

The Four Cost Buckets to Track Per Job

For every job, capture these four buckets. Get the buckets right and the math works regardless of which field tool you use.

1. Direct Labor

This is the tech's loaded labor cost — wages plus payroll taxes plus benefits plus workers comp — multiplied by hours on that job.

The mistake most shops make is using the straight hourly wage instead of the loaded cost. A tech you pay $32 an hour actually costs you $42–$48 once you load payroll taxes, comp, and benefits. Using $32 makes every job look more profitable than it is.

How to capture it: Time-on-job from your field tool (Jobber, Housecall Pro, ServiceTitan). Multiply by the loaded hourly cost per tech.

The harder problem: hours that don't belong to one job. Time-on-job handles the clean case — a tech is at the Henderson install from 8am to 3pm. What it does not handle is the rest of the payroll. Shop time, a morning spent pulling permits, a tech riding along on a job that only needed one person, drive time between three calls. Those hours are real, they are paid, and they belong to the work somewhere.

Most shops handle this by ignoring it, which means their job costs only include the hours that happened to be tagged. Your jobs then look profitable while your P&L says otherwise, and nobody can explain the gap. If your costed labor for the month is materially less than your actual payroll, that gap is the answer.

Two workable approaches:

  • Allocate the untagged hours proportionally. Total your paid direct-labor hours for the month, subtract the hours already tagged to jobs, and spread the remainder across jobs in proportion to their tagged hours. Crude, but it closes the gap and it is defensible.
  • Allocate by job type. If installs reliably carry more untagged overhead than service calls — permits, staging, a second body for a lift — weight the allocation accordingly rather than spreading it evenly.

Either way, the test is the same: the labor cost you assigned to jobs this month should reconcile to the direct labor on your P&L. If it does not, your per-job margins are systematically overstated by the difference. This is the single most common reason a shop's job costing says 34% while the income statement says 26%.

2. Materials

Equipment, parts, refrigerant, consumables. The clean version is everything that physically went onto the job, valued at what you paid for it.

The trap here is supply-house runs that get shared across multiple jobs. A tech runs to Ferguson, picks up parts for two jobs, and the receipt has both. If the receipt does not get split, one job absorbs the full cost and the other looks free. Over a month, this scrambles your numbers.

How to capture it: Receipt scanning at the supply house, with the receipt tagged to the right job — ideally split across multiple jobs at the point of capture. Vendor invoices for equipment.

3. Direct Truck and Equipment Cost

This is the cost of getting the truck and the tech to the job. Fuel, mileage, tools used, equipment depreciation. Most shops skip this entirely and bury it in overhead. That's a mistake — truck cost is huge for service businesses, and allocating it makes long-distance jobs look as expensive as they actually are.

A simple version: pick a per-mile or per-hour truck cost (most shops land somewhere between $0.60–$1.00 per mile or $15–$25 per truck-hour, depending on vehicle and gear) and apply it to each job's actual usage.

How to capture it: Either GPS-tracked mileage from your field tool times a per-mile rate, or truck-hours per job times a per-hour rate. Pick one and stay consistent.

4. Allocated Overhead

This is everything that doesn't tie to a specific job but exists because the shop exists: dispatcher salary, shop rent, software, insurance, marketing. You cannot leave it out of job cost — if you do, every job looks more profitable than it really is and you'll price too low.

The standard allocation is monthly overhead divided by billable tech-hours, then applied to each job by its actual labor hours.

Example. If your monthly overhead is $42,000 and your shop produces 1,400 billable tech-hours per month, your overhead rate is $30 per tech-hour. An 8-hour install absorbs $240 in overhead.

How to capture it: Calculate the rate quarterly, then apply it programmatically. Re-check the rate every quarter — it drifts as the shop grows.

What "Profit" Means in a Per-Job P&L

Once you have the four cost buckets, the per-job P&L is straightforward:

  • Job revenue — invoice total
  • Less direct labor (loaded)
  • Less materials (at cost)
  • Less truck cost (allocated)
  • Equals gross job profit
  • Less allocated overhead
  • Equals net job profit

Two numbers matter. Gross job profit tells you whether the work itself was profitable — useful for pricing and bidding. Net job profit tells you whether the work was profitable after overhead — useful for portfolio decisions like "should we keep doing this kind of job."

A common pattern: jobs are gross-profitable but net-unprofitable. That means the work itself makes money, but you do not have enough volume to absorb your overhead. The fix is volume, not pricing — though it is also a warning sign if you're stuck there too long.

A Worked Example: The Henderson Install

Here is what this looks like on a real install.

ItemAmount
Invoice total (2.5-ton heat pump)$18,400
Equipment cost$6,200
Materials (Ferguson, Johnstone)$1,840
Direct labor (22 tech-hours at $44 loaded)$968
Truck cost (3.5 truck-hours at $20)$70
Gross job profit$9,322 (50.7%)
Allocated overhead (22 tech-hours at $30)$660
Net job profit$8,662 (47.1%)

Now compare that to a maintenance call:

ItemAmount
Invoice total (annual tune-up)$189
Materials$12
Direct labor (1.25 tech-hours at $44)$55
Truck cost (1.0 truck-hours at $20)$20
Gross job profit$102 (54%)
Allocated overhead (1.25 tech-hours at $30)$38
Net job profit$64 (34%)

The install has lower gross margin percent but much higher net margin percent — because its labor hours are dense relative to the dollars on the invoice. This is the kind of pattern that changes how you bid and which jobs you chase. You cannot see it without per-job costing.

The Hard Part: Getting the Data Into Your Books

Capturing per-job costs is not the limiting step. Most HVAC shops capture the data already — Jobber or Housecall Pro tracks time on the job, your receipts are sitting in a pile or scanned somewhere, your vendor invoices are in email.

The hard part is getting all of that into your bookkeeping system in a structure that lets you actually pull a per-job P&L. Most shops never get there because:

  • Jobber and QuickBooks do not natively share job-level cost data — labor and materials live in Jobber, overhead and bank activity live in QBO, and nothing ties them together
  • Bookkeepers manually rekey job data between systems, which is slow and error-prone
  • Supply-house receipts get categorized to a "Materials" expense account without a job tag, so they are aggregated by month, not by job
  • Monthly close lands two to three weeks late, which means per-job P&Ls are stale by the time anyone sees them

The result is a shop that has all the data it needs to see job profitability and zero ability to actually see it.

Three Patterns That Actually Work

There are three ways HVAC shops successfully get to per-job profitability. Pick whichever fits your shop size and stomach for software work.

Pattern 1: Field tool + spreadsheet. Export jobs and time from Jobber or Housecall Pro to a spreadsheet, manually enter materials and overhead, calculate per-job profit. Works for shops with 50 jobs a month or fewer. Stops working past that because the manual work eats your week.

Pattern 2: Field tool + QuickBooks classes or projects. Use QuickBooks' projects feature (Plus and Advanced tiers) and tag every transaction with a job. Requires discipline and a bookkeeper who actually uses the feature. Most shops set it up and abandon it within a quarter because tagging every transaction is a chore.

Pattern 3: Managed bookkeeping with direct field-service integration. A service like Poof Managed for Trades connects directly to Jobber or Housecall Pro, pulls job data into the ledger automatically, and produces per-job P&Ls without manual rekeying. A former controller reviews the categorizations before anything is final, so the numbers are audit-grade. This is what we built for shops that hit the ceiling on patterns 1 and 2.

If you're under 30 jobs a month, start with the spreadsheet. Once you cross 50 jobs, the manual approach starts breaking. By 100 a month, you need a real system.

What to Do With the Numbers

Per-job profitability is only worth tracking if you actually act on it. Three things to do once the data starts coming in:

  • Re-price the bottom 20%. Sort jobs by net margin. The bottom-margin jobs are usually a pricing problem, a scope-creep problem, or a job-type problem. Adjust your bid template for that kind of work.
  • Look at tech-level patterns. If one tech consistently delivers higher margins on the same job type, that's a coaching opportunity for the rest of the crew. If one tech consistently delivers lower margins, look at whether the issue is speed, callbacks, or upsell rate.
  • Flag customer segments. Sometimes the issue is a customer, not a job type — a property manager who always pushes scope, a builder who pays slow. Per-job data makes this concrete instead of a vague gripe.

Compare jobs against each other, not just against a target

A single job's margin is hard to judge in isolation. Is 27% good on a heat pump changeout? It depends on the equipment, the crew, the season, and what your other changeouts returned.

The more useful comparison is against your own similar jobs. Group by job type and look at the spread rather than the average. A changeout that ran 12 points under your other changeouts is a specific, answerable question — was it the equipment cost, the hours, a callback, a discount someone gave in the truck? An average tells you none of that, and the outliers are where the money is.

Two habits make this work. Review by job type every month rather than looking at the whole list. And look at the bottom of each group specifically, because a couple of bad jobs inside an acceptable average is the most common way a real pricing problem stays hidden.

Watch for costs that never made it onto the job

Some costs are real, attributable, and almost never costed to the work that caused them:

  • Callback labor. A return trip on a job already invoiced. If it lands in a general labor bucket, the original job keeps a margin it never earned.
  • Permits and inspections, including re-inspection trips.
  • Financing dealer fees. When a customer finances an install, the lender funds you less a fee that comes out of your side. Recorded in general expenses, financed jobs report a margin they never earned — often by 6 to 10 points. This is covered in why dealer financing hides your real install margin.

The rule underneath all three: if a cost was caused by a specific job, it belongs on that job.

The Bottom Line

If you run an HVAC, plumbing, or electrical shop and you can tell me your monthly revenue but not which jobs made money, you're flying with one instrument. Per-job profitability is the second instrument. Once you have it, every bid, every crew assignment, and every customer decision gets sharper.

The data is already in your field tool and your bank account. The work is connecting the two — and either doing that yourself, getting your bookkeeper to do it, or moving to a system that does it automatically.

For the broader picture — the chart of accounts, the Jobber-to-books handoff, the monthly close routine, and what each bookkeeping option costs — see our complete guide to HVAC bookkeeping. Running plumbing or electrical work too? The plumbing bookkeeping guide and electrical contractor bookkeeping guide cover what those trades need.

And if you'd rather have all of this done for you, Poof Managed for Trades is built for exactly this: per-job P&L with every monthly close, built from your existing Jobber or Housecall Pro data, reviewed by a former controller — no rekeying by you.

Frequently asked questions

How do you calculate job costing for an HVAC business?

Capture four buckets against every job, then subtract them from the invoice total. Direct labor at a burdened rate, materials and equipment at cost, truck cost allocated by mileage or truck-hours, and overhead allocated by labor hours. Revenue less the first three is gross job profit — the number you price from. Subtract allocated overhead and you get net job profit — the number you make portfolio decisions from. Both matter, and they frequently disagree.

What is a burdened labor rate and why does it matter?

It's the tech's real cost to you: base wage plus payroll taxes, workers' comp, and benefits — typically 1.3 to 1.4 times the base hourly wage. A tech you pay $32 an hour actually costs $42 to $48. Job-costing at $32 makes every job look more profitable than it is, and the error compounds across every bid you base on those numbers.

Should overhead be included in job costing?

Yes. Leave it out and every job looks profitable, because dispatcher salary, shop rent, software, insurance, and marketing exist whether or not you run a given job. The standard method is monthly overhead divided by billable tech-hours, applied to each job by its actual labor hours. If your overhead is $42,000 a month across 1,400 billable tech-hours, that's $30 per tech-hour, so an 8-hour install absorbs $240. Recalculate the rate quarterly — it drifts as the shop grows.

Can QuickBooks do per-job costing for an HVAC shop?

Partly. QuickBooks Online Plus and Advanced include a projects feature that can hold job-level cost, but it only works if every transaction gets tagged to a job — and Jobber and QuickBooks don't natively share job-level cost data, so labor and materials live in one system while bank activity lives in the other. Most shops set projects up and abandon it within a quarter because the tagging is a chore nobody owns.

What is a good net profit margin on an HVAC job?

It depends far more on job type than most owners expect, which is the reason to measure rather than assume. In the worked examples in this guide, a heat pump install returns 50.7% gross and 47.1% net, while an annual tune-up returns a higher 54% gross but only 34% net — because its labor hours are dense relative to the invoice. Comparing gross margin alone would rank those two jobs in the wrong order.

Ready to Automate Your Bookkeeping?

See how Poof can save you hours every week with AI-powered bookkeeping.

Start Your Free Trial