Ask a roofing contractor which of last month's jobs made the most money and you will usually get an answer. Ask how they know, and the answer gets quieter.
Most companies can tell you what a job was sold for. Far fewer can tell you what it cost, and the gap between those two numbers is not a spreadsheet problem. It is that the costs arrive at different times, from different people, in different formats, long after the crew has moved on to the next roof.
The tear-off crew finished in a day. The supplement came through three weeks later. The gutter sub invoiced in month two. By the time all of it has landed, nobody is looking at that job any more, and the only signal left is whether the bank account went up.
The Bank Balance Is Not a Costing System
It nets everything together. A great month can absorb two bad jobs and you will never know which two. A slow quarter looks like a sales problem when it was a production problem, and the company responds by hiring another salesperson to feed a machine that loses money on delivery.
There are really only three ways companies answer the question, and they differ mostly in when you find out.
Three ways a roofing company answers "did that job make money?"
| The bank balance | A spreadsheet per job | A cost ledger on the job | |
|---|---|---|---|
| When you find out | Whenever the account looks thin | When somebody updates it, which is after the job | As each cost is posted, while the job is still open |
| What it tells you about one job | Nothing. It nets every job together. | Whatever was typed in, if it was typed in | Material, labour, subs, equipment, permits and overhead, each as its own line |
| Where the estimate fits | It does not | Usually pasted in once and never compared again | Held beside actuals, so the variance is a number and not an argument |
| Who can see it | The owner | Whoever has the file open | Anyone with access to the job, on the job |
| What happens to the crew's numbers | They never enter it | They are remembered, then rounded | Hours and rate are stored on the entry that used them |
| How it fails | A bad year explains itself as a slow year | Two versions of the file disagree and both are wrong | A cost nobody posts is a cost the job never shows |
The third column's failure is the one worth reading twice. A ledger is only as honest as the entries reaching it, and the ones that do not arrive by themselves are the ones that decide whether the margin on your screen is real.
Notice that the third approach still fails, and read how. A ledger is only as good as the entries that reach it. Which means the interesting question is not whether your software has job costing. It is which costs arrive on their own and which ones depend on somebody remembering.
Which Costs Arrive by Themselves
This is the part most buying decisions get wrong, because a demo shows a finished dashboard and the finished dashboard does not tell you who filled it in.
Materials
The one category with a real automated path. A purchase order can be posted to every job its materials were allocated to, and the posting checks first whether that PO has already been written, so a retry is safe.
Two things to keep straight. It runs when something calls it, not the moment a PO is marked received, so somebody has to close that loop. And if one PO covers several jobs, read what lands on each of them before you trust the totals.
Labour
Posted by hand. There is no payroll integration writing crew cost onto a job, and a completed work order does not post its own hours.
That is worth saying plainly because labour is usually the second largest number on a roof and the one most likely to be missing. A job showing a strong margin with no labour entries on it is not a profitable job, it is an incomplete one.
Subs, equipment, permits
All posted by hand, all with a reference field for the vendor invoice number. The categories exist so they do not get swept into materials, which is what happens when a system only has one bucket.
The discipline that makes this work is unglamorous: post the cost the day the invoice arrives, not the day you reconcile the month.
Overhead
Posted by hand as an allocation. There is no rule engine spreading your monthly overhead across open jobs by revenue or by days.
Which means the margin on a single job is a gross margin unless you have chosen an allocation method and applied it consistently. Comparing one job's margin to another's is only fair if both were treated the same way.
Be honest with yourself about the labour tab in particular. Labour is usually the second largest cost on a roof and it is the one with no automated path into the ledger anywhere in this category of software. A job showing a strong margin with no labour posted against it is not a profitable job. It is an unfinished record wearing a profitable job's clothes.
See Job Costing on Your Own Jobs
BetterRoofingPro keeps the estimate, the purchase orders, the cost ledger and the profitability summary on the same job record, so the margin you are looking at is built from entries you can click into.
Closing One Job Honestly
Do not try to fix a year of history. Take one job that is finishing this week and run it properly end to end. The sequence matters more than the software.
Closing out one job honestly, start to finish
- Approve the estimate, and let it become the baseline The approved estimate's material and labour figures become the job's estimated costs. Everything after this is measured against that line, so an estimate nobody approved leaves you comparing actuals to nothing.
- Know what the contract amount is reading from Revenue comes from the job's final value, falling back to its estimated value, falling back to the estimate total. A job whose final value was never set is being measured against a number that was only ever a proposal.
- Post the material costs from the purchase order There is a posting path that reads a PO's line items, finds the jobs its materials were allocated to, and writes a material entry. It is idempotent: it checks whether that PO has already been posted before writing, so running it twice does not double the cost.
- Post labour with the hours on it A labour entry carries hours and an hourly rate alongside the amount. Entering only a lump sum works and tells you nothing later about whether the crew took longer than the estimate assumed.
- Post the subs, the equipment and the permits as they land Each with the invoice or reference number in the entry. These are the costs that arrive by email weeks later, and the ones most likely to be remembered as smaller than they were.
- Read the variance, not just the margin Cost variance is actual total cost minus estimated total cost. A healthy margin with a large variance means you underbid and got rescued by something else, which will not happen twice.
- Compare invoiced against collected before you celebrate The summary tracks both what was invoiced and what was actually received. Profit on an uncollected invoice is a receivable, and roofing companies do not fail from thin margins nearly as often as they fail from money that never arrived.
Two steps in there deserve more attention than they usually get.
Know what your contract amount is reading from. Revenue on a job typically falls back through a chain: the final value if somebody set one, otherwise the estimated value, otherwise the estimate total. That chain is sensible and it is also a trap. A job where nobody ever recorded the final contracted amount is being measured against a proposal, and every change order, supplement and concession after signing is invisible to the margin. The number looks authoritative because it is displayed to two decimal places.
Read the variance, not just the margin. Margin tells you what happened. Cost variance, actual cost against what you estimated, tells you whether your estimating is any good. A job can land on a healthy margin while running well over its estimated cost, rescued by a generous contract or a supplement that happened to come through. That is not a repeatable outcome, and a company that only watches margin will bid the next ten jobs exactly the same way.
The Four Numbers Worth Watching
Once costs are landing on jobs reliably, you do not need a finance department to read them.
- Cost variance by job. Consistently over on materials means your takeoffs or your waste factor are wrong. Consistently over on labour means your production assumptions are.
- Variance by job type. Steep and complex work often carries the whole loss while simple tear-offs subsidise it. Most contractors discover they have been buying the jobs they are worst at.
- Margin spread, not average margin. An average is comfortable and tells you nothing. Two jobs at very different margins average into a number that describes neither.
- Invoiced against collected. Profit sitting in an unpaid invoice is not profit yet. More roofing companies get into trouble here than on thin margins.
Start With One Job
Not a rollout. Not a policy. One job, this week, costed properly, including the labour nobody usually posts and the sub invoice that has not arrived yet.
Then do the next one, and the one after. Within a month you will have enough to see a pattern, and the pattern is almost never the one people expect. The job everybody remembered as the bad one usually was not, and the comfortable repeat work for a favourite customer is usually where the margin quietly went.
You cannot bid better without knowing what the last ones actually cost. Everything else in estimating is guesswork with confident formatting.
Find Out What Your Jobs Actually Cost
BetterRoofingPro tracks material, labour, subcontractor and overhead costs against every job, alongside the estimate that set the baseline. Schedule a demo to see it on your own numbers.