← Blog

Track real filament cost per print, self-hosted

Cost per print is grams over 1000 times your price per kilogram. Which half a self-hosted stack measures rather than estimates, and where the number ends up.

cost-trackingfilamentspoolmanself-hosted

The arithmetic is not the hard part. Filament cost for a print is grams used divided by 1000, multiplied by what you paid per kilogram. A 50 g part off a spool that cost 20 of your currency per kilogram cost you about 1.00 in plastic.

The hard part is getting both numbers to be real rather than assumed, and keeping them attached to the print they describe. Self-hosted, that means two containers: PrintStash for the print record and Spoolman for the spool inventory and its prices. Klipper machines report the grams they actually used, PrintStash resolves the cost from the spool you picked, and the figure is frozen onto the job when it completes.

Two limits decide whether that is worth setting up. Measured consumption comes back from Moonraker only, so on any other provider the grams stay a slicer estimate. And this is material cost, full stop: no electricity, no machine hours, no labor.

What makes a cost number real

Both halves of that multiplication can be a guess or a fact, and the difference is bigger on the grams than on the price.

The slicer’s estimate is available before the print and is usually close. It is a prediction from the toolpath, so it does not know about a purge tower you changed, a failure at layer 300, or the filament left in the nozzle.

Measured consumption comes from the printer’s own accounting after the job. In PrintStash that arrives from Moonraker, and it is the number worth keeping, with one caveat: it is what the firmware counted, not what a scale would say.

The price side has its own version of the same split. A generic material preset says PETG costs roughly this much. A synced Spoolman spool says this specific roll cost exactly that, which matters the moment two spools of the same material came from different suppliers at different prices.

PrintStash resolves cost once, when the job completes, and freezes it. Editing a filament price afterwards does not rewrite last month’s prints, which is the behavior you want in a historical total and the opposite of what a spreadsheet does.

The self-hosted stack

Spoolman owns the spools: what you have, what it cost, how much is left. PrintStash owns the print record: which model, which G-code revision, which printer, which spool, and what it cost. Syncing pulls each Spoolman filament into PrintStash as a read-only preset carrying material, brand, density, diameter, and a price per kilogram derived from the spool’s price and weight.

From there the flow is short. Pick the spool when you send the job. When a Moonraker print finishes, PrintStash writes the measured grams back to Spoolman so remaining inventory stays right, and checks first whether Spoolman already has an active spool, which means Moonraker’s own hook is doing the decrement and PrintStash should stay out of it.

The setup itself, including the network addressing that trips people up when both run in Docker, is in tracking filament use with Spoolman and the Spoolman guide. Both are optional: the integration is off by default and only a superuser can turn it on. If you are still deciding which tools belong in that stack, which self-hosted tools connect to Spoolman maps every connection layer.

Where the numbers surface afterwards is the model’s print history, per job and per revision, which print history tracking covers in detail.

What it will not tell you

Material cost is the floor of what a print costs, not the price of making it. Electricity, the share of the machine you used up, failed attempts, and your own time are all real and none of them are in this number. What a 3D print actually costs works through those, and the short version is that filament is often the smaller half of a quote.

There is also no invoicing, no margin calculation, and no customer-facing quote in PrintStash. If that is what you need, you are shopping for a different category of tool.

The hosted alternatives, and why they show up first

Search this question and you mostly get cloud products, which is fair, because they answer more of it.

3D Print Log is a cloud print logger with a free account, slicer integrations that populate print details automatically, and analytics over print times, material use, and success rate. It is a log more than a cost engine, and it needs an account on someone else’s service.

FilamentManager is a hosted SaaS built around exactly the calculation this post stops short of: filament, power, machine time, and profit, with waste, handling, and tax on top. It bridges to Moonraker, OctoPrint, Home Assistant, and Bambu with an AMS through Home Assistant. The free tier covers 50 rolls and 2 printers, and the cost calculator sits in the €8 per month Pro tier, with tiers running up to €27 per month for a business plan. Checked August 20, 2026.

Neither can be self-hosted, which is the whole distinction. If the requirement is that no print data leaves your network, PrintStash plus Spoolman gives you the material half locally and leaves the rest to a spreadsheet. If the requirement is a finished quote with margin on it, a hosted calculator does more of the work and you accept the account.

Questions that come up

Do I need Spoolman to get a cost per print?

No, but without it the price side is a generic material preset rather than the actual roll. You can store material profiles in PrintStash directly and record an estimated cost, including on a print you log by hand. What Spoolman adds is the real purchase price per spool, remaining weight that stays correct because measured grams are written back, and a sensible answer when two spools of the same material cost different amounts. Both run on your own server, and the integration is off until a superuser enables it.

Which printers give a genuinely measured number?

Moonraker, and only Moonraker. Klipper reports what it consumed, PrintStash records it against the job, and that measured figure drives both the cost and the Spoolman write-back. OctoPrint, PrusaLink, Bambu LAN, and Elegoo Centauri do not report measured consumption, so their jobs keep the slicer’s estimated weight and PrintStash will not decrement inventory from a guess. Measured elapsed duration is a separate thing and does come back from more of them, which the compatibility matrix breaks down per provider.

Does the cost change if I update the filament price later?

Not for prints that already finished. Cost is resolved when a job completes and frozen on that record, so historical totals keep the price you actually paid at the time. New prints use the new price. This is deliberate, and it is the main reason a print history beats a spreadsheet where editing one cell quietly rewrites every past job.

Can I run all of this without a cloud account?

Yes, and that is the reason to choose it over the tools that rank above it. PrintStash and Spoolman are both self-hosted containers, there is no account, no telemetry, and no external service in the path. The trade is scope: you get material cost tied to a specific model, revision, printer, and spool, and you do not get electricity, machine amortization, or margin. Those you add yourself, or you accept a hosted calculator that does them for you.

Sources

  • PrintStash Spoolman guide for the one-way sync, read-only presets, per-print spool selection, /spool/{id}/use write-back, and the double-count check. The cost freeze at job completion was read from backend/app/db/models.py and backend/app/services/print_results.py in the repository.
  • Spoolman for the inventory side.
  • 3D Print Log and FilamentManager for the hosted alternatives, their integrations, and FilamentManager’s tier limits and prices. Both checked August 20, 2026.