You billed more last year than the year before. You added two accounts, hired three cleaners, worked more nights than you want to count, and your checking balance on December 31 looked almost identical to the year before.
That gap between growth and cash is almost never a collections problem. It is an overhead problem that started at the bid table, months before the first shift was ever scheduled.
Calculate overhead by adding every cost that is not direct job labor or job supplies into an annual pool, then dividing that pool by your total annual direct labor hours. The result is an overhead cost per labor hour. Add it to loaded labor and supplies on every quote before you apply profit.
Most cleaning quotes get labor roughly right. Production rates are well documented, wages are visible, and everyone checks their math on hours. The leak is downstream of that, in the part of the spreadsheet where somebody typed a percentage three years ago and nobody has touched it since.
What actually counts as overhead in a cleaning business?
Overhead is every dollar you spend that does not change when you win or lose one specific account. Your insurance renewal does not drop because a tenant moved out. Your office manager does not get paid less in a slow February.
The most common classification error in janitorial bidding is treating labor burden as overhead. Payroll taxes, workers compensation and paid time off ride directly with the hours worked on that site, so they belong in loaded labor, not in the overhead pool. Put them in the wrong bucket and you will double count on some bids and undercount on others.
| Cost | Where it belongs in the quote | Why |
|---|---|---|
| Cleaner wages for that site | Direct labor | Varies hour for hour with the account |
| Employer FICA, FUTA, SUTA, workers comp, PTO accrual | Labor burden, added to direct labor | Calculated as a percentage of the wages on that job |
| Chemicals, liners, paper, pads consumed on site | Direct supplies | Consumption scales with the square footage cleaned |
| Night supervisor covering nine buildings | Overhead | Cost follows the number of sites, not one account |
| Owner time spent bidding, hiring and putting out fires | Overhead | Real cost even when nobody writes a check for it |
| Office rent, phones, software, accounting, licenses | Overhead | Fixed regardless of tonight's schedule |
| General liability, commercial auto, janitorial bond | Overhead | Company-wide policy, allocated across all work |
| Callbacks, rework nights, unbilled make-goods | Overhead (and the most invisible line of all) | Nobody codes these to a job, so they never appear in a bid |
How much does the flat-percentage habit cost on one account?
Here is the autopsy. All figures below are illustrative and the assumptions are stated so you can swap in your own.
Assume a company with 22 cleaners and 38,000 billable direct labor hours a year. Pull the P&L and everything that is not job labor, labor burden or job supplies lands in the overhead pool.
| Overhead line item (illustrative) | Annual |
|---|---|
| Owner compensation, non-cleaning portion | $60,000 |
| Office and admin salary | $42,000 |
| Field supervisor, non-billable | $28,000 |
| Vehicles: insurance, fuel, maintenance | $18,000 |
| Rent and storage | $10,800 |
| General liability, auto, bond | $9,600 |
| Marketing and sales | $7,200 |
| Software, phones, internet | $6,000 |
| Accounting, legal, licenses | $4,800 |
| Uniforms, training, miscellaneous | $2,600 |
| Total overhead pool | $189,000 |
$189,000 divided by 38,000 direct labor hours gives an overhead recovery rate of $4.97 per direct labor hour. That number is the whole point of the exercise, and most operators have never calculated it.
The bid: Meridian Office Park, 42,000 sq ft, five nights a week
Assume a production rate of 3,200 cleanable square feet per hour for mixed office space, which puts the building at 13.1 hours per night. That is 65.5 hours a week, or 3,406 hours a year.
At a $16.00 base wage with a 22% burden, loaded labor is $19.52 per hour. Multiply by 3,406 hours and site labor lands at $66,485 a year. Add $3,000 in consumables and $1,200 in equipment allocation for $4,200 in supplies.
Now apply overhead properly: 3,406 hours times $4.97 equals $16,928. Total annual cost is $87,613. At a 12% target net margin, the price is $87,613 divided by 0.88, which is $99,560 a year, or $8,297 a month.
Now price it the way it usually gets priced. Labor plus supplies is $70,685. Add the habitual 20% for "overhead and profit" and you get $84,822 a year, or $7,068 a month. That number feels competitive. It feels like a win.
The gap between the correctly priced bid and the habit bid is $14,738 a year on one building. Repeat that across a portfolio and you have a complete explanation for why revenue climbs while cash does not.
Why a flat percentage of revenue breaks the moment your mix changes
A flat markup assumes overhead consumption is proportional to price. It is not. Overhead in a cleaning company is consumed mostly by hours and by sites.
A 6,000 sq ft medical office cleaned five nights a week eats supervision, drive time, scheduling attention, supply drops and client phone calls almost as heavily as a 40,000 sq ft account. Price it as a percentage of its small revenue and it contributes almost nothing to the pool it is draining.
The same distortion runs the other way on high-supply, low-labor work. Add a floor restoration project with heavy material cost and a percentage markup silently inflates the overhead you charge, because finish and pads do not consume dispatch time.
Should you allocate overhead by labor hour, by revenue, or by site?
- Direct labor hours: the default for recurring janitorial. Your overhead is dominated by people who manage people, so hours are the honest driver.
- Percentage of revenue: acceptable only if every account you service has a near-identical labor-to-material ratio. Most portfolios do not.
- Per site, per month: useful as a second pool for costs that follow building count rather than hours: supervision visits, vehicle miles, supply deliveries, account management.
The two-pool method is worth the extra half hour. Split the overhead pool into an hour-driven portion and a site-driven portion, divide each by its own base, and small accounts stop hiding behind big ones. Using the numbers above, if $54,000 of that $189,000 is genuinely site-driven across 30 buildings, that is $150 per site per month that every bid must carry before the hourly rate is even applied.
Warning signs your quotes are under-absorbing overhead
Under-absorption does not announce itself. It shows up as symptoms that look like other problems, which is why operators chase the wrong fix for years.
- You win more bids than you lose. A high win rate feels like sales strength. In competitive janitorial markets it more often means your number is the lowest for a reason nobody has explained to you yet.
- Your own pay is the plug figure. If what you take home is whatever is left after everyone else is paid, your overhead pool is missing its largest line item.
- Growth requires cash injections. Every new account triggers a draw on the line of credit for startup supplies and the first payroll cycle before the first invoice clears.
- You added a supervisor and nobody re-priced anything. The overhead pool grew by $50,000 and the recovery rate stayed frozen at whatever it was in 2022.
- You cannot state your fully loaded cost per labor hour from memory. Ask yourself right now. If the answer takes more than five seconds, no bid you wrote this year was built on it.
- Small accounts feel disproportionately annoying. That irritation is data. It is telling you the account consumes management time it is not paying for.
- Callbacks never appear anywhere. If a crew goes back on a Saturday to redo restrooms and nothing is recorded, that cost is real and invisible at the same time.
- The markup cell in your quote sheet is hardcoded. Open the file. If "20%" is typed in rather than calculated, you found the origin of the leak.
How to calculate your overhead rate in five steps
- Pull twelve months of P&L data. Trailing twelve months, not a calendar year, so seasonality does not distort it.
- Strip out direct costs. Remove job labor, labor burden and job supplies. Whatever remains is your overhead pool. Add back any owner labor that is not cleaning, at a market salary, if you have been paying yourself in distributions.
- Count your actual direct labor hours. Use clock data, not scheduled hours. The two are rarely the same, and using scheduled hours understates your rate.
- Divide. Overhead pool divided by direct labor hours equals your overhead recovery rate per hour. Optionally split into hour-driven and site-driven pools as described above.
- Build it into the quote before profit. Loaded labor plus supplies plus overhead equals cost. Then divide cost by (1 minus your target net margin). Do not multiply by the margin, that is a markup and it produces a smaller number than you think.
On step five, the arithmetic matters. Cost of $87,613 multiplied by 1.12 is $98,127, which yields a 10.7% margin, not 12%. Dividing by 0.88 gives $99,560 and an actual 12%. Small error, repeated on every bid, for years.
What to do about accounts you have already underpriced
Recalculating your rate will surface accounts that are underwater today. Do not send eight increase letters in one week.
Rank them by dollars of annual under-recovery, not by percentage. Start with the worst one, and go in with specifics: the hours actually worked versus the hours bid, the added scope that crept in since signing, the wage floor in your market. Clients argue with "we need more money." They argue far less with a documented hour count.
For the accounts you cannot re-price mid-term, adjust scope instead. Move a five-night carpet vacuum to three nights with detail vacuuming on the other two, or renegotiate consumables to a pass-through. Then set a calendar reminder 90 days before renewal so the correct number goes out on time.
Prevention checklist: keeping overhead recovery honest
- Recalculate the overhead rate every quarter, and immediately after any hire that is not a cleaner.
- Verify direct labor hours against actual clock records, not the schedule, before dividing.
- Keep owner compensation in the pool at a market salary, even in years you take less.
- Confirm that payroll taxes, workers comp and PTO sit in labor burden and appear nowhere in the overhead pool.
- Code callbacks and rework nights to a job so they stop being free.
- Re-run the rate whenever your insurance, vehicle count or software stack changes materially.
- Check that every bid template pulls the overhead rate from one cell, and that no one can type over it.
- Apply a site-driven overhead charge to small accounts so they carry their share of supervision and drive time.
- Compare bid hours to actual hours on every account at 60 to 90 days after startup, and flag anything over 10% off.
- Divide by (1 minus target margin) on every quote. Never multiply by the margin.
- Track your win rate. A sharp climb usually means the market is telling you your price dropped below everyone else's cost.
- Set a renewal reminder for every contract 90 days out, with the current overhead rate attached.
Where CleanTrack360 fits
The overhead rate is only as good as the hour count underneath it, and that is the number most operators guess at. CleanTrack360 captures geofenced GPS clock-in and clock-out in the phone browser, so the direct labor hours you divide by are the hours crews actually worked, not the hours you scheduled. Reports export to CSV, which means you can pull a trailing twelve months of hours by location and drop them straight into your overhead calculation.
On the bid side, the quoting calculator prices on square footage, frequency, labor and supplies, and branded PDF proposals with open tracking let you see whether a prospect actually read the number before they push back on it. Quality inspections with photo evidence and automatic scoring also help you catch the rework nights that quietly inflate your overhead pool. Plans start at $99 per month for up to 5 team members, with a 14-day free trial and no credit card required.