Pricing 3D prints like a machine shop
Two years of making things and I still caught myself pricing prints by feel. "That's about a $5 part." Sometimes it was, sometimes it was a money-loser, and I couldn't tell which because I had no ledger. Spools got cheaper per kilogram the more you bought, the printer was eating electricity nobody measured, and the machine I paid $549 for was slowly turning into depreciation I never accounted for.
So I built a cost engine for the site and let it grow teeth. It's at ibakas.com/print-cost, it produces a customer-ready quote sheet, and every number feeding it traces back to a cited source.
What the engine actually bills
The quote starts from six lines, the same way a shop would break out a job:
- Material — model weight plus supports and purge, charged by your price per kilogram.
- Energy — power draw over the print, at your electricity tariff.
- Machine — printer price divided by its working lifetime, per print hour.
- Consumables — nozzles, plates, grease, IPA, budgeted per hour.
- Labor — prep, removal, post-processing and packing, at your rate.
- Failure buffer — a percentage on the subtotal for the prints that don't come off the plate.
Margin goes on top of all of it. What survives is the minimum selling price, shown per unit and for the whole batch, with a breakdown bar that makes it obvious when labor is silently eating your margin.
The numbers that surprised me
Working examples keep grounding me. Take a 300 g part (250 g model, 50 g supports) on a Bambu P1S, 8 hours, plain PLA, US residential power:
| Line | Math | Cost |
|---|---|---|
| Material | 0.300 kg × $10.29/kg (Sunlu PLA) | ≈ $3.09 |
| Energy | 0.105 kW × 8 h × $0.15/kWh | ≈ $0.13 |
| Machine | $549 ÷ 8,000 h × 8 h | ≈ $0.55 |
| Consumables | $0.20/h × 8 h | ≈ $1.60 |
| Labor | 0.25 h × $20/h | ≈ $5.00 |
| Subtotal | ≈ $10.36 | |
| +5% failure buffer | ≈ $10.88 | |
| +50% margin | ≈ $16.32 |
The part I would have "felt" at five dollars is sixteen before you package it. Labor does that.
The catalog behind the engine currently holds 32 filaments and 23 printers. Prices run from $6.00/kg for Sunlu's 5 kg PETG spools to $49.99/kg for high-temp carbon nylon, and machines from a $199 Ender-3 to a $2,899 X1E. Two rules keep the data honest:
- Power figures are averages, not ratings. A rated 350 W input tells you nothing about the 78–85 W an Elegoo Neptune 4 Pro actually draws mid-print. The X1-Carbon averages 105 W on a PLA print while its peak would panic you — ratings overcharge, averages bill you.
- Every row cites a source and a verified date. Manufacturer measurements when they exist, measured teardowns and reviewer benches when they don't, and an explicit "estimate" note when only a guess exists. Anything without a source doesn't ship.
Why there's an "add your own" queue
A per-kilogram price from August is a guess by November. I can't keep 55 rows fresh by hand, and the people who actually know a filament's real-world behavior are the people burning through it. So the tool now ends with a small "Add your own printer or filament" form.
Your entries stay in your browser until you upload one, and they're quotable immediately, tagged (Custom) so you always know the numbers aren't mine. When you submit for review, here's what happens on the server:
- The payload is validated and rate-limited (5 per hour per IP) before it's allowed anywhere near the database.
- It lands in a pending queue that public visitors cannot read — the table has no anonymous policy, so it fails closed.
- Approving imports your rows as new, unpublished catalog entries. Only then does the normal dashboard verify-and-publish flow take over: I check the source, set a verified date, and switch them live.
- Rejecting leaves a note and a decision trail, so nothing evaporates silently.
The point is that the queue is a funnel, not a garbage chute. A material only reaches the shared catalog after a human checks it against the same rules as the rest of the data.
What I'd do differently
The biggest miss so far is deciding up front what "verified" means. I started with good intentions and no written policy, which is how you end up with a spreadsheet you argue with. Define your source tiers on day one and encode them in the schema — we ship rows with source_type (manufacturer, measured, review) and a dated last_verified so the staleness is visible instead of argued about.
Also: don't let currency pretend it's live. The engine computes everything in USD and converts for display; tariffs and exchange rates are dated presets, clearly labelled, never silently refreshed. Fresher numbers are the next job — if this is a tool you'd actually use, that's the queue telling me what to add.
Ready when you are: price your next print.
Keep reading
Referenced tools
Related builds
