n8n is genuinely excellent, and that's the trap. It's easy enough that a working prototype takes an afternoon, and prototypes get promoted to production by accident. Three weeks later a webhook silently fails at 2am, nobody notices for four days, and two hundred leads never reached the CRM.
Here's the checklist we run before any n8n build gets pointed at real customers.
1. Queue mode and a real database
The default SQLite setup is fine for evaluation and wrong for production. Move to Postgres, enable queue mode with Redis, and run workers separately from the main instance. Now a long-running workflow stops blocking everything behind it, and a restart doesn't lose in-flight executions.
2. Environments that aren't your live one
You need at least staging and production, with separate credentials. Editing a live workflow while it's executing is a habit that eventually costs someone a data migration. Use n8n's source control where you can, and keep workflow JSON in git regardless, it's the only real audit trail of who changed what.
3. Error workflows on every single flow
Every workflow gets an error workflow attached. Not one global handler that posts "something failed". A handler that reports the workflow name, the node, the error message and the input payload that caused it.
// Error handler → Slack message
Workflow: {{$json.workflow.name}}
Node: {{$json.execution.lastNodeExecuted}}
Error: {{$json.execution.error.message}}
Run: {{$json.execution.url}}
That last line matters more than it looks. Being one click from the failed execution is the difference between fixing it now and fixing it Thursday.
4. Retries with backoff, and idempotency to make them safe
Turn on retry-on-fail for every node that touches a network, with a sensible wait between attempts. Then make the retry safe: before writing, check whether this record already exists. Pass a deterministic key, an external ID, a hash of the payload, so re-running a batch updates rather than duplicates.
Retries without idempotency don't fix failures. They multiply them.
5. A dead-letter path
Some items will fail after every retry: malformed data, a genuinely invalid record, a third party having a bad day. Those items go to a dead-letter store, an Airtable table or a Postgres table is plenty, with the payload, the error and a timestamp. Once a week someone looks at it. Without this, failures are simply invisible.
6. Rate limits you respect on purpose
Use Split In Batches with a wait between batches rather than firing 500 API calls in parallel and discovering the provider's limit the hard way. Getting your production API key throttled during business hours is a memorable way to learn this.
7. Credentials that aren't one person's login
Service accounts, not the founder's Google account. Scoped tokens, not admin keys. Document which credential each workflow uses and when it expires, because an OAuth token quietly expiring is the single most common cause of "the automation just stopped working".
8. Observability, even if it's simple
Log every execution's outcome somewhere you can query: workflow name, duration, item count, status. A basic dashboard over that table answers the questions that actually come up, is it slower than last month, which workflow fails most, how many runs did we do, and gives you the numbers to prove the build paid for itself.
The uncomfortable ratio
On a typical production build, the happy path is maybe 30% of the work. The other 70% is error handling, idempotency, monitoring and credential hygiene. That's not overhead, that's the difference between a demo and infrastructure.
If a quote for automation work looks suspiciously cheap, this is usually the part that's missing. You'll pay for it later, at a worse moment.
Want this built, not just read?
Tell us the workflow that's eating your week. Thirty minutes, no deck.