← Blog

Managing a mixed Klipper and OctoPrint fleet

One library for machines that speak different protocols: what each provider lacks, how to keep 0.4 and 0.6 slices straight, and why cost data differs.

guidemulti-printeroctoprintklipper

A fleet that grew by accident tends to speak three protocols. The Voron runs Klipper behind Moonraker, the older Ender sits behind an OctoPrint box that has been reliable for years, and something newer arrived with its own app. One library can drive all of them, and the part that needs planning is not the connection. It is that a file which is correct for one machine is wrong for the next one, and no amount of shared dashboard fixes that.

The connection side is quick: add each printer with its own address and credential, and PrintStash disables the actions a given provider cannot perform rather than failing when you try. What follows is about the files.

What actually differs between providers

Moonraker is the stable provider and the only one that reports measured filament use back from a finished job. Measured elapsed duration is a separate field, and PrusaLink, OctoPrint, and Elegoo Centauri return that one too, though only Moonraker’s has been checked against real prints. OctoPrint and PrusaLink are beta and cover the daily loop: live status, upload from the library, start, job control, and a remote file inventory you can list and prune. Bambu LAN accepts plain-text uploads and an opt-in start but exposes no file inventory. Elegoo Centauri accepts chunked uploads, starts files, and provides controls, but upload is still beta and file inventory is disabled.

Those four sentences decide most of your workflow. The compatibility matrix has the per-capability grid, and it moves with releases, so check it rather than memorizing this paragraph.

One model, one revision per machine

The useful pattern for a mixed fleet is that a slice belongs to a machine, and the library should say which. Keep each variant as a revision of the same model rather than as separate entries, and put the machine in the label: 0.6 nozzle, farm A, 0.4 nozzle, desk Ender, PETG on the Voron.

Two library behaviors make that pay off. The parsed slicer metadata already carries the printer profile and nozzle diameter from the file itself, so filtering by printer model finds candidate revisions without reading any labels. And exactly one revision on a model holds the recommended marker, which is the right shape for a single-printer library and a poor fit for a fleet, because two slices can both be correct for different machines. Let the marker mean “print this if you had to pick blind” and let the labels carry the machine-specific truth.

Nothing in the queue checks this for you. Routing does not score jobs by loaded filament, nozzle diameter, or plate compatibility, so sending an ABS slice to the machine with PLA loaded is a mistake the software will happily execute. Sending G-code to multiple printers covers how routing does behave, and queueing and scheduling across a printer farm has the eligibility rules and the fleet API.

Working around the two awkward providers

A printer with no upload path, like the Elegoo Centauri before v0.11.3, still fits, but the file gets there another way: copy it over the machine’s own interface or a USB stick, then use PrintStash to start it and record the job. Treat the library as the source of truth for what the file is and the printer as a dumb executor.

A printer with no remote inventory, which is Bambu LAN’s gap, means PrintStash cannot tell you what is currently sitting on the machine. Uploading the same file twice is then a real possibility, so name revisions deliberately and check the printer’s own screen when it matters. On the providers that do expose an inventory, syncing it before a send is a two second habit that prevents printing last week’s version.

Cost and history are not comparable across the fleet

This is the part that surprises people, and it is specifically about filament. Moonraker reports actual filament use when a job finishes, so those jobs carry a measured figure. Every other provider falls back to the slicer’s estimate, which is a different kind of number wearing the same units. Elapsed duration is the exception that behaves better: PrusaLink, OctoPrint, and Elegoo Centauri report that back as well, so the clock is comparable across the fleet in a way the grams are not.

The consequence is that a per-print cost of 84 grams from the Voron and 79 grams from the OctoPrint machine are not evidence about which machine is more efficient. One is weighed, the other is predicted. If you are tracking cost seriously, either compare within a provider or treat the estimated rows as rough. Spoolman consumption write-back has the same boundary: it is Moonraker-only, because it depends on the measured figure.

Print history does attach to the revision on every provider, so “which slice ran on which machine, and did it work” stays intact regardless. Moonraker can additionally import a printer’s existing history onto matching models, which backfills jobs from before the library existed.

Who can touch which machine

Access is granted per printer: view, print, control, or admin on each machine independently, and printing also requires edit rights on the model’s collection. In a mixed fleet this matters more than in a uniform one, because the machines usually differ in how much trust they have earned. The shared OctoPrint printer in the garage can be print-only for everyone, while the Voron in mid-calibration stays view-only until you are done with it.

A routine that survives a mixed fleet

  1. Slice for a specific machine and let the metadata record which one.
  2. Land the file in the library, by hand or through the OrcaSlicer hook, and attach it to its model as a revision with the machine in the label.
  3. Before sending, filter revisions by printer model and confirm the nozzle and material match what is actually loaded.
  4. Sync the printer’s file inventory where the provider supports it, then upload without auto-start on anything unfamiliar.
  5. Start the job, then watch the first layer in Mainsail, Fluidd, or OctoPrint. A library is not a monitoring tool.
  6. Record the outcome, and read measured numbers as measured only on Moonraker.

Questions that come up

Can one library drive Klipper and OctoPrint printers at the same time?

Yes. Each printer is configured with its own provider, address, and credential, and they appear on the same dashboard with the same library behind them. Moonraker printers connect with a URL, usually on port 7125, and OctoPrint printers with the instance URL plus an application key. What differs is the capability set rather than the setup: the app declares per provider what it can do and disables the rest, so a mixed dashboard has some buttons greyed out on some machines.

Does an OctoPrint machine get the same features as a Klipper one?

Nearly, with two real gaps. OctoPrint covers live status, upload from the library, start, pause, resume, cancel, and a remote file inventory including deletion. What it does not do is report measured filament consumption back, so those jobs record the slicer’s estimate for grams and cost, and it does not accept raw G-code or an emergency stop through PrintStash. Elapsed duration does come back from OctoPrint, so the gap is narrower than it sounds: it is the material figure you cannot trust, not the clock. The provider is also beta rather than stable, which means shipped and usable with less hardware coverage behind it than Moonraker.

How do I keep 0.4 and 0.6 nozzle slices from getting mixed up?

Keep both as revisions of one model, put the machine and nozzle in each revision label, and rely on the parsed nozzle diameter for filtering. Both can be marked known good at once, since the outcome is per revision. Only one can be recommended, so give that marker to the slice you would print if you had to choose without thinking, and treat the labels as the real answer. The routing layer will not catch a mismatch, so the check happens when you pick the revision.

Why do costs look inconsistent between machines?

Because they come from different sources. Moonraker returns what the printer actually used, and every other provider falls back to what the slicer predicted. Estimates and measurements diverge for the usual reasons: purge lines, a partial failure, a spool change mid-print, or a slicer profile that has drifted from reality. Compare within a provider, and treat cross-provider comparisons as indicative. Spoolman write-back stays Moonraker-only for the same reason.

Can I stop someone printing on one specific machine?

Yes. Per-printer access grants view, print, control, or admin on each printer independently, and the queue and routing APIs enforce the effective role rather than only hiding buttons. A machine under maintenance can also be taken out of routing with a maintenance window or soft-drain mode, which stops new work from landing on it without cancelling the job it is currently running.

Sources

For adding machines one at a time, connecting multiple Klipper printers covers the Moonraker side and connecting OctoPrint covers the key handling that trips people up. If the fleet is uniform Klipper, the Klipper farm walkthrough is a better starting point than this page.