Automation that
survives contact with reality.
Anybody can connect two apps in an afternoon. The interesting question is what happens on day two hundred — when the API rate-limits you, when a duplicate arrives, when someone renames a dropdown, and when the person who built it has left. We build for day two hundred.
Make, n8n, Zapier or code?
Four legitimate answers. The wrong one is chosen by habit; the right one is chosen by volume, data residency and who will maintain it.
| Platform | Best for | Strengths | Where it bites |
|---|---|---|---|
| Make.com our default |
Mid-market operations with branching, arrays and real error paths | Genuinely visual for complex flows. Iterators and aggregators handle array work natively. Data stores give you state. Error handler routes per module. Blueprints export as JSON so they can live in version control. Cheap per operation at scale. | The visual model gets unwieldy past roughly sixty modules — we split into sub-scenarios. Operations-based pricing punishes naive designs; budgeting matters. |
| n8n | Data residency requirements, heavy custom logic, high volume | Self-hostable in the EU or on your own infrastructure — decisive for some German clients. Arbitrary JavaScript or Python in a node. Execution priced by workflow, not per operation. Fair-code licence. | You now own hosting, upgrades, backups and uptime. Fewer polished native connectors than Make. Needs someone technical on your side or a managed arrangement with us. |
| Zapier | Simple linear A-to-B triggers, or teams already standardised on it | The broadest app catalogue in existence. Non-technical staff can build and maintain simple Zaps without help. | Branching, loops and error handling are weak. Task-based pricing escalates quickly. Complex logic becomes a chain of Zaps nobody can follow. Rarely the right base layer for an operations backbone. |
| Custom code | High-volume, latency-sensitive or genuinely bespoke logic | No platform ceiling, no per-operation cost, full testing and CI. We ship serverless functions — Cloudflare Workers, or a small typed service — where it is warranted. | Only your developers or we can change it. For most business-process automation this is over-engineering, and it removes the ability of an ops person to adjust a rule themselves. |
The patterns we build with
These are the specific decisions that separate an automation which quietly keeps working from one that quietly stops.
Idempotency before anything else
Every scenario that creates or updates a record must be safe to run twice. Webhooks get redelivered, humans re-trigger runs, retries fire after a timeout that already succeeded. Without idempotency, one afternoon of debugging produces four hundred duplicate deals.
- A deterministic external key per business object, stored on the target record
- Search-then-upsert rather than blind create
- A Make data store as a processed-event ledger for sources that offer no stable identifier
- Processed markers written after the side effect, never before
Error handling as design, not afterthought
Make gives you five error directives and most builds use none of them. We attach handlers per module and choose deliberately between them.
- Resume — substitute a safe default and continue, for genuinely optional enrichment
- Break — park the bundle in incomplete executions with automatic retry, for transient failures
- Rollback — undo a transaction where a partial write would be worse than none
- Ignore — used sparingly and only where the failure is expected and harmless
- Exponential backoff on 429 and 5xx, with a jitter interval so retries do not synchronise
- A dead-letter route: anything that fails after final retry lands in a table a human reviews, with the payload attached
Operations budget as a design constraint
Make bills per module execution. A scenario that loops one thousand records through eight modules costs eight thousand operations per run — and if it runs hourly, that is your entire plan by Wednesday. We design cost in from the start.
- Batch API calls instead of per-record HTTP requests wherever the endpoint supports it
- Filter as early as possible — the cheapest module is the one that never runs
- Aggregate before writing, not after
- Instant webhook triggers instead of frequent polling schedules
- A monthly operations forecast per scenario, and an alert when consumption deviates from it
State, not statelessness
Business processes have memory. Data stores hold it explicitly rather than smuggling it into a CRM field that someone will later repurpose.
- Deduplication ledgers and processed-event keys
- Cursor and watermark values for incremental syncs
- Rate-limit counters and circuit-breaker flags
- Lookup tables — territory mapping, routing rules, thresholds — editable by your ops team without touching a scenario
Observability by default
The failure mode that actually hurts is not a scenario that errors loudly. It is one that silently stopped running three weeks ago and nobody noticed.
- Failure alerts into a dedicated Slack channel with scenario name, module, error and a direct link to the execution
- A heartbeat scenario that verifies critical flows have run within their expected window and escalates when they have not
- Structured run logs written to a database for volume, latency and error-rate trends
- A weekly digest — executions, incomplete runs, operations consumed, top error types
Version control and environments
Automation is production software. It gets treated as such.
- Blueprints exported as JSON and committed to a Git repository on every meaningful change
- A separate staging organisation or team, with connections pointing at sandbox accounts
- Naming convention that encodes domain, direction and trigger, so a list of eighty scenarios is still readable
- A change log per scenario: what changed, why, by whom, when — the question "why does this do that?" has an answer
Composition over monoliths
One enormous scenario is impossible to test, impossible to reason about, and re-runs everything when one step fails. We decompose.
- Router branches split by business case, not by convenience
- Reusable sub-scenarios invoked over webhook with a defined payload contract — enrich company, notify owner, write audit entry
- Custom apps and IML functions where the same transformation appears more than three times
- Long-running work broken into queue-and-worker pairs, so a slow third party never blocks intake
Security and access hygiene
Automation platforms concentrate credentials for every system you own. That deserves attention.
- Connections owned by a company service account, never a personal login that leaves with the employee
- Least-privilege API scopes per connection, reviewed at handover
- Secrets in the platform's secure store or environment variables — never inline in a module
- Webhook endpoints protected with a shared secret or signature verification, and payload validation before processing
- Personal data minimised in scenario payloads and log retention shortened accordingly
What we most often build
Concrete flows, not categories. Most engagements start with three or four of these and grow from there.
Inheriting somebody else's automation
A meaningful share of our work is taking over an estate built by a freelancer who has moved on, or grown organically over three years without anyone owning it. The first engagement is always an audit before a single change is made.
- Inventory. Every scenario, its trigger, its schedule, its connections, its last successful run and its operations consumption.
- Dependency map. Which scenarios call which, which share a data store, and what breaks if one is switched off.
- Risk register. Missing error handling, personal connections, hard-coded credentials, silent failures, unbounded loops, absent deduplication.
- Cost analysis. Operations per scenario against business value. There is almost always a top-three consuming a disproportionate share for very little return.
- Remediation plan. Ordered by risk, with an estimate per item, so you can decide what to fix now and what to live with.
You probably need this if…
- Nobody can say with confidence what a given scenario does without opening it
- Connections are owned by someone who left the company
- Your operations consumption grows faster than your business does
- Failures are discovered by a customer complaining, not by an alert
- There are scenarios nobody dares switch off because the consequences are unknown
- The same logic appears in five places and has drifted apart in three of them
- "Incomplete executions" has a number in it that nobody has cleared in months
Automation questions we get asked most
How much can realistically be automated?
A useful mental model: sort every task by how much judgement it needs and how much variation it has. Low judgement and low variation — data entry, routing, notification, document assembly, status synchronisation, scheduling — automates completely and reliably. Medium judgement with structured inputs — classification, extraction, prioritisation, drafting — is where AI belongs, with a human approving output. High judgement — negotiation, design, exception handling, relationships — stays human and should.
In practice, for a mid-market commercial team, the honest number is that most of the administrative load around selling and delivering can go. The selling itself cannot, and any vendor telling you otherwise is selling you something.
What if Make goes down or changes pricing?
Two mitigations, both structural. Blueprints are exported to your repository, so the logic is documented in a portable form rather than trapped in an account. And the architecture keeps business rules in data stores and configuration rather than hard-coded into module chains, which is what makes a migration to n8n or code a re-implementation rather than an archaeology project. We have moved estates between platforms; it is work, but it is bounded work.
Can our own team maintain what you build?
That is the intended end state. Consistent naming, decomposed scenarios, inline notes on non-obvious steps, a written runbook per flow, and recorded walkthroughs of the ten most important ones. We also run handover sessions with whoever will own it.
Realistically, an operations-minded person can maintain and extend most of it after a couple of weeks. The parts that need us are custom apps, IML functions and anything cryptographic — and those are deliberately few and clearly marked as such.
How do you handle GDPR in automation?
By treating each scenario as a processing activity with a purpose, a lawful basis and a retention period. Practically: minimise personal data in payloads, keep special-category data out of automation entirely unless there is a specific documented basis, shorten execution-log retention on flows carrying personal data, run EU data centres where the platform offers the choice, ensure a Data Processing Agreement exists with every processor in the chain, and make deletion and export requests executable — a subject access request should be a scenario you run, not a fortnight of manual searching.
Do you work with our existing IT department?
Regularly, and it usually works well because the boundary is natural. IT owns identity, network, endpoints and the systems of record they already run; we own the process layer between those systems. What we need from IT is API access with appropriate scopes, a service account, and a review of anything that touches production data. What IT usually appreciates is that the result is documented and inspectable rather than a black box someone in sales bought on a credit card.
Name the process that wastes the most time.
Describe one workflow your team does by hand every week. We will sketch how we would automate it — modules, error paths, rough operations cost — on the first call.