How to Set Up Construction Cost Codes Your Crews Will Actually Use
Most job costing fails at the timesheet, not the software. How to build a cost code list sized for the foreman filling it in, matched to your estimate, and short enough to be coded right.
It's month end and the labour report is in. Half the hours on the job landed in a code called "general labour." Another chunk went to a concrete code on a week when the crew was doing nothing but excavation. The report says the job is fine. Nobody on site believes it, and nobody in the office can prove otherwise, because the numbers stopped meaning anything the moment they were coded.
This is the quiet failure of most job costing systems. The software works. The timesheets get filled in. The reports print. But the codes the hours land in are wrong often enough that the whole exercise produces something that looks like data and behaves like fiction. And it almost always traces back to the same root cause: the cost code list was designed for the accountant, not for the foreman filling in a timesheet at 4:30 in the afternoon.
The two ways a code list fails
Cost code lists fail in opposite directions, and both failures look like success for a while.
Too coarse. Everything on the job maps to five or six buckets: labour, materials, equipment, subs, other. Coding is easy and always "correct," which is exactly the problem. When the job loses money, the report tells you labour was over. It cannot tell you whether you lost it on the footings, the backfill, or the three weeks of rework in April. You have accurate totals and zero explanations.
Too granular. Somebody, often during an ERP implementation, decides that more detail means more control, and the list balloons to 80 or 120 codes. It works for about two weeks. Then the foreman, entering time for an eight-person crew from memory at the end of a long day, starts scrolling, picks the first code that looks plausible, and moves on. The reports now show precise-looking numbers that are quietly wrong. This is worse than coarse coding, because coarse data announces its own limits. Wrong-but-precise data gets trusted.
Of the two, the second failure is more expensive, and it's the one that comes from good intentions.
Design for the person doing the coding
Here is the test that matters more than any template: can your foreman hold the day's codes in their head? Not the whole list. The five to ten codes that apply to what the crew actually did this week, named in language that matches how the crew would describe the work.
"Form and pour footings" passes that test. "03 30 00 Cast-in-Place Concrete" does not, even though they describe the same work. If the person coding time has to translate from what happened on site into accounting language, some of those translations will be wrong, and you will never know which ones.
This is also why copying MasterFormat wholesale is usually a mistake for small and mid-sized contractors. MasterFormat is a specification system built to organize documents on large commercial projects. It's a fine reference for naming conventions. As a live coding list for a 15-person civil contractor, it's a scrolling exercise that ends in miscoding.
Build the list from your estimate, not from a template
The real purpose of cost codes is not tidy reports. It's the feedback loop: you priced the work a certain way, the work cost what it cost, and the comparison between those two numbers is how your next bid gets sharper. That loop only closes if the codes match the way you estimate.
So start there. Pull up your last three estimates and look at the line items you actually priced. Each cost code should be a piece of work that meets three tests:
- A crew does it for at least a shift at a time. If two activities always happen together in the same hour, they're one code. Nobody can honestly split an hour of time three ways.
- You would price it as its own line next time. If it appears in your estimates, it needs a code, or you'll never check the estimate against reality.
- You would manage it differently if it went over. If two codes would trigger the same conversation and the same fix, merge them. Detail you'll never act on is just noise with a decimal point.
For most small and mid-sized contractors, that lands somewhere between 15 and 30 active codes on a typical job. Not 6, not 80. The exact number matters less than the discipline behind it: every code earns its place by feeding a decision.
Keep a company master list so the same work carries the same code on every job, then activate only the relevant subset per project. Three jobs from now, that consistency is what turns your job costing into your own unit-rate database, built from your crews, your equipment, and your conditions. On coastal BC work, where weather and tide windows push labour productivity around in ways no published rate table captures, your own history is the only reference that's worth anything at bid time.
Two more structural rules that pay for themselves. First, give change order work its own codes or its own tracking dimension, separate from base contract work. Mixing them hides overruns inside extras and extras inside overruns, and it makes the change order log impossible to reconcile. Second, retire codes that never get used. A code that has sat empty for two jobs is a scrolling hazard, not an option.
Getting the field to actually code correctly
A good list is necessary but not sufficient. The field codes correctly when three things are true.
The codes are where the work is. Print the job's active codes, in plain language, on the daily timecard or in the timesheet app, in the order the work happens. A laminated one-pager in the truck and on the trailer wall is old-school and still works. If entering the right code takes more effort than entering the wrong one, the wrong one wins.
Somebody looks at the coding weekly, not monthly. A five-minute scan of last week's hours catches the crew that dumped everything into one code while the memory is fresh enough to fix. At month end it's archaeology. This review is also where the office earns the field's effort: a quick call that starts with "did you really pour for 60 hours last week, or did some of that belong to stripping?" tells the foreman someone reads what they write.
The data visibly comes back to the field. The fastest way to kill coding discipline is to collect numbers that disappear into the office forever. The fastest way to build it is to show the foreman their own production rate, use the coded hours to back up a change order, or walk through estimate-versus-actual at the end of the job. People maintain data they see being used. This is the same principle that makes daily reports worth keeping, and it fails the same way when it's ignored.
The tradeoff, stated honestly
Coding discipline costs something real: foreman time at the end of every shift, office time every week, and some friction while the crews adjust. A contractor doing three or four straightforward jobs a year with steady crews might reasonably decide that a coarse system plus an experienced gut is good enough. That's a defensible choice as long as it's a choice, made knowing that every bid is being priced from memory instead of history.
What isn't defensible is the middle state most companies drift into: paying for detailed job costing software, burdening the field with a long code list, and getting reports nobody trusts. That's the cost of precision with none of the benefit. If that's where your reports are, fix the list before you blame the software, and fix who reviews the coding before you blame the crews.
At Manara we help contractors design cost structures like this and wire them into whatever systems they already run, from spreadsheets to Acumatica. We don't sell job costing software, so we have no stake in the answer being complicated. If your month-end reports look precise and feel wrong, a free discovery call is a reasonable place to start untangling why.
Dealing with something like this?
Book a free 30-minute discovery call. No pitch, practical next steps either way.
Book a call