Margin and Markup in Practice
Why this matters
Knowing that markup divides by cost and margin divides by price is where most shops stop, and it is not where the money is lost. The money is lost in what happens after: a mixed ticket that has no single markup, a target margin quoted against estimated cost and never re-read against actual cost, a discount that gives away a fifth of a job's gross profit while looking like a small concession, and a billing rate that has not moved while the wage behind it has. All four of those are still true for someone who can recite both formulas perfectly. This is the operating layer.
The refresher, in one line, then we move on
Markup is profit as a fraction of cost. Margin is profit as a fraction of price. The same job carries both numbers at the same time and they are never equal, with margin always the smaller of the two. The full definition, the conversion table, and the classic confusion between them are covered in the sibling cards listed at the end. Everything below assumes you have those and asks what to do with them once real numbers land on real jobs.
Markup builds the price, margin grades it, and each belongs in its own artifact
Keep them physically separated by where they live, because that is the only reliable way to stop them being mixed up under pressure.
- The price book and the estimating template use multipliers. You are building up from a cost, so a multiplier is the natural form: parts at 1.5 times cost, labor at a rate set as a multiple of the burdened hour. Nobody should be doing a margin-to-markup conversion in their head while a customer waits.
- The post-job review and the profit and loss statement read margin. You are grading down from a price that already exists, so margin is the natural form, and it is the only one of the two that is comparable across jobs of wildly different size and mix.
- The target you set is a margin. The instruction you deploy is a multiplier. Do the conversion once, write both numbers next to each other in the price book, and date it.
A shop that states its goal as "we want 50 points" and then tells the field "mark it up 50" has just set a target of 50% margin and deployed an instruction that produces 33% margin. That single mismatch is the most expensive arithmetic error in the trades.
A mixed ticket has no single markup
Almost every ticket is at least two lines with two different rules: material bought and resold, and labor sold as time. They carry different multipliers for good reasons, so the ticket's blended result depends on the mix, and the mix changes job to job without anyone deciding it.
Work an example with the same two rules throughout: parts priced at 1.5 times parts cost, labor priced at 2.2 times burdened labor cost.
Ticket A, a labor-heavy service job. Of the total job cost, parts are 40% and labor is 60%. Indexing total cost to 1.00:
- Parts price: 0.40 x 1.5 = 0.60
- Labor price: 0.60 x 2.2 = 1.32
- Total price: 1.92 times total cost
Gross profit is 1.92 - 1.00 = 0.92, so the blended markup is 92% of cost and the blended margin is 0.92 / 1.92 = 47.9% of price.
Ticket B, a parts-heavy replacement. Same two rules, but of total job cost, parts are 70% and labor is 30%:
- Parts price: 0.70 x 1.5 = 1.05
- Labor price: 0.30 x 2.2 = 0.66
- Total price: 1.71 times total cost
Gross profit is 0.71, blended markup 71% of cost, blended margin 0.71 / 1.71 = 41.5% of price.
Nobody changed a price. The mix shifted from 40% parts to 70% parts, and the ticket's margin fell by 6.4 percentage points, from 47.9% to 41.5%. This is why a shop that has grown its equipment-replacement work can watch overall margin slide while every individual line is priced exactly to policy. If you want a floor on blended margin, you have to either set the floor at the ticket level and let the multipliers flex, or accept that parts-heavy work will run structurally leaner and price the growth accordingly.
The margin you quoted and the margin you earned are two different numbers
Quoted margin uses estimated cost. Realized margin uses actual cost. Most shops only ever compute the first one, print it on the estimate, and never go back. The gap between the two is your estimating error restated in margin points, which is the single most useful number this whole discipline produces, because it is already in the unit an owner thinks in.
Continue with Ticket A, which was quoted at 1.92 times estimated cost with a 47.9% quoted margin. It is a fixed-price job, so the price does not move. Labor comes in 25% over the estimated hours:
- Parts actual: 0.40, on plan
- Labor actual: 0.60 x 1.25 = 0.75
- Total actual cost: 1.15, against the 1.00 that was estimated
Realized margin is (1.92 - 1.15) / 1.92 = 0.77 / 1.92 = 40.1% of price. The 25% labor overrun cost 7.8 percentage points of margin, dropping the ticket from 47.9% to 40.1%.
Notice how much smaller the margin move looks than the labor move. A 25% overrun on the largest cost line reads as a single-digit margin change, which is exactly why margin alone is a poor instrument for catching estimating error. Report both: margin for the financial result, hours variance for the diagnosis.
What a discount actually costs, stated correctly
A discount comes entirely out of gross profit, because your cost does not move when you concede. So the right way to state its size is as a share of the profit, not as a share of the price.
Ticket A again at its on-plan cost of 1.00 and price of 1.92, with a 10% discount off the price:
- Discounted price: 1.92 x 0.90 = 1.728
- Gross profit: 1.728 - 1.00 = 0.728, down from 0.92
- Profit given away: 0.92 - 0.728 = 0.192, which is 0.192 / 0.92 = 20.9% of the ticket's gross profit
- Margin: 0.728 / 1.728 = 42.1% of price, down 5.8 percentage points from 47.9%
A 10% discount handed over roughly 21% of that ticket's gross profit. On the parts-heavy Ticket B, where gross profit is a thinner 0.71 against a price of 1.71, the same 10% discount removes 0.171 of profit, which is 0.171 / 0.71 = 24.1% of that ticket's gross profit. The leaner the ticket, the more of the profit a fixed percentage discount consumes, which is the opposite of the instinct most people have when the customer pushes on a big parts-heavy quote.
Now stack the discount on the overrun. Price 1.728, actual cost 1.15: margin is 0.578 / 1.728 = 33.4% of price, against 47.9% quoted. A concession the salesperson considered small and an overrun the field considered normal removed 14.5 percentage points of margin between them, and neither person saw the other's contribution.
The multiplier that erodes without anyone changing it
A parts markup expressed as a multiplier is self-correcting on cost: if parts cost rises 8% and you still multiply by 1.5, the parts line holds its margin percentage, because both the cost and the price moved together. A labor rate expressed as a fixed hourly number is not self-correcting at all, and this is where quiet erosion lives.
Ticket A was built with labor priced at 2.2 times burdened labor cost. Suppose burdened labor cost rises 6% and the billing rate is left alone:
- Labor cost: 0.60 x 1.06 = 0.636, labor price unchanged at 1.32
- Effective labor multiple: 1.32 / 0.636 = 2.08 times cost, down from 2.2
- Total cost: 0.40 + 0.636 = 1.036, total price still 1.92
- Margin: (1.92 - 1.036) / 1.92 = 0.884 / 1.92 = 46.0% of price, down 1.9 percentage points from 47.9%
One 6% wage movement, no decision made by anyone, 1.9 points of blended margin gone on this ticket mix. Two or three of those in a row and the rate is materially under-set while the price book still says the policy is being followed. The fix is to store the labor rate as a multiple of the current burdened cost and re-derive the hourly number whenever burdened cost moves, rather than storing the hourly number and hoping someone remembers.
What changes these calls
Fixed-price versus time and materials. Everything above assumes the price is locked, so overruns land on you. On a genuine time-and-materials job the overrun bills through and realized margin holds, which is why the two contract types must be reported separately or the T and M jobs will make your fixed-price estimating look better than it is.
Parts you do not mark up. Some shops pass customer-supplied or owner-furnished material through at cost. Those lines must be excluded from the blended margin calculation, not entered at a 1.0 multiplier, or they will drag the blended figure and trigger a correction to a template that is working fine.
Very small tickets. On a short call, the trip and the minimum charge dominate and blended margin is close to meaningless as a comparison across job types. Judge those on contribution per visit instead.
How to verify your margins are being read correctly
Take one closed ticket and compute its margin three ways: from the estimate, from the actual cost, and from what the accounting system reports for that job. All three should reconcile, and each difference should have a name you can state. Estimate to actual is estimating variance. Actual to accounting is usually either a cost that landed in overhead instead of on the job, or a part booked at file price rather than paid price.
Then check one instruction against one target. Open the price book, find the stated target margin, find the multiplier actually deployed for that line, and confirm the conversion. Do this on two or three lines. Finding one line where a 40% target is being delivered by a 1.4 multiplier, which produces 28.6% margin, is common enough that the check is worth running on every price book at least once a year.
References
- U.S. Small Business Administration (SBA), pricing and gross margin fundamentals for small business
- Generally Accepted Accounting Principles (GAAP), cost of goods sold and gross profit concepts
- See related: Markup vs Margin: The Mistake That Kills Profit, The Difference Between Markup and Margin, Gross Margin per Job, The Discount Discipline That Protects Your Margin, How to Read Your Own Job Costing Data