# Steel Fabrication Job Costing: Why Margins Leak

> Source: https://netray.co/resources/steel-fabrication-job-costing-why-margins-leak
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: Knowledge Base

## Short answer

Why fabrication jobs lose margin: steel price swings, change orders, rework, outside processing, and bad labor coding. How to cost and review jobs properly.

## Category

erp-general

## Content

**Intro:** Fabrication jobs lose margin in a few predictable places: material bought at a different price than quoted, unbilled change orders, welding and fit-up hours above the estimate, rework, outside processing overruns, and labor booked to the wrong job. Job costing that compares actuals to the bid by cost code, weekly rather than at close, is how shops catch these early. This guide covers how to set up job cost codes, review jobs while they are open, and use closed-job variance to fix the next estimate.

**Sections:**

#### Set Cost Codes That Match How You Bid

**Body:** If you estimate by detailing, material, shop labor, welding, paint, freight, and erection, your job cost must report on the same lines. Otherwise you cannot tell whether a loss came from the estimate or the shop. Break shop labor into work centers such as cutting, fit-up, welding, and finishing so you can see which operation overran. Tie material cost to purchase orders and issue them to the job with the actual price paid. Many shops post all material to a single line, which hides whether the problem is steel price or waste. Consistent codes across jobs also make benchmarking possible.

**Bullets:**

- One code structure used for both estimating and job cost
- Labor split by work center and by welding versus fit-up
- Separate lines for outside processing and freight

#### Material: Price Moves, Waste, and Remnants

**Body:** Steel prices move, and quotes often hold for only days. If you quote in March and buy in May, the difference lands in your margin unless the contract has escalation terms or you bought at award. Track quoted price against purchase price per job. Material waste comes from drops, mis-cuts, and over-ordering. Remnants returned to inventory should be credited back to the job, but only when actually reused or valued correctly; otherwise reports are inflated. Domestic-content or Buy America requirements can also force a higher-cost source than the estimate assumed.

**Bullets:**

- Compare quoted versus purchased price by line
- Track scrap and drops against the cut list
- Credit remnants to stock with heat information

#### Labor Coding Discipline and Rework

**Body:** Cost reports are only as honest as time entry. If welders book hours to whichever job is easiest, one job looks great and another looks terrible. Make the traveler or work order the basis for time entry and require that rework hours be coded separately, such as repairs after UT rejection, fit-up corrections, or re-dimensioning. Separate rework tells you whether the loss is a quoting problem or a quality problem. Without it, bad estimates and bad execution look identical and each gets blamed on the other.

#### Change Orders and Unbilled Work

**Body:** In field and shop work, scope grows through RFIs, revised drawings, and verbal requests. If those hours are not tracked against a change order, the shop absorbs them. Create a process where any out-of-scope work is documented with a signed or emailed direction, priced, and billed. For revised drawings, record the hours spent fixing already-fabricated pieces. Reviewing open jobs weekly for percent complete versus percent of budget spent will show which ones are drifting before the final bill.

#### Review Cadence and Where AI Helps

**Body:** A weekly 30-minute review of open jobs, sorted by variance, catches more than a year-end analysis. For each job look at earned value versus cost, pending change orders, and forecast at completion. AI can prepare this by querying the ERP in plain language, listing jobs where welding hours exceed budget by more than a threshold, and explaining the transactions behind a variance with links to the source records. It does not fix bad time coding. If the data is poor, start by cleaning the process, not by buying more analysis.

**Cta:** Netray can add a private ask-your-ERP layer so owners and project managers can ask which open jobs are over budget and why, with the underlying transactions shown.

**Faq:**

#### Why do steel fabrication jobs lose money?

**Answer:** Common causes include steel price changes between quote and purchase, underestimated welding and fit-up hours, rework, unbilled change orders, outside processing overruns, and labor booked to the wrong job. Reviewing open jobs by cost code against the bid shows which of these applies so you can fix the estimate or the process.

#### How should a fabricator track job costs?

**Answer:** Use cost codes that mirror the estimate, book labor from work orders by work center, post material at actual purchase price, track rework and change orders separately, and review open jobs weekly. Compare closed-job actuals to the bid to update labor standards and pricing assumptions for the next quote.

#### What is a good gross margin for a steel fabricator?

**Answer:** It varies widely by market, job type, and competition, so published benchmarks are unreliable. Instead, track your own margin by job type and size and watch the spread between estimated and actual. A consistent gap between estimate and actual margin is more useful than comparing against an industry number.

## Related Slugs

- gross-margin-analysis-manufacturing
- syteline-costing-variance-investigation
- manufacturing-costing-methods-comparison
- how-to-estimate-welding-cost-per-foot-fabrication

## Search terms

steel fabrication job costing, fabrication job cost report, why fabrication jobs lose money, fabricator margin analysis, change order tracking fabrication, estimate vs actual steel fabrication

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
