What it is
Estimates price labor as hours per unit of work, such as hours per square foot of slab. In the field, crews record hours by cost code and foremen report quantities installed.
Earned hours are the hours the installed quantity was worth under the estimate. Comparing them with actual hours gives a productivity factor.
Why operators track it
- Labor is hard to predict. Material prices are usually fixed by purchase order; labor depends on the field.
- Earlier than cost variance. Hours and quantities can be reported daily or weekly; the cost report lags.
- Better forecasts. The current rate on a cost code is a basis for the remaining hours forecast.
- Better bids. Actual rates on finished jobs feed future estimates.
How it is calculated
Productivity factor = earned hours ÷ actual hours
- Earned hours = budgeted hours × (quantity installed ÷ budgeted quantity).
- Above 1.0 is better than estimate; below 1.0 is worse.
- An alternative is units per hour: quantity installed ÷ actual hours, compared with the estimated rate.
Worked example
On job 2420, the slab on grade code has 1,300 budgeted hours for 26,000 square feet. Crews have installed 13,520 square feet (52%), worth 680 earned hours, but used 1,000 hours. The productivity factor is 0.68.
How to read it
- Look at the trend, not one week. Start-up on a new code is often slow.
- Quantities drive the answer. If foremen do not report quantities, the metric cannot be trusted.
- Combine with remaining hours. A low factor early on a large code is a forecast problem.
- Productivity varies by trade, crew, and site, so we do not publish a benchmark.
Definitional choices and common pitfalls
- Hours basis. Use hours, not labor dollars, so wage changes do not distort it.
- Quantity source. Foreman daily reports, survey, or schedule of values. Pick one per cost code.
- Rework. Decide whether rework hours stay on the original code or go to a rework code.
- Period. Cumulative to date vs this week. Show both.
How different roles use it
| Role | How they use it |
|---|---|
| Operations / superintendent | Reviews productivity by crew and cost code weekly. |
| Project manager | Uses current rates to forecast remaining labor. |
| Estimator | Updates unit rates from finished jobs. |
| Owner / CEO | Sees which jobs and trades are running behind the estimate. |
Questions it answers
- Which cost codes are using more hours than estimated?
- Is productivity improving week to week?
- How many hours will it take to finish at the current rate?
- Which crews are fastest on similar work?
How to present it in a report
- One row per cost code: budget hours, percent installed, earned hours, actual hours, and factor.
- Color factors above and below 1.0.
- Weekly trend line of the factor for large codes.
- Projected hours at completion at the current rate.
| Cost code | Budget hrs | % installed | Earned hrs | Actual hrs | Factor |
|---|---|---|---|---|---|
| 03-310 Slab on grade | 1,300 | 52% | 680 | 1,000 | 0.68 |
| 03-110 Formwork | 1,800 | 72% | 1,300 | 1,500 | 0.87 |
| 03-210 Rebar | 900 | 69% | 620 | 600 | 1.03 |
Data you need
Fields
| Field | What it means | Example value |
|---|---|---|
| Job and cost code | Where hours and quantities are tracked | Job 2420, 03-310 slab on grade |
| Budgeted hours | Hours in the estimate | 1,300 |
| Budgeted quantity and unit | Quantity in the estimate | 26,000 SF |
| Quantity installed | Reported by the foreman | 13,520 SF |
| Actual hours | From timecards | 1,000 |
| Crew and date | Who and when | Crew 4, Oct 14 |
What the raw data looks like
Example data A few rows as they might come out of the source system.
| Date | Job | Cost code | Crew | Hours | Quantity | Unit |
|---|---|---|---|---|---|---|
| Oct 13 | 2420 | 03-310 | Crew 4 | 64 | 820 | SF |
| Oct 14 | 2420 | 03-310 | Crew 4 | 72 | 910 | SF |
| Oct 14 | 2420 | 03-110 | Crew 2 | 40 | 1,150 | SFCA |
| Oct 15 | 2420 | 03-210 | Crew 2 | 32 | 3.1 | TON |
Where this data usually lives
- Payroll and time tracking hold hours and labor cost by job and cost code, sometimes from a field time app.
- Field reporting (daily logs, foreman reports) holds quantities installed and site events.
- Construction ERP and accounting holds job cost, budgets, billing, AP, and AR. For example: Sage 300 Construction and Real Estate, Viewpoint Vista (Trimble), and Foundation. Some smaller contractors use general accounting software such as QuickBooks with jobs set up as projects.
- Spreadsheets often hold forecasts, logs, or the report itself.
The same field can live in more than one system. Agree with the customer which one is the source of truth.
Common data gaps and traps
- Quantities not reported. Hours come from payroll automatically; quantities need a foreman to enter them.
- Hours on the wrong code. Crews may charge time to whatever code is convenient.
- Different units. Estimate and field may use different units for the same work.
- Time tracking outside the ERP. Field apps may hold hours that reach payroll but not job cost by code.
Related metrics
- Job cost variance: the dollar result of productivity.
- Cost to complete: forecast remaining hours from the current rate.
- Schedule variance: slow crews also slip the schedule.
FAQ
- What is a productivity factor?
- Earned hours divided by actual hours. 1.0 means the crew is working at the estimated rate.
- Why hours and not dollars?
- Hours remove the effect of wage rates and overtime premiums.
- What if quantities are not tracked?
- Then productivity cannot be measured directly. Percent complete by cost code from the PM is a weaker substitute.
For your data teamFormula variants, tables, SQL sketch, and dashboard spec
Formula details
pct_installed = qty_installed / budget_qty
earned_hours = budget_hours * pct_installed
prod_factor = earned_hours / actual_hours
hours_at_completion = actual_hours + (budget_hours - earned_hours) / prod_factor
Worked example detail
| Cost code | Budget hrs | % installed | Earned | Actual | Factor |
|---|---|---|---|---|---|
| Formwork | 1,800 | 72% | 1,300 | 1,500 | 0.87 |
| Rebar | 900 | 69% | 620 | 600 | 1.03 |
| Slab on grade | 1,300 | 52% | 680 | 1,000 | 0.68 |
Tables and fields
| Table | Fields | Notes |
|---|---|---|
timecards |
job_id, cost_code, crew_id, work_date, hours | |
quantities |
job_id, cost_code, work_date, qty, unit | From field reports |
budgets |
job_id, cost_code, budget_hours, budget_qty, unit |
SQL sketch
WITH q AS (SELECT job_id, cost_code, SUM(qty) qty FROM quantities GROUP BY 1,2),
t AS (SELECT job_id, cost_code, SUM(hours) hrs FROM timecards GROUP BY 1,2)
SELECT b.job_id, b.cost_code,
b.budget_hours * q.qty / NULLIF(b.budget_qty,0) AS earned_hours, t.hrs AS actual_hours,
(b.budget_hours * q.qty / NULLIF(b.budget_qty,0)) / NULLIF(t.hrs,0) AS prod_factor
FROM budgets b LEFT JOIN q USING (job_id, cost_code) LEFT JOIN t USING (job_id, cost_code);
Build spec
Copy this into a ticket. It lists the grain, inputs, logic, and edge cases.
metric: construction.labor_productivity
grain: one row per job per cost code per week
inputs:
- budget_hours
- budget_qty
- qty_installed
- actual_hours
logic:
- earned_hours = budget_hours * qty_installed / budget_qty
- factor = earned_hours / actual_hours
edge_cases:
- no quantity reported: return null, not 0
- actual_hours = 0: return null
- unit mismatch: block and flag
- qty over 100%: cap and flag for budget update
As a dashboard card
- Bar per cost code with a 1.0 reference line, and a weekly trend for the largest codes.
Common mistakes
- Joining timecards and quantities row by row, which double counts. Aggregate each first.
- Using labor dollars instead of hours.
- Showing a factor when quantities are missing.