The principle: income and COGS in matching pairs
The whole trick is symmetry. Each revenue stream gets its own income account, and each gets matching cost-of-goods-sold accounts, so gross margin per stream falls out of the P&L automatically, every month, without a spreadsheet. When someone asks 'are we making money on installs?', the report answers.
Income accounts for an HVAC company
- Installation Revenue, residential replacements/changeouts (split new-construction into its own account if you do it; different margin, different cash rhythm)
- Service & Repair Revenue, demand calls, diagnostics, repairs
- Maintenance Agreement Revenue, recognized as visits are delivered (the deferred revenue mechanics live on the balance sheet; see below)
- Indoor Air Quality / Add-On Revenue, filtration, humidifiers, duct work if it's a real line for you
- Commercial Revenue, separate if you serve both markets; blending resi and commercial hides both
COGS accounts (the matching half)
- Equipment, condensers, furnaces, air handlers (the big boxes, kept apart from parts so install margin is honest)
- Parts & Materials, everything from the supply house that isn't equipment
- Direct Labor, field techs' wages + payroll taxes + workers' comp, ideally split install vs service via payroll mapping
- Subcontractors, crane lifts, electrical subs, insulation
- Permits & Inspections
- Equipment Rental & Disposal, recovery, refrigerant handling, dump fees
- Financing Fees, dealer fees on consumer financing promotions, which are a real cost of install revenue and almost never tracked
The balance sheet accounts HVAC actually needs
- Customer Deposits (liability), install deposits held until the job completes; booking them as income on receipt is the classic HVAC error
- Deferred Maintenance Revenue (liability), agreement money collected up front, recognized per visit; this is what makes spring's agreement-selling blitz not distort April's P&L
- Inventory, if you stock equipment; truck stock can stay expensed if modest, tracked if material
- Warranty Reserve, if you're big enough for callbacks to be a real number, accrue for them
Overhead: keep it boring, keep it out of COGS
Everything not tied to producing jobs stays below the gross margin line: office wages, rent, marketing, software, insurance (general business, not the liability tied to field labor, which belongs in labor burden), vehicles (or allocate to jobs if you want sharper costing), training, uniforms. The test for every expense: 'if we ran zero jobs this month, would this cost exist?' Yes → overhead. No → COGS.
What this structure gives you monthly
- Gross margin by line: installs at 38%, service at 55%, agreements at 60%, now pricing, marketing, and hiring decisions have numbers
- Labor efficiency: direct labor as a % of its revenue stream, the number that catches overtime creep and underbilled service calls
- Seasonal truth: maintenance revenue recognized evenly exposes what summer must bank for February
Class or location tracking in QuickBooks Online adds the second dimension, by crew, by market, by branch, and pairs with job-level costing for the full picture: Job Costing in QuickBooks Online: The Contractor Setup That Actually Works .
Migrating without wrecking history
Don't delete old accounts mid-year, build the new structure, map the old accounts into it (merge where names match, deactivate what's dead), and cut over at a month boundary with prior periods locked. Or have it done as part of a cleanup: restructuring the chart is standard first-month work when we take on an HVAC client, because every report after depends on it. HVAC
Frequently asked questions
How many accounts is too many?
If a category won't change a decision, it's clutter. The structure above runs 40–60 accounts, enough to see the business, few enough that categorization stays consistent. Resist the urge to give every part type its own account; that's what items and job costing are for.
Does this work in QuickBooks Online or do I need desktop?
QBO handles all of it, chart, classes, deferred revenue via recurring journal entries, and the field-software integrations (ServiceTitan, Housecall Pro) that post into this structure cleanly when mapped once.