n8n sub-workflows: när du ska bryta ut logik och hur du strukturerar återanvändbara moduler
Det vanligaste misstaget i n8n-projekt som växt utanför proof-of-concept: all logik i ett enda monolitflöde. Det fungerar. Det är oanvändbart vid felsökning.
Sub-workflows löser detta. Men de används felaktigt lika ofta som de utelämnas.
De tre signalerna att bryta ut
Signal 1: Duplicerad logik. Om samma sekvens av noder — t.ex. “hämta kunddata från CRM, validera att fälten finns, formatera för nästa steg” — finns i tre olika flöden, ska den vara ett sub-workflow. Varje ändring i den logiken kräver annars tre parallella uppdateringar.
Signal 2: Flödet överstiger ~30 noder. Det är ingen hård gräns, men ett 45-nods flöde har en kanvas du inte kan hålla i arbetsminnet. Operationella gränser — var ett webhook-svar skickas, var felhanteringen börjar, var externa API-anrop sker — försvinner i bruset.
Signal 3: Felhanteringen kräver eget flöde. Om din felberedskap är mer komplex än “lägg i kö och skicka Telegram-notis” är den komplex nog att separera. En Error Trigger-nod som kör ett dedikerat felflöde håller primärflödet rent.
Hur du passar data — och varför delat tillstånd inte fungerar
n8n sub-workflows kommunicerar via den explicita inputData-parametern i Execute Sub-workflow-noden. Ingenting annat.
{
"customerId": "{{ $json.customerId }}",
"orderId": "{{ $json.orderId }}",
"amount": "{{ $json.amount }}"
}
Sub-workflowet startar med dessa fält i $json. Det kan returnera data via standardutdatan från den sista noden.
Varför inte globala variabler eller external state? Testbarhet. Om ett sub-workflow beror på externt tillstånd kan du inte testa det isolerat. Du måste köra hela föräldraflödet i rätt kontext. Det skapar exakt den koppling du försökte undvika.
Namnkonvention
Verb-substantiv i lowercase med bindestreck:
skicka-telegram-notisvalidera-kunddatahämta-order-från-crmtransformera-till-faktura-format
Det möjliggör sökning. När du om sex månader felsöker ett produktionsflöde och behöver hitta “det flödet som validerar kunddata” hittar du det i n8n:s sökfunktion utan att öppna varje flöde.
Felhantering i sub-workflows
Tre mönster, i ordning efter komplexitet:
Mönster 1 — Propagera. Sub-workflowet hanterar ingenting, låter fel kastas upp. Föräldraflödet fångar via Error Trigger. Enkelt, men föräldraflödet måste kunna skilja på “sub-workflow misslyckades” och “API-timeout”.
Mönster 2 — Hantera och returnera statuskod. Sub-workflowet fångar fel med Try/Catch-mönster (IF-nod på error-output), returnerar { "success": false, "error": "Kundnummer saknas" }. Föräldraflödet branchar på success-fältet. Renare kontrakt.
Mönster 3 — Hantera och notifiera. Sub-workflowet fångar fel, skickar en Telegram-notis, returnerar statuskod till förälder. Används för kritiska operationer där felet behöver mänsklig uppmärksamhet men föräldraflödet ska fortsätta.
Välj mönster 2 som standard. Det ger ett tydligt kontrakt utan att koppla sub-workflowet till din notifieringsinfrastruktur.
Praktiskt exempel
Ett skicka-telegram-notis sub-workflow som anropas från fem separata automationer: daglig analytics-rapport, betalningsbekräftelse, felnotifikation, ny task, och innehållspublicering.
Sub-workflowet tar emot { "message": "...", "topicId": 4 }. Det formaterar och skickar. Inget mer.
När Telegram lade till rate limiting för bots behövdes uppdatering på ett enda ställe — inte fem.
Vanliga frågor
Hur stor bör ett sub-workflow vara?
En atomisk operation: en sak, beskrivet av ett verb-substantiv-namn. Om du tvekar på vad du ska kalla det är det förmodligen för stort — dela upp det.
Kan sub-workflows anropa varandra?
Ja, men var försiktig med djupa kedjor. Fel sprids uppåt men exekveringshistoriken visar bara ett steg i taget. Håll kedjedjupet under tre nivåer för att behålla felsökbarheten.
Saktar sub-workflows ner exekveringen?
Minimalt. Varje anrop till Execute Workflow lägger till ett litet overhead för workflow-uppstart. I praktiken är det omärkbart — nätverksfördröjning och externa API-anrop dominerar alltid exekveringstiden.