Job Costing Calculator
ANA›Life Services Authority›National Calculator Authority›Job Costing Calculator
.calc-container { max-width: 640px; margin: 2rem 0; padding: 1.5rem; background: #fff; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); font-family: system-ui, -apple-system, sans-serif; } .calc-container h3 { font-family: Georgia, serif; font-size: 1.15rem; color: #1a1a1a; margin-bottom: 1rem; padding-bottom: 0.5rem; border-bottom: 2px solid var(--ac, #3d5a80); } .calc-row { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.75rem; flex-wrap: wrap; } .calc-row label { min-width: 160px; font-size: 0.9rem; color: #333; font-weight: 500; } .calc-row input[type="number"], .calc-row select { flex: 1; min-width: 120px; max-width: 200px; padding: 0.5rem 0.6rem; border: 1px solid #ccc; border-radius: 4px; font-size: 0.9rem; font-family: system-ui, sans-serif; color: #1a1a1a; background: #fafaf8; } .calc-row input:focus, .calc-row select:focus { outline: none; border-color: var(--ac, #3d5a80); box-shadow: 0 0 0 2px rgba(26,74,138,0.12); } .calc-row .unit { font-size: 0.82rem; color: #888; min-width: 30px; } .calc-btn { display: inline-block; margin-top: 0.5rem; padding: 0.55rem 1.5rem; background: var(--ac, #3d5a80); color: #fff; border: none; border-radius: 4px; font-size: 0.9rem; font-weight: 600; cursor: pointer; font-family: system-ui, sans-serif; } .calc-btn:hover { opacity: 0.9; } .calc-result { margin-top: 1.25rem; padding: 1rem 1.25rem; background: #f0f6fc; border-left: 3px solid var(--ac, #3d5a80); border-radius: 0 6px 6px 0; display: none; } .calc-result.visible { display: block; } .calc-result-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: #666; margin-bottom: 0.25rem; } .calc-result-value { font-size: 1.6rem; font-weight: 700; color: var(--ac, #3d5a80); } .calc-result-detail { font-size: 0.85rem; color: #555; margin-top: 0.5rem; line-height: 1.5; } .calc-note { margin-top: 1rem; font-size: 0.8rem; color: #888; font-style: italic; } .calc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; margin-top: 0.75rem; } .calc-grid-item { padding: 0.6rem 0.8rem; background: #f8f9fa; border-radius: 4px; border: 1px solid #eee; } .calc-grid-item .label { font-size: 0.75rem; color: #888; text-transform: uppercase; letter-spacing: 0.04em; } .calc-grid-item .value { font-size: 1.1rem; font-weight: 600; color: #1a1a1a; } @media (max-width: 720px) { .calc-row { flex-direction: column; align-items: flex-start; gap: 0.3rem; } .calc-row label { min-width: auto; } .calc-row input[type="number"], .calc-row select { max-width: 100%; width: 100%; } .calc-grid { grid-template-columns: 1fr; } } .calc-chart { margin: 1rem 0; text-align: center; } .calc-chart svg { max-width: 100%; height: auto; } .calc-chart-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem 1.2rem; margin-top: 0.6rem; font-size: 0.8rem; color: #555; } .calc-chart-legend span { display: inline-flex; align-items: center; gap: 0.3rem; } .calc-chart-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; font-style: normal; } .calc-related { max-width: 640px; margin: 2rem 0 1rem; padding: 1.25rem 1.5rem; background: #f8f9fa; border: 1px solid #e8e8e8; border-radius: 8px; } .calc-related h3 { font-family: Georgia, serif; font-size: 1rem; color: #1a1a1a; margin: 0 0 0.75rem; padding-bottom: 0.4rem; border-bottom: 2px solid var(--ac, #3d5a80); } .calc-related-list { list-style: none; padding: 0; margin: 0 0 0.75rem; display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem 1.5rem; } .calc-related-list li a { font-size: 0.88rem; color: var(--ac, #3d5a80); text-decoration: none; } .calc-related-list li a:hover { text-decoration: underline; } .calc-browse-all { margin: 0.5rem 0 0; font-size: 0.9rem; font-weight: 600; } .calc-browse-all a { color: var(--ac, #3d5a80); text-decoration: none; } .calc-browse-all a:hover { text-decoration: underline; } @media (max-width: 720px) { .calc-related-list { grid-template-columns: 1fr; } }
Job Costing Calculator
Estimate the total cost and minimum bid price for a job by factoring in labor, materials, subcontractors, overhead, and your desired profit margin.
Total Labor Hours
Fully Burdened Labor Rate ($/hr)
Include wages, payroll taxes, workers' comp, benefits (~1.25–1.40× base wage)
Total Materials Cost ($)
Materials Markup (%)
Typical range: 10–25% to cover handling, waste, and procurement time
Subcontractor Costs ($)
Subcontractor Markup (%)
Typical range: 5–15% to cover coordination and liability
Overhead Rate (%)
Applied to direct labor cost. Covers rent, insurance, vehicles, admin (typically 15–30%)
Desired Net Profit Margin (%)
Typical contractor net profit: 10–20%
Calculate
### Job Cost Breakdown
function jobCalc() { const errEl = document.getElementById('job-error'); const resEl = document.getElementById('job-result'); const tblEl = document.getElementById('job-result-table'); errEl.style.display = 'none'; resEl.style.display = 'none';
// --- parse inputs --- const laborHours = parseFloat(document.getElementById('job-labor-hours').value); const laborRate = parseFloat(document.getElementById('job-labor-rate').value); const materials = parseFloat(document.getElementById('job-materials').value) || 0; const materialsMarkup = parseFloat(document.getElementById('job-materials-markup').value) || 0; const subs = parseFloat(document.getElementById('job-subs').value) || 0; const subsMarkup = parseFloat(document.getElementById('job-subs-markup').value) || 0; const overheadRate = parseFloat(document.getElementById('job-overhead-rate').value) || 0; const profitMargin = parseFloat(document.getElementById('job-profit-margin').value);
// --- validation --- const errors = []; if (isNaN(laborHours) || laborHours 500) errors.push("Materials markup must be between 0% and 500%."); if (subsMarkup 500) errors.push("Subcontractor markup must be between 0% and 500%."); if (overheadRate 500) errors.push("Overhead rate must be between 0% and 500%."); if (isNaN(profitMargin) || profitMargin = 100) errors.push("Profit margin must be between 0% and 99%.");
if (errors.length) { errEl.innerHTML = errors.map(e => '⚠ ' + e).join(''); errEl.style.display = 'block'; return; }
// --- formulas --- // 1. Direct Labor Cost const directLaborCost = laborHours * laborRate;
// 2. Overhead Cost = Direct Labor Cost × (overheadRate / 100) const overheadCost = directLaborCost * (overheadRate / 100);
// 3. Materials with markup const materialsCost = materials * (1 + materialsMarkup / 100);
// 4. Subcontractors with markup const subsCost = subs * (1 + subsMarkup / 100);
// 5. Total Direct Cost (before profit) const totalDirectCost = directLaborCost + overheadCost + materialsCost + subsCost;
// 6. Minimum Bid Price using margin formula: // Bid = Total Direct Cost / (1 - profitMargin/100) // This ensures profit is the correct % of the selling price, not cost. const bidPrice = totalDirectCost / (1 - profitMargin / 100);
// 7. Profit amount const profitAmount = bidPrice - totalDirectCost;
// 8. Cost per labor hour (fully loaded) const costPerHour = laborHours > 0 ? bidPrice / laborHours : 0;
// --- render --- const fmt = v => '$' + v.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ','); const pct = v => v.toFixed(2) + '%';
const rows = [ ['Direct Labor Cost', fmt(directLaborCost), '(' + laborHours + ' hrs × ' + fmt(laborRate) + '/hr)'], ['Overhead Cost', fmt(overheadCost), '(' + pct(overheadRate) + ' of direct labor)'], ['Materials (with markup)', fmt(materialsCost), '(' + fmt(materials) + ' + ' + pct(materialsMarkup) + ' markup)'], ['Subcontractor (with markup)', fmt(subsCost), '(' + fmt(subs) + ' + ' + pct(subsMarkup) + ' markup)'], ['─────────────────────', '─────────', ''], ['Total Direct Cost', fmt(totalDirectCost), ''], ['Profit (' + pct(profitMargin) + ' margin)', fmt(profitAmount), ''], ['─────────────────────', '─────────', ''], ['Minimum Bid Price', '' + fmt(bidPrice) + '', ''], ['Fully Loaded Cost / Labor Hr', laborHours > 0 ? fmt(costPerHour) : 'N/A', '(bid ÷ labor hours)'], ];
tblEl.innerHTML = rows.map(([label, value, note]) =>
${label}
${value}
${note}
).join('');
resEl.style.display = 'block'; }
#### Formulas Used
Direct Labor Cost = Labor Hours × Fully Burdened Labor Rate
Overhead Cost = Direct Labor Cost × (Overhead Rate ÷ 100)
Materials with Markup = Materials Cost × (1 + Materials Markup ÷ 100)
Subcontractor with Markup = Sub Cost × (1 + Sub Markup ÷ 100)
Total Direct Cost = Direct Labor + Overhead + Materials (marked up) + Subs (marked up)
Minimum Bid Price = Total Direct Cost ÷ (1 − Profit Margin ÷ 100)
The bid price formula ensures profit margin is calculated on the selling price (gross margin), not on cost (markup). A 15% margin on price ≠ 15% markup on cost.
#### Assumptions & References
- Fully Burdened Labor Rate includes base wages plus payroll taxes (FICA ~7.65%), workers' compensation, general liability insurance, and benefits — typically 1.25–1.40× the base hourly wage. (NAHB, 2023)
- Overhead Rate is applied to direct labor and covers indirect costs: office rent, vehicle expenses, tools, software, and administrative salaries. Industry average is 15–30% of direct labor. (Construction Financial Management Association)
- Materials Markup of 10–25% is standard to cover procurement time, storage, waste, and price volatility risk. (RSMeans Cost Data)
- Subcontractor Markup of 5–15% covers coordination, scheduling, and the general contractor's liability exposure.
- Net Profit Margin of 10–20% is typical for residential and commercial contractors after all costs. (CFMA Annual Financial Survey)
More Calculators
- SEER Rating Savings Calculator
- HVAC Financing Cost Calculator
- HVAC Replacement Cost Estimator
- HVAC Company Quote Comparison Calculator
- Air Changes Per Hour (ACH) Calculator
- Airflow CFM Calculator
Read Next
Study Time Planner Authority Network America › Life Services Authority › National Calculator Authority .calc-container { max-width: 640px;...