Powder Bed - SLS / MJF
How to price powder bed processes (SLS, MJF, HSS, SAF) using shrink wrap volume, amortised setup costs, and quantity discounts.
Why this process is unique
Powder bed processes (SLS, MJF, HSS) don't use support structures - the unfused powder supports the part during printing. This has two major pricing implications:
- Cost is driven by chamber volume occupied, not just part volume. A small dense part and a large hollow part with the same actual volume cost very differently.
- Build setup is expensive - depowdering, cake extraction, powder sieving, and material refresh are significant fixed costs per build. These must be amortised over all parts in the run.
The standard cost metric is shrinkWrapVolume - the tightest wrapping around the part including overhangs. It's the best proxy for how much of the chamber the part consumes.
Core methodology
Variable cost: shrinkWrapVolume × cost per cm³
Fixed cost: setup fee per build, divided by quantity ordered
Quantity discount: banded, reflecting better chamber utilisation and batch efficiency
Review gate: parts exceeding the chamber in any dimension
HP MJF 5200 Pro specifications (reference)
- Build volume: 380 × 284 × 380 mm
- Layer height: 0.08 mm
- Typical cycle: 8-12 hours per full build
Numerical example
Part: 50 × 50 × 100 mm bracket, shrinkWrapVolume = 210,000 mm³ (part has overhangs)
| Input | Value |
|---|---|
costPerCm3 | €0.18 |
setupCost | €80 |
| Quantity | 5 |
Calculation:
- Volume cost: (210,000 / 1,000) × 0.18 = €37.80
- Setup per part: 80 / 5 = €16.00
- Subtotal: €53.80
- Qty 5 discount (none below 10): ×1.00
- Unit price: €53.80
At qty 50: setup = €1.60/part, discount 10% → unit price €35.46. Material cost is now ~90% of the price.
Complete algorithm
const { shrinkWrapVolume, length, width, height } = specification
const { quantity } = requisition
// Machine chamber limits — adapt to your printer
const CHAMBER_LENGTH = 380
const CHAMBER_WIDTH = 284
const CHAMBER_HEIGHT = 380
const costPerCm3 = material.variables['costPerCm3']
const setupCost = material.variables['setupCost']
// Variable cost: shrink wrap volume × rate
const volumeCm3 = shrinkWrapVolume / 1000
const volumeCost = round(volumeCm3 * costPerCm3, 2)
// Fixed cost: setup amortised over order quantity
const setupPerPart = round(setupCost / quantity, 2)
const baseCost = volumeCost + setupPerPart
// Quantity discount: smaller batches pay more per part
const getDiscount = createBands({ 5: 0.97, 10: 0.93, 25: 0.88, 50: 0.83, 100: 0.78 }, 1.0)
const unitPrice = variable('unitPrice', round(baseCost * getDiscount(quantity), 2))
// Review gate: part exceeds chamber dimensions
const oversized = length > CHAMBER_LENGTH || width > CHAMBER_WIDTH || height > CHAMBER_HEIGHT
done(unitPrice, 0, oversized)Material variables to create: costPerCm3, setupCost
When to use this
Use this model for any powder bed process: MJF, SLS, HSS, SAF. All share the same pricing structure.
Do not use for metal powder bed (LPBF) - print time dominates there and requires a time-based model.
You could also think of a packing algorithm to predict the usage of the build chamber at larger quantities.
Last updated on
Before You Build - Questions to Ask First
A thinking guide for scoping your pricing equation before you write code: cost drivers, calibration data, minimums, quantity curves, machines, material variables, review gates, overrides, lead times, customer pricing, and post-processes.
FDM - Filament Extrusion
How to price FDM/FFF parts by splitting geometry into shell, infill, and supports to estimate print time, which is the dominant cost driver.