How to Build an Estimate From a Cost Model
Why this matters
An estimate written as one number is unauditable. When it comes back over, you have exactly one thing to correct, so you correct it, and the following quarter you correct it again in the other direction. A shop can spend years doing that and never converge, because the number being moved is a sum of five or six independent quantities and only one of them was ever wrong.
An estimate built from a model is a set of separate claims. Each input is a hypothesis your own actuals can falsify on its own. That is the entire point: not that the model is more accurate on day one (it usually is not), but that it is correctable, and a correctable estimate beats an accurate one inside three cycles.
This article covers the assembly. What the underlying cost layers are, and how to derive a burdened labor rate, are separate siblings; see the references.
Step 1: Pick the model's unit before you pick any number
Decide what one unit of this model produces: one job of a type, one fixture, one linear unit installed, one service visit. Every input then gets stated per that unit and nothing gets stated per anything else.
This sounds like bookkeeping and it is the step that most often sinks a model. A model carrying productive hours per fixture, travel per job, and disposal per load is three models wearing one coat, and it cannot be compared to actuals without a conversion someone will get wrong. Pick the unit that matches how your actuals are recorded: if your time entries land against a job, the job is your unit, and per-fixture rates get multiplied up inside the model.
Step 2: List the inputs as separate lines, never as one blended rate
Minimum viable model for field work:
| Input | Stated as | Where it comes from |
|---|---|---|
| Productive hours | Crew-hours per unit | Median of your own closed jobs of that type |
| On-site non-productive hours | Crew-hours per mobilization | Measured once, reused |
| Travel hours | Crew-hours per round trip | Your own routing history for the service area |
| Material quantity | Installed quantity from take-off | Take-off |
| Material waste | Percent of installed quantity | Your own purchase-to-install reconciliation |
| Rework and lost time | Percent of the labor subtotal | Your own callback and stand-down history |
| Direct job costs | Per unit, listed by name | Actual charges: permits, disposal, rentals, subs |
| Contingency | Percent, set by assumption strength | Judgment, but recorded |
The temptation is to skip half of this with one all-in hourly figure that "covers everything." That figure is a weighted average of a specific past job mix, so it silently reprices your model every time the mix changes, and when a job runs over you cannot tell whether the hours were wrong or the coverage inside the rate was.
Step 3: Put productive hours in, not clock hours
Productive hours means hands on the work. Everything else - staging, protection, cleanup, the walk from the truck, the customer conversation, the supply run - is either an on-site non-productive line or a travel line, and it gets its own number.
Two reasons this split is load-bearing. First, these quantities scale differently: productive hours scale with the size of the work while mobilization scales with the number of trips, so a job split across two visits looks identical in a blended model and is not. Second, they are correctable by different actions: productive hours move with method and training, mobilization moves with scheduling and truck stock.
Take productive hours from the median of your own closed jobs of the type, not the mean and not the best run. Published or remembered production rates are a starting point only when you have no history, and they are systematically optimistic because they describe the work, not the day the work happens in.
Step 4: Apply load factors in a fixed order, once each
Order matters when factors are multiplicative, and applying one twice is the most common quiet error in a homemade model. Fix the sequence and write it on the model:
- Sum the raw hour lines (productive, non-productive, travel).
- Apply the rework and lost-time allowance to that subtotal.
- Apply contingency to the loaded subtotal.
- Convert hours to cost using the burdened rate, once, at the end.
The double-count trap: a shop measures its on-site non-productive time, adds it as a line, then also applies an all-in load factor derived from the gap between billed and paid hours, which already contained that same non-productive time. The model now carries mobilization twice and the shop prices itself out of competitive work while believing its numbers are conservative. Before you trust a new model, take one closed job and check that each hour of real time appears in exactly one line.
Step 5: Keep contingency separate from margin
Contingency covers uncertainty in the estimate. Margin is the shop's return for doing the work. They are different quantities, they respond to different conditions, and they must be separate lines.
Set contingency from the strength of your assumptions on that specific job, not as a habit. A defensible ladder to start from and tune: near zero on a repeat job at a site you have worked, in the range of 5 to 10 percent on a job you scoped in person with a normal number of open questions, and 15 percent or more when you bid from photos or a phone description. Any bid needing more than about 20 percent contingency to feel safe is telling you the scope is not defined enough to price as a fixed number, and the honest move is a range, a not-to-exceed with a re-quote trigger, or time and materials.
Blend the two and you lose both. You cannot lower a price by dropping contingency to win a job you understand well, because you no longer know how much of the number is contingency. And you cannot tell whether a thin year came from underpricing or from repeatedly spending contingency you should not have needed.
Step 6: Price on top of the model, do not price inside it
Build the model to your honest cost. Then make the pricing decision as a visible, separate step: this is the cost, this is the target margin, this is the number that goes out, and here is why it differs from cost plus target if it does.
This prevents competitive pressure leaking backward into the inputs. An estimator who needs a lower number and trims productive hours has not just discounted the job, they have corrupted the input for every future job of that type, and the next review will read the resulting overrun as an estimating miss. Discount the price if you choose to. Never discount the model.
Step 7: Store the model with the estimate, not just the total
Save every input value with the job record. A stored total lets you compute one variance. A stored model lets you compute six, and five of them will usually be fine, which is the finding that saves you from correcting the wrong thing.
A worked build, input by input
A repeating job type. Unit: one job.
The model. Productive hours 12.0 crew-hours, from the median of 19 closed jobs. On-site non-productive 1.5 crew-hours per mobilization, one mobilization assumed. Travel 0.9 crew-hours for one round trip. Raw subtotal: 14.4 crew-hours.
Rework and lost-time allowance at 6 percent of the raw subtotal adds 0.9 hours, giving 15.3. Contingency at 8 percent of that adds 1.2 hours, giving 16.5 crew-hours in the quote. Material: 100 units installed from take-off, waste factor 14 percent of installed quantity, so 114 units purchased. Direct costs: one disposal load, one permit.
The actuals. Productive 13.1 crew-hours. On-site non-productive 3.0. Travel 1.8. Total 17.9 crew-hours. Material: 116 purchased, 101 installed. One disposal load, one permit.
Read against the raw subtotal first. 17.9 actual against 14.4 raw is 3.5 hours over, about 24 percent over the raw subtotal. Against the 16.5 quoted it is 1.4 hours over, about 8.5 percent over the quote. Both answer different questions: the first tells you how the model performed, the second how the job performed against what the customer was told.
Now input by input. Productive: 13.1 against 12.0, so 1.1 hours over that input, about 9 percent over it. On-site non-productive: 3.0 against 1.5, exactly double, one extra mobilization cycle. Travel: 1.8 against 0.9, also exactly double, a second round trip.
What that says. 2.4 of the 3.5 hours over, roughly 69 percent of the overrun, trace to a single cause: the job took two trips instead of one. Productive hours, the input everybody reaches for first, were 9 percent light, which for this shop sits inside its normal spread and is not a correction.
A total-only review would have seen 24 percent over the raw model and moved productive hours from 12.0 to something like 15. That change would have made the model wrong on every single-trip job of the type, which is most of them, and it would not have fixed the two-trip jobs at all.
The allowances did their job. The 0.9 hour rework allowance plus the 1.2 hour contingency gave 2.1 hours of buffer against a 3.5 hour overrun, absorbing about 60 percent of it. That is contingency working as designed, and it is only visible as such because contingency was a separate line.
Material held. 116 purchased against 101 installed is 15 units of waste, about 14.9 percent of installed quantity, against a modeled 14 percent. Within a point on a single job, so no action.
The correction. Not a number change at all. The model gains a mobilization count input, defaulting to 1, with a scoping question that sets it to 2 when the work cannot run continuously. When it is set to 2, the model adds one more non-productive cycle and one more round trip, so 1.5 plus 0.9 equals 2.4 hours, which is exactly the mobilization gap this job produced. The job's total gap was 3.5 hours; this input accounts for 2.4 of it, about 69 percent.
What changes the answer
No usable history. Build the model anyway, seed productive hours from published production rates or a peer estimate, mark that input low-confidence, and raise contingency to match. The model's value then is not accuracy, it is that after four jobs you will know which input to fix. Bid the first few on time and materials.
Crew size changes. Crew-hours and clock hours diverge once you add people, and the divergence is not linear because coordination and shared setup change. Keep the model in crew-hours, and if your history is thin at a crew size you rarely run, treat that size as a separate low-confidence case rather than scaling.
A job priced per unit rather than per job. Fixed per-job costs, mobilization especially, do not scale with unit count. A per-unit model applied to a job with a third of the usual unit count will be light, because it spread one mobilization across too few units. Carry the fixed lines as fixed and scale only the variable ones.
Subcontracted scope. A sub's quoted amount is a direct cost line at its quoted value, not something you model. Your model still carries your own coordination and supervision hours for that scope, which is the line most shops leave out entirely.
How to verify the model, not just the total
- Reconcile one closed job hour by hour. Every hour of real time should land in exactly one model line, with nothing double-counted and nothing missing. This catches the load-factor double-count and it is the single highest-value check on a new model.
- Check each input against its own history, separately. An input that has never been within a reasonable band of actuals is not a bad estimate, it is a broken input, and it needs a different source rather than a nudge.
- Watch for input drift with no dated change. If productive hours in the model no longer match the median of the last twenty closed jobs, someone has been trimming it to hit prices. Every input change gets a date and a reason.
- Confirm contingency is being spent, not banked. If contingency is never consumed on any job, it is not contingency, it is undisclosed margin, and you are losing bids you should be winning. If it is consumed on nearly every job, it is not contingency either, it is a missing input, and the right move is to find and name what it is covering.
References
- U.S. Small Business Administration (SBA), pricing and cost estimation guidance for small business
- Trade-standard practice for detailed unit-cost estimating and basis-of-estimate documentation
- See related: Knowing Your True Cost Before You Set a Price, Fully Burdened Labor Rate Calculation, The Materials Waste Factor Worth Measuring, The Hidden Costs That Never Make It Into an Estimate