Sebastiano Druda

← Back to writing

Essay / AI & Automation

n8n Is Great Until Your Workflow Becomes a Product

Visual workflows can coordinate useful work without owning each rule. Examine testing, recovery and the point where domain logic deserves its own boundary.

The first version is easy to explain. A form arrives, a record is created, somebody gets a notification. The workflow fits on one screen. Each node has a recognizable purpose. You can show the diagram to a colleague and talk about the work without opening an application repository.

Then a customer asks for a different approval rule. Another needs a separate account. A failed notification must be retried, but the record must not be created twice. Someone changes a field in the upstream system. Soon the diagram contains a product’s behavior, even though nobody has decided to operate it as a product.

That transition is the interesting part. I do not think it makes n8n the wrong tool. It changes the questions the tool needs to answer, and the responsibilities that should sit around it.

Low-code is not low-complexity. It changes where the complexity lives.

The diagram has become a contract

Consider a hypothetical service that turns incoming supplier requests into approved catalogue updates. At first, a person reviews every request. The workflow gathers the attachments, creates a task, and sends a message. Its responsibility is coordination.

Now imagine that approval becomes automatic for some suppliers. The workflow decides whether a price change is acceptable, which catalogue fields may be overwritten, and whether missing information should block publication. Those are domain rules. Their correctness matters independently of the order in which connectors happen to run.

A useful diagnostic question is whether you can explain and test a rule without opening the workflow editor. If you cannot, the visual graph may have become the only specification of the product. That is manageable for a small rule set, but it becomes expensive when several workflows must agree about the same decision.

Keep orchestration legible

An orchestration layer should make the sequence of work understandable: receive a request, validate its identity, obtain a decision, apply the result, and record the outcome. It can also express timeouts, waiting, and escalation. Those responsibilities are substantial; they do not become trivial because the interface is visual.

What I would avoid is burying a complicated pricing policy inside several expression fields and copied code nodes. The problem is not the presence of code. It is that the rule becomes difficult to locate, review, reuse, and change consistently.

A small function or service can own that policy while n8n continues to coordinate the surrounding work. The boundary might accept a proposed update and a policy version, then return an explicit decision with reasons. It need not begin as a network service. The appropriate packaging depends on how the workflow is deployed and what must share the rule.

Extraction should follow evidence. Moving three straightforward conditions into a separate service can add deployment and monitoring work without buying useful clarity. Start by naming the rule and its inputs. Extract it when reuse, testing, or change frequency makes the boundary worthwhile.

Recovery needs business meaning

An execution marked failed tells an operator where the engine stopped. It does not necessarily tell them what happened in the outside world. The supplier record may already exist. The catalogue may already have changed. The acknowledgement may have disappeared while the receiving system completed its work.

n8n documents error workflows that can respond to failed executions, including an Error Trigger and execution information. That provides a mechanism for handling failures. The application still needs to decide which failures are safe to retry and which require reconciliation.

For the catalogue example, I would give each requested change a stable operation identifier. Before retrying a write, the workflow should be able to check whether that operation has already been applied. Where the destination supports idempotency, use its documented contract. Where it does not, design a specific reconciliation procedure instead of assuming every connector call can be repeated.

This connects directly to reliability after the happy path. Recovery is part of the feature. An operator needs a way to distinguish failed, completed, and uncertain work, especially when a retry could create a second external effect.

Test decisions and journeys separately

A workflow screenshot is a poor test specification. It shows the current implementation, so a test built only around the screenshot risks protecting the arrangement of nodes rather than the intended outcome.

I would start with examples of business decisions. An unapproved supplier cannot publish a change. An invalid currency produces a useful rejection. Repeating the same request does not create another catalogue operation. A notification outage does not reverse a completed approval. These examples remain meaningful even if the graph is rearranged.

Then test the connectors and the complete journey with controlled accounts and representative payloads. A successful mocked policy test cannot prove that a remote API accepts the actual request. Conversely, one successful live execution cannot cover all the policy boundaries.

Keep a small set of redacted fixtures for malformed, incomplete, duplicate, and delayed input. Record which version of the rule produced the expected result. This makes changes reviewable without retaining an unnecessary archive of sensitive production payloads.

Credentials are part of the design

A shared credential can make a prototype convenient and a production incident confusing. If multiple customers or departments use the workflow, the identity behind each operation must be deliberate. Which account can read an attachment? Which account can publish a catalogue update? Can the workflow access more than its job requires?

Those questions should be answered before copying an execution into another environment. Development must not accidentally send real notifications or modify the live catalogue. A test credential should be visibly different in purpose and restricted in capability, not merely stored under a different display name.

n8n’s source control and environments documentation describes mechanisms for managing workflow changes across environments. Check the capabilities available in the actual installation. Versioning a workflow is useful, but it does not automatically recreate external accounts, destination data, permissions, or every operational dependency.

An environment inventory should therefore describe those dependencies alongside the graph. That inventory is also valuable when a workflow must be restored by somebody who did not build it.

Observe the request, not only the execution

A user cares whether their catalogue change was accepted and published. An operator may need several execution records to reconstruct that journey. Connecting those views requires a stable request identifier and meaningful state transitions.

Useful operational records might include received, awaiting review, approved, applied, and acknowledged. Keep technical attempt counts separate from business status. Three attempts can still represent one completed request, and a successful HTTP response can still contain a rejected business operation.

Measure queue age and unresolved uncertainty as well as execution failures. A workflow that never crashes but leaves requests waiting indefinitely is not healthy from the user’s perspective. Alerts should point toward a decision somebody can make, such as replaying a notification or investigating a missing destination record.

Avoid logging entire documents by default. A request identifier, policy version, outcome, and carefully selected diagnostic fields often provide a better starting point. Add payload access only where the investigation needs it and the retention policy permits it.

A workflow becomes easier to operate when its business state can be explained without replaying every node.

Know what moving would involve

Portability does not require abandoning the platform. It means understanding which parts of the system belong to it. List the triggers, connectors, schedules, state stores, credentials, and domain rules that an alternative implementation would need.

A useful exercise is to take one representative request and describe its contract in plain language. What arrives? What decision follows? Which external effects are allowed? What evidence proves completion? If those answers exist only in screenshots, migration will involve rediscovering the product.

The same exercise improves today’s implementation. It exposes copied rules, hidden dependencies, and ambiguous recovery. The result may be a decision to keep everything in n8n, supported by clearer tests and operating procedures. It may be a decision to extract one rule while retaining the orchestration.

That is the threshold I care about: not whether a diagram looks sufficiently technical, but whether the system has explicit contracts and a credible recovery path. Visual tooling can remain a strong part of a product. It just cannot take responsibility for decisions the team has never made.

Sources

  1. n8n: Error handling — checked 2026-10-13
  2. n8n: Source control and environments — checked 2026-10-13

Topics