Business — throughput accounting at the constraint
Throughput accounting for a machine shop, where the product mix is decided by throughput per constraint minute rather than by margin per unit — and the difference between the two is priced. Typed FlowScript for business strategy. Keywords: OKR, objective, key result, funnel.
Make it your own.
// Throughput accounting for a machine shop, where the product mix is
// decided by throughput per constraint minute rather than by margin per
// unit — and the difference between the two is priced.
//
// The constraint is one 5-axis turn-mill. Everything the shop can sell has
// to pass through it, so a minute of that machine is the only genuinely
// scarce thing in the business. Ranking work by margin per unit is the
// instinct every quoting system encourages, and here it costs about GBP
// 4700 a month, which is a third of the net profit.
//
// Cost per constraint minute is deliberately built from the minutes read
// as a plain number — constraint_minutes / 1[min] — because dividing money
// by a duration would produce a unit no report can print and no currency
// the unit table has.
constraint_system machining_cell {
title: "Contract machining cell — March 2026"
constraint: "DMG MORI NTX 2000 5-axis turn-mill, single machine"
currency: "GBP"
period: "March 2026, 21 working days"
working_days: 21
shifts_per_day: 2
shift_length: 450 min
// Availability at the constraint, measured: setup, first-off inspection
// and unplanned stops are all already inside this.
oee: 0.85 source "Machine monitoring, rolling 13 weeks"
constraint_minutes: = working_days * shifts_per_day * shift_length * oee
constraint_hours: = constraint_minutes / 60[min]
operating_expense: 48000
cost_per_constraint_hour: = operating_expense / constraint_hours
}
product_line aero_bracket {
of: machining_cell
title: "Aerospace bracket, 7075-T6"
price: 148
material_cost: 34
outsourced_cost: 7
variable_cost: = material_cost + outsourced_cost
throughput: = price - variable_cost
constraint_time: 24 min
throughput_per_constraint_minute: = throughput / (constraint_time / 1[min])
demand: 220
minutes_demanded: = demand * constraint_time
build: 220
minutes_used: = build * constraint_time
throughput_earned: = build * throughput
}
product_line medical_housing {
of: machining_cell
title: "Medical pump housing, 316L"
price: 212
material_cost: 44
outsourced_cost: 14
variable_cost: = material_cost + outsourced_cost
throughput: = price - variable_cost
constraint_time: 41 min
throughput_per_constraint_minute: = throughput / (constraint_time / 1[min])
demand: 150
minutes_demanded: = demand * constraint_time
build: 150
minutes_used: = build * constraint_time
throughput_earned: = build * throughput
}
product_line motorsport_upright {
of: machining_cell
title: "Motorsport upright, 7075-T7351"
price: 340
material_cost: 96
outsourced_cost: 25
variable_cost: = material_cost + outsourced_cost
throughput: = price - variable_cost
constraint_time: 62 min
throughput_per_constraint_minute: = throughput / (constraint_time / 1[min])
demand: 60
minutes_demanded: = demand * constraint_time
build: 60
minutes_used: = build * constraint_time
throughput_earned: = build * throughput
}
product_line hydraulic_manifold {
of: machining_cell
title: "Hydraulic manifold, EN24T"
price: 415
material_cost: 118
outsourced_cost: 29
variable_cost: = material_cost + outsourced_cost
throughput: = price - variable_cost
constraint_time: 96 min
throughput_per_constraint_minute: = throughput / (constraint_time / 1[min])
demand: 40
minutes_demanded: = demand * constraint_time
// The marginal product: it has the highest throughput per unit and the
// lowest per constraint minute, so it is the one that gets cut.
build: 9
minutes_used: = build * constraint_time
throughput_earned: = build * throughput
}
mix_result throughput_first {
of: machining_cell
label: "Mix ranked by throughput per constraint minute"
minutes_demanded: = sum(kind:product_line, "minutes_demanded") * 1[min]
minutes_committed: = sum(kind:product_line, "minutes_used") * 1[min]
minutes_idle: = machining_cell.constraint_minutes - minutes_committed
overload: = pct(minutes_demanded, machining_cell.constraint_minutes)
// Named line by line. The two roll-ups above it work because their
// attributes are one step from a literal; throughput_earned is three
// (material and outsourced cost make variable cost, price less variable
// cost makes throughput, build times throughput makes this), and the
// aggregate runs before a chain that deep resolves — so the selector
// matches nothing and the total silently comes out zero. A zero total
// in a throughput-accounting figure is the one number that must never
// be quietly wrong.
total_throughput: = hydraulic_manifold.throughput_earned + motorsport_upright.throughput_earned + medical_housing.throughput_earned + aero_bracket.throughput_earned
net_profit: = total_throughput - machining_cell.operating_expense
return_per_constraint_hour: = total_throughput / machining_cell.constraint_hours
}
// The same capacity filled highest-margin-first, which is what the quoting
// system recommends today.
mix_result margin_first {
of: machining_cell
label: "Mix ranked by throughput per unit"
manifolds: 40
uprights: 60
housings: 150
brackets: 98
minutes_committed: = (manifolds * hydraulic_manifold.constraint_time) + (uprights * motorsport_upright.constraint_time) + (housings * medical_housing.constraint_time) + (brackets * aero_bracket.constraint_time)
total_throughput: = (manifolds * hydraulic_manifold.throughput) + (uprights * motorsport_upright.throughput) + (housings * medical_housing.throughput) + (brackets * aero_bracket.throughput)
net_profit: = total_throughput - machining_cell.operating_expense
penalty: = throughput_first.total_throughput - total_throughput
penalty_share_of_profit: = pct(penalty, throughput_first.net_profit)
}
// An hour recovered at the constraint is worth a whole hour of throughput;
// an hour saved anywhere else is worth nothing at all.
elevation_option setup_reduction {
of: machining_cell
label: "Single-minute exchange of die on the turn-mill: 18 setups per month, 22 minutes saved each"
setups_per_month: 18
minutes_saved_each: 22 min
minutes_recovered: = setups_per_month * minutes_saved_each
extra_manifolds: = floor(minutes_recovered / hydraulic_manifold.constraint_time)
throughput_gained: = extra_manifolds * hydraulic_manifold.throughput
project_cost: 6500
payback_months: = project_cost / throughput_gained
}
// The month's constraint minutes, spent in the order the ranking implies.
// Each step is the previous one less the minutes that product takes, so
// the chart is the mix decision rather than an illustration of it.
funnel_step capacity_available {
n: = machining_cell.constraint_minutes
title: "Constraint minutes available — 21 days, 2 shifts, 85% OEE"
}
funnel_step after_brackets {
n: = capacity_available.n - aero_bracket.minutes_used
from: capacity_available
title: "After 220 aerospace brackets at GBP 4.46 per constraint minute"
}
funnel_step after_housings {
n: = after_brackets.n - medical_housing.minutes_used
from: after_brackets
title: "After 150 medical housings at GBP 3.76"
}
funnel_step after_uprights {
n: = after_housings.n - motorsport_upright.minutes_used
from: after_housings
title: "After 60 motorsport uprights at GBP 3.53"
}
funnel_step unsold_capacity {
n: = after_uprights.n - hydraulic_manifold.minutes_used
from: after_uprights
title: "After 9 of the 40 manifolds at GBP 2.79 — the constraint runs out here"
}
cite goldratt {
key: "goldratt1992"
title: "The Goal: A Process of Ongoing Improvement, 2nd revised edition"
authors: "Eliyahu M. Goldratt and Jeff Cox"
publisher: "North River Press"
year: 1992
type: "book"
of: machining_cell
}
note inventory_measure {
text: "Throughput accounting has three measures and this document uses two. The third, investment, is what the shop has tied up in material and work in progress; it does not change the mix decision but it does change whether the manifold work is worth quoting at all, because its material cost sits on the floor for eleven days before the machine sees it."
anchor: machining_cell
}
view capacity: funnel(capacity_available)
caption capacity_caption {
of: capacity
title: "Where the constraint's month goes"
text: "Constraint minutes spent in descending order of throughput per constraint minute. The manifold is the marginal product: 31 of the 40 units demanded do not get made, and that is the correct decision — made in the other order it costs about GBP 4700 of throughput."
n_statement: "Basis: 16 065 constraint minutes, March 2026."
style: journal
}