Built a fleet manager for agencies running n8n across many client instances

Most people running n8n for clients end up with one instance per client, separate and client-owned, which is the sane call for isolation and roughly what the license nudges you toward anyway. The catch is that past a few clients it gets painful: the same workflow change redone on every instance, credentials rebuilt on each one, and failures that surface when the client notices before you do.

There wasn’t really a tool for managing the whole fleet, so I built one. It works over the standard public API and doesn’t host or bundle n8n, so it stays clear of the Sustainable Use License. Roughly what it does:

  • Keep a golden version of a workflow and push it to whatever instances you pick, with each client’s own credentials injected and per-client variables filled in. If one instance fails, the rest still go.
  • Drift detection for when someone hand-edits a deployed workflow. It compares a canonical hash so per-client creds and variables don’t count, only real edits, and you get a diff plus a one-click re-sync.
  • Fleet-wide execution polling with failure alerts (Telegram or webhook), and a basic monthly per-client report: runs, success rate, hours saved.

A few things I ran into building it, in case it helps anyone:

  • n8n rewrites a workflow on save (settings defaults, version metadata, node ids), so you compare the canonical form of what the API returns, not what you sent, or everything looks drifted.
  • Webhook nodes need a webhookId or the deployed webhook 404s. The editor adds one for you, the API doesn’t.
  • No “run workflow” endpoint on the public API, so you trigger through the production webhook.

It’s a product (Flotilla), but there’s a free tier (2 instances) and you can point it at a workflow you
already run to watch it for drift without deploying anything, so it’s quick to try:

Still early. Mostly I want to know if this is a real pain for people here, or if I’ve misjudged it. Happy
to dig into the drift or credential side if anyone’s curious.

Dashboard:

Drift diff:

1 Like

This feels like the deploy/control-plane half of agency ops. The part I would keep separate is the support record after a push: which client got which version, what broke after deploy, what got fixed, and what can be shown back to the client later. That is basically the lane I am testing with Maintain Flow: not fleet management, just the check → issue → fix note → report layer after workflows are live.

1 Like

Yeah, that split makes sense to me. Flotilla touches the post-deploy side a little, it polls executions, alerts on failures, keeps an audit log of which instance got which version, and does a basic monthly per-client report, but you’re right that a real support record is a different job from deploy plus drift. Deploy and drift are state in the moment; “what broke after this push, what we did, what the client sees” is a timeline, and stapling those two together in one tool gets muddy fast. The part I found genuinely hard is attribution: tying a failure back to a specific deploy/version instead of just “this workflow errored today”. How are you handling that in Maintain Flow, keying the record to the workflow version or to a time window around each push? Curious how you frame the fix-note to client-report handoff too.

1 Like

Good question. I would track both, but I would not pretend the attribution is cleaner than it is.

If the agency has a deploy id / workflow version / change note, the issue should attach to that. If not, I would key it to the time window around the push or failed check and show that honestly as “this happened after X change / during Y window”.

The handoff I want is simple: failed check → issue → fix note → follow-up check → report line. The client report should say what broke, what changed, what evidence confirmed it, and what is still being watched.

So Maintain Flow is less “this deploy definitely caused it” and more “here is the support timeline and confidence level”. Exact version attribution is great when the upstream tool gives it, but the report still has to be useful when all you have is time-window evidence.

When a client has intentionally modified part of your golden workflow, what happens when you release a new version of the golden workflow?

Nope, it just overwrites. No merge. Push v2 and whatever they hand-edited is gone.

Saving grace is you find out before the push, not after. Stuff that’s supposed to differ per client (creds, endpoints, whatever values) is a variable in the template and gets re-rendered on every deploy, so that never shows up as drift. Actual hand edits do, and the diff is against what got pushed to that specific instance, not the raw golden, so you’re looking at their change and not a wall of noise.

So realistically you scan before a rollout, see who’s got real edits, deal with them one at a time. Usually ends up either “ok that change is actually good, pull it into the golden behind a variable so only the clients who want it get it”, or “yeah this one’s a fork now, skip it on the push”.

I did look at doing a proper merge and noped out. Three-way merging a graph where node ids and connections all point at each other seemed like a great way to ship something that looks fine and quietly isn’t. Rather have it be dumb and loud tbh. Might regret that, ask me in a year.

You hitting this right now? How many instances are you on, and what do you do currently when a client edits something you own? That’s the bit I’m least sure I got right.

Late as hell, sorry.

Yeah, agree on the confidence thing. “This happened in the window around X change” is way more useful to a client than a confident “this deploy caused it” that’s wrong once and then they stop trusting the report at all.

fwiw the upstream bit you’re describing does exist on my side. Every deploy stores the template version, a snapshot of exactly what went to that instance, and an audit row with a timestamp. So deploy id + what actually changed is already sitting there, not something you’d have to reconstruct. Whether the two ever meet, dunno, but it’s not missing.