n8n workflow-patronen
Gebaseerd op czlonkowski/n8n-skills @ 72470a0, licentie MIT
Dit bestand is door ToolBrain vertaald en inhoudelijk gewijzigd op 2026-08-30, op basis van
n8n-workflow-patterns SKILL.md uit czlonkowski/n8n-skills (MIT), zie de bron_url hierboven
en ../LICENSES/n8n-skills-MIT.txt.
Zes bewezen architectuurpatronen voor het bouwen van n8n-workflows, gedestilleerd uit een grote hoeveelheid echte workflow-gebruik. Gebruik dit overzicht om vóór je gaat bouwen het juiste basispatroon te kiezen in plaats van een workflow ad hoc in elkaar te klikken.
De 6 kernpatronen
- Webhook-verwerking (meest voorkomend) — Webhook ontvangen → valideren → transformeren → antwoorden/notificeren.
- HTTP API-integratie — Trigger → HTTP Request → transformeren → actie → foutafhandeling.
- Database-operaties — Schedule → query → transformeren → wegschrijven → verifiëren.
- AI-agent workflow — Trigger → AI Agent (model + tools + memory) → output.
- Geplande taken — Schedule → ophalen → verwerken → afleveren → loggen.
- Batchverwerking — Voorbereiden → SplitInBatches → verwerken per batch → accumuleren → aggregeren.
Wanneer welk patroon
- Webhook-verwerking: binnenkomende data van externe systemen, integraties (Slack-commands, formulieren, GitHub-webhooks), directe respons nodig. Voorbeeld: "Stripe-betaalwebhook ontvangen → database bijwerken → bevestiging sturen."
- HTTP API-integratie: data ophalen bij externe API's, synchroniseren met derde partijen, data-pipelines. Voorbeeld: "GitHub-issues ophalen → transformeren → Jira-tickets aanmaken."
- Database-operaties: synchroniseren tussen databases, periodieke queries, ETL. Voorbeeld: "Postgres-records lezen → transformeren → naar MySQL schrijven."
- AI-agent workflow: conversational AI, AI met tool-toegang, meerstaps-redeneren.
- Geplande taken: terugkerende rapportages, periodiek ophalen van data, onderhoudstaken.
- Batchverwerking: grote datasets die API-limieten overschrijden, resultaten accumuleren over meerdere API-calls, geneste loops (bijvoorbeeld meerdere categorieën × gepagineerde calls per categorie).
Bouwstenen die alle patronen delen
- Triggers: Webhook (instant), Schedule (cron), Manual (testen), Polling (intervallen).
- Databronnen: HTTP Request, database-nodes (Postgres/MySQL/MongoDB), service-nodes (Slack, Google Sheets), Code (custom JS/Python).
- Transformatie: Set (velden mappen), Code (complexe logica), IF/Switch (routering), Merge (datastromen combineren).
- Output: HTTP Request (API's aanroepen), database (schrijven), communicatie (mail/Slack/Discord), storage (bestanden/cloud).
- Foutafhandeling: Error Trigger (workflowfouten opvangen), IF (foutconditie checken), Stop and Error (expliciet falen), Continue On Fail (per-node instelling).
Checklist bij het bouwen van elke workflow
Planfase: patroon bepalen → benodigde nodes opzoeken → dataflow in kaart brengen (input → transform → output) → foutafhandelingsstrategie plannen.
Bouwfase: workflow met de juiste trigger aanmaken → databron-nodes toevoegen → authenticatie/credentials instellen → transformatie-nodes toevoegen (Set, Code, IF) → output-/actienodes toevoegen → foutafhandeling configureren.
Validatiefase: elke node-configuratie valideren, de complete workflow valideren, testen met voorbeelddata, edge cases afdekken (lege data, fouten).
Uitrolfase: workflow-instellingen controleren (uitvoervolgorde, timeout, foutafhandeling), activeren, de eerste runs monitoren, het doel en de dataflow documenteren.
Levenscyclus: valideren, verifiëren, testen — vóór activeren
Nodes bouwen is het begin, niet het einde. Loop vóór een workflow live gaat vier poorten door — en onthoud de hoofdregel: een geslaagde validatie is noodzakelijk, niet voldoende. Een workflow kan schoon valideren en toch items laten vallen, de verkeerde Merge-input pakken, of Slack-berichten als platte tekst posten. Schone validatie betekent dat de vormen kloppen, niet dat de logica klopt.
- Valideren. Draai de workflowvalidatie op de volledige JSON tijdens het bouwen, of op de levende instantie zodra de workflow bestaat. Los elke fout op en valideer opnieuw. Dit vangt schema-, node-configuratie-, expressie- en referentiefouten — de structurele laag.
- Verbindingen verifiëren. Haal de workflow op en lees het connections-object direct. Validatie bevestigt alleen dat verbindingen niet kapot zijn, niet dat ze correct zijn. Hier vind je de geldig-maar-fout bedrade zaken: een Merge waarvan de input-instelling niet overeenkomt met de aangesloten slot, een Switch-fallback die nergens naartoe gaat, een fan-out-tak die nooit verder is aangesloten, een foutuitgang die in het niets eindigt.
- Testen. Voer een testrun uit en inspecteer de output. Controleer of de outputvorm klopt met wat afnemers verwachten, of fan-outs allemaal data hebben opgeleverd, en (bij webhook-API's) of status/body/headers kloppen. Echte side effects vuren tijdens een test — schrijfacties committen, berichten worden verstuurd, externe API's worden echt aangeroepen. Heeft een node een gebruikers-zichtbaar effect, vraag dan eerst toestemming of test tegen veilige testdata.
- Activeren pas nadat de eerste drie stappen slagen. Activeer nooit direct na een schone validatie: een actieve workflow die data laat vallen of dubbel verstuurt is erger dan een die nooit gestart is.
Een poort overslaan ruilt een paar minuten nu in voor het debuggen van een live, mogelijk stateful, mogelijk verkeer-dragende workflow later. Die ruil is het nooit waard.
Dataflow-patronen
- Lineaire flow: Trigger → Transform → Actie → Einde. Voor eenvoudige workflows met één pad.
- Vertakkende flow: Trigger → IF → [waar-pad] / [onwaar-pad]. Voor acties afhankelijk van condities.
- Parallelle verwerking: Trigger → [tak 1] → Merge ← [tak 2]. Voor onafhankelijke operaties die tegelijk kunnen draaien.
- Loop-patroon: Trigger → Split in Batches → Verwerken → Loop (tot klaar). Voor grote datasets in stukken.
- Foutafhandelingspatroon: Hoofdflow → [succespad] / [Error Trigger → foutafhandeling]. Voor een aparte foutafhandelingsworkflow.
Batchverwerkingspatroon
De SplitInBatches-loop
De SplitInBatches-node splitst een grote dataset op in kleinere brokken. De twee outputs zijn cruciaal om te begrijpen:
main[0]= done — vuurt ÉÉN keer, nadat alle batches klaar zijn.main[1]= per batch — vuurt per batch (dit is het lichaam van de loop).
Items voorbereiden → SplitInBatches → [main[1]: batch verwerken] → (loopt terug)
[main[0]: done] → Limit 1 → aggregerenZet altijd een Limit 1-node na de done-output.
batchSize kiezen (de kostenknop)
Een SplitInBatches-loop draait zijn hele body opnieuw per iteratie — ongeveer 0,8 ms/iteratie
engine-overhead plus de kosten van de body zelf — dus de totale kosten zijn ruwweg
⌈items / batchSize⌉ × (overhead + body). batchSize is dus direct een snelheidsknop:
- Kies de grootste batch die je echte beperking toelaat (API-paginagrootte, rate limit, geheugen). Grotere batches = minder iteraties = minder overhead; de body ziet nog steeds elk item.
batchSize: 1is het dure uiterste — een volledige engine-pass per item. Gebruik dit alleen als je echt per item moet handelen (geneste-loop-besturing, of een API die precies één ID accepteert).- Loop je alleen om "over de items heen te gaan" zonder externe beperking, dan heb je meestal helemaal geen loop nodig — één Code-node die alle items in één keer verwerkt is veel goedkoper.
Data tussen iteraties
Na de loop geeft een verwijzing naar een node binnen de loop alleen de items van de laatste
batch terug. Om over alle iteraties te accumuleren gebruik je $getWorkflowStaticData('global')
in een Code-node binnen de loop.
Geneste loops
Bij N categorieën × M items per categorie (waarbij een API een batchlimiet heeft):
Categorieën definiëren (N items)
→ Buitenste loop (SplitInBatches, batchSize=1)
→ Categoriedata voorbereiden
→ Binnenste loop (SplitInBatches, batchSize=1000)
→ API-call → Verifiëren → (terug naar binnenste loop via main[1])
→ Binnenste done[0] → Rate-limit vertraging → terug naar buitenste loop
→ Buitenste done[0] → Limit 1 → EindaggregatieBedradingsvalkuil: de binnenste done[0] moet terugkoppelen naar de INPUT van de buitenste loop, niet naar de aggregatie. De buitenste done[0] voedt de eindaggregatie.
API-paginering
Voor API's zonder multi-ID-filtering: gebruik een id_from plus datumvenster voor efficiënte
paginering — Schedule → datumvenster zetten → pagina ophalen → verwerken → IF meer? → ja:
id_from bijwerken en opnieuw ophalen, nee: aggregeren en output.
Dry-run-tolerantie
Bij testen met API-schrijfnodes uitgeschakeld (voor dry-runs) krijgen verificatienodes de
requestbody in plaats van de response. Maak de verificatie daar tolerant voor: check of het
object op een request lijkt (heeft method en parameters, geen status) en geef dan expliciet
"SKIPPED — upstream disabled for testing" terug, anders de normale verificatie.
Performance op het hot path
Bij workflows die duizenden items verwerken met weinig I/O, wordt de snelheid bepaald door hoe vaak n8n een per-item/per-iteratie-grens oversteekt — elke oversteek zet een executiecontext op en kopieert de items. Vier architectuurkeuzes domineren:
- Kies liever weinig, grotere All-Items-nodes boven lange transformatiekettens. Elke node-naar-node-stap kopieert alle items opnieuw (~0,05 ms/item per stap), dus zes geketende Code/Set-nodes kosten ~7× zoveel als één All-Items-Code-node die hetzelfde doet.
- Gebruik Code "Run Once for All Items", niet "Each Item" — ~0,02 ms/item versus ~0,6 ms/item (25-30× verschil). Een keten van Each-Item-Code-nodes is het slechtste geval.
- Maximaliseer batchSize in SplitInBatches-loops — iteraties zijn de kostenpost.
- Micro-optimaliseer geen expressies — complexiteit is gratis; nodes en iteraties kosten.
Maar profileer eerst. De meeste productieworkflows zijn I/O-bound — opeenvolgende HTTP-/ DB-/Sheets-calls (honderden ms elk) overschaduwen al het bovenstaande. Deze regels tellen als transformatiewerk de bottleneck is, of als een anti-patroon (Each-Item Code, batchSize 1, lange per-item-ketens) een goedkope operatie traag maakt. Onder een paar honderd items maakt het niets uit.
Integratie-specifieke valkuilen
Google Sheets: gebruik nooit append op sheets met formulekolommen (breekt formules) — gebruik
in plaats daarvan de Google Sheets API values.update (PUT) via een HTTP Request-node met een
googleApi-credential. Schrijf getallen, geen strings, in formule-afhankelijke kolommen (string
"4,98" breekt ADD()-formules). Google Sheets-nodes draaien per input-item — voor één bulk-write
eerst accumuleren in een Code-node. UNFORMATTED_VALUE geeft getallen terug, geen tekst zoals
"N/A" — filter dit expliciet in Code-nodes.
Google Drive: convertToGoogleDocument: true maakt een Google Doc (tekst), GEEN Google
Sheet — voor een downloadbare CSV laat je die optie helemaal weg. Gebruik voor een
CSV-downloadlink het formaat https://drive.google.com/uc?id={fileId}&export=download in plaats
van een /view-link.
Tweerichtings-drempelcontrole: check bij het vergelijken van waarden (prijzen, aantallen,
metrics) altijd beide richtingen — een check die alleen diff > threshold toetst, mist crashes;
Math.abs(diff) > threshold vangt zowel pieken als dalen, want beide zijn signalen van een
datakwaliteitsprobleem.
Veelvoorkomende valkuilen
- Webhook-datastructuur: payloaddata staat genest onder
$json.body, niet direct onder$json. Zie de skill over expression-syntax. - Meerdere input-items: gebruik "Execute Once" of pak alleen het eerste item.
- Authenticatieproblemen: configureer credentials in de credentials-sectie, niet als parameter, en test ze vóór activatie.
- Uitvoervolgorde van nodes: check workflow-instellingen → Execution Order (v0 = top-naar- onder/legacy, v1 = verbindingsgebaseerd/aanbevolen).
- Expressiefouten: gebruik
{{ }}rond expressies, anders verschijnen ze als platte tekst.
Samenvatting
Zes kernpatronen dekken het overgrote deel van de praktijkgevallen. Webhook-verwerking is het vaakst voorkomende patroon. Gebruik de bouwchecklist voor elke workflow: patroon plannen → nodes selecteren → bouwen → valideren → uitrollen. Combineer dit met de skills voor expression-syntax, validatie en node-configuratie voor complete workflowontwikkeling.
Praktijkvoorbeeld (NL)
Een Nederlandse installatiebedrijf met vijftien monteurs gebruikt n8n om binnenkomende serviceaanvragen via een contactformulier op de eigen website automatisch te verwerken. Dit is in essentie het webhook-verwerkingspatroon: de webhook ontvangt de formulierdata, een Set-node valideert of postcode en telefoonnummer aanwezig zijn, een IF-node routeert spoedgevallen (trefwoord "lekkage" of "storing" in de omschrijving) direct naar een Slack-kanaal voor de planning, terwijl reguliere aanvragen in een Postgres-tabel worden weggezet voor de volgende ochtendplanning. Omdat de piekbelasting rond negen uur 's ochtends soms tientallen aanvragen tegelijk oplevert, is bewust gekozen voor één grote transformatiestap in plaats van een lange keten van losse Set-nodes, precies volgens het advies hierboven om per-node-overhead te vermijden.