The anatomy of a published n8n template
Everyone has a feeling about how big a “normal” n8n workflow is. Nobody has published the number. So we measured every public template on n8n.io — all 10,957 of them.
By Muhammad Muneeb · · Pixtex research
Every one of the 11,015 template ids listed on n8n.io was requested. 58 of them return nothing — the template API answers 404 for 48 and 400 for 10, and every one of the 58 public template pages answers 404 — so those ids are withdrawn rather than missed. That leaves 10,957 templates that still exist, all of which are measured here. This is a census, not a sample, so nothing here carries a sampling error. Each workflow was parsed with the same code that renders it in the Pixtex editor. Sticky notes are annotations, not steps, so they are excluded from node counts and reported separately. Measured 2026-07-28.
What this is not. Templates are written to be shared, so they skew simpler than production workflows, and the AI share is inflated because AI templates are what people publish right now. Read every figure below as the anatomy of a published template, not of the workflow running in your instance.
How big is a workflow?
The median public template has 12 nodes. The mean is 15.1, pulled up by a long right tail — the largest template measured has 213. Half of all templates sit between 8 and 18 nodes; one in ten is above 27.
That tail is why this site exists, though the connection is an opinion rather than something measured here: nothing in this dataset records legibility, and we did not test it. What the distribution does say is that a template at the 90th percentile carries 2.3× the nodes of the median one, and the top percentile 5.3× — so whatever size defeats a screenshot for you, a real share of the library sits past it.
How connected are they?
The average workflow has 15.1 connections — about 1 per node. That close to one means most workflows are predominantly linear chains with a few branch points, rather than dense graphs.
52.5% contain an if or switch, and 19.6% bring paths back together with a merge. Splitting is common; rejoining is not.
Connection figures are measured on 10,951 of the 10,957 workflows. 6 store their connection map in an older or hand-edited format this analysis will not guess at, so they are left out of these two numbers only — their node counts are still included everywhere else.
How workflows start
The schedule trigger leads at 30.5%, with manual behind it at 22.9% — no single entry point accounts for even half the library. Percentages sum to more than 100 because a workflow can have several triggers.
0.7% of templates have no trigger node at all — fragments published as building blocks rather than runnable workflows.
What is inside them
Start with the top of the ranking below, because it is not what n8n's positioning would lead you to expect: the single most-used node in the template library is the plain Code node, in 54.1% of templates. More published templates contain hand-written JavaScript than contain any integration.
Two more figures are worth sitting with. The first is AI: 55.5% of public templates contain a LangChain node, which makes AI orchestration an ordinary part of the library rather than a category within it. That figure gets quoted more than anything else here, so the exact rule and every node type it matched are listed below — and note what it excludes: a hand-rolled HTTP call to an LLM API is not counted, and neither is the base-package OpenAI node.
The second is error handling. Only 14% of templates configure a non-default onError anywhere — nearly every published workflow assumes every step succeeds, which is worth knowing before you run one in production.
Sticky notes go the other way: 91.1% of templates carry at least one, averaging 6.1 where present. Authors publishing a workflow for other people to read annotate it far more readily than they guard it — which is exactly why a rendered diagram keeps them.
The most-used nodes
1,064 distinct node types appear across the library. These are the ones that show up in the most templates — core building blocks included, because the shape of the list is the point.
| node type | of templates | total uses |
|---|---|---|
| code · base | 54.1% | 16,628 |
| set | 52.5% | 12,806 |
| httpRequest | 50.3% | 15,182 |
| if | 45.1% | 9,099 |
| agent | 33.9% | 5,657 |
| googleSheets | 33% | 8,494 |
| scheduleTrigger | 28.2% | 3,435 |
| lmChatOpenAi | 23.6% | 4,254 |
| manualTrigger | 22.9% | 2,518 |
| gmail | 20.5% | 3,627 |
| merge | 19.6% | 3,139 |
| webhook | 18.1% | 2,341 |
| splitInBatches | 17.8% | 2,486 |
| wait | 17.7% | 3,072 |
| outputParserStructured | 16.4% | 2,648 |
| slack | 14.9% | 2,599 |
| switch | 14.4% | 2,083 |
| telegram | 12.3% | 3,408 |
| openAi · langchain | 12.3% | 2,136 |
| splitOut | 12% | 1,939 |
That breadth is thinner than it looks. Across 165,076 node instances in 1,064 distinct types, the top ten types alone account for 49.5% of every node placed, and the twenty in this table for 65.2%. The other 1,044 types share the remaining 34.8%.
Read that as a shape rather than a headline: the catalogue is wide, the usage is not. Nearly all of what gets built is assembled from a few dozen node types, and the rest of the library exists in the tail.
The most-used integrations
The same ranking with the plumbing removed — no if, set, code, agents or output parsers — leaving the services people actually connect to.
| integration | of templates | total uses |
|---|---|---|
| googleSheets | 33% | 8,494 |
| lmChatOpenAi | 23.6% | 4,254 |
| gmail | 20.5% | 3,627 |
| slack | 14.9% | 2,599 |
| telegram | 12.3% | 3,408 |
| openAi · langchain | 12.3% | 2,136 |
| googleDrive | 11.1% | 2,382 |
| lmChatGoogleGemini | 9.7% | 1,710 |
| telegramTrigger | 6.6% | 736 |
| emailSend | 5.3% | 811 |
| lmChatOpenRouter | 4.5% | 864 |
| airtable | 4% | 1,332 |
| gmailTrigger | 3.5% | 406 |
| lmChatAnthropic | 3.1% | 545 |
| notion | 3.1% | 782 |
| googleGemini | 3% | 474 |
| embeddingsOpenAi | 2.9% | 531 |
| httpRequestTool | 2.6% | 1,132 |
| dataTable | 2.4% | 967 |
| googleDriveTrigger | 2.3% | 299 |
What gets built together
Integration pairs that co-occur most often in the same workflow. This is the closest thing to a map of what people are actually automating.
| pair | of templates | count |
|---|---|---|
| gmail + googleSheets | 10.1% | 1,110 |
| lmChatOpenAi + googleSheets | 7.3% | 803 |
| googleSheets + slack | 6.6% | 719 |
| telegram + telegramTrigger | 6.3% | 695 |
| lmChatOpenAi + gmail | 5.8% | 639 |
| gmail + slack | 4.9% | 533 |
| openAi · langchain + googleSheets | 4.9% | 532 |
| googleDrive + googleSheets | 4.6% | 504 |
| lmChatOpenAi + telegram | 3.8% | 412 |
| lmChatGoogleGemini + googleSheets | 3.6% | 393 |
| lmChatOpenAi + openAi · langchain | 3.6% | 393 |
| googleSheets + telegram | 3.5% | 382 |
| lmChatOpenAi + slack | 3.4% | 369 |
| openAi · langchain + gmail | 3.3% | 363 |
| lmChatOpenAi + googleDrive | 3.1% | 337 |
How these are counted
Every classification rule, with the node types it actually matched. If a figure above cannot be reproduced from this section plus the published data, it should not be quoted.
Node type matches /langchain/i — in practice the @n8n/n8n-nodes-langchain.* package. The base-package OpenAI node (n8n-nodes-base.openAi) and hand-rolled HTTP calls to an LLM API do NOT count.
88 node types matched — show
- @n8n/n8n-nodes-langchain.agent3,718
- @n8n/n8n-nodes-langchain.lmChatOpenAi2,591
- @n8n/n8n-nodes-langchain.outputParserStructured1,799
- @n8n/n8n-nodes-langchain.openAi1,351
- @n8n/n8n-nodes-langchain.lmChatGoogleGemini1,068
- @n8n/n8n-nodes-langchain.chainLlm1,006
- @n8n/n8n-nodes-langchain.memoryBufferWindow997
- @n8n/n8n-nodes-langchain.chatTrigger707
- @n8n/n8n-nodes-langchain.lmChatOpenRouter491
- @n8n/n8n-nodes-langchain.documentDefaultDataLoader354
- @n8n/n8n-nodes-langchain.lmChatAnthropic345
- @n8n/n8n-nodes-langchain.googleGemini326
- @n8n/n8n-nodes-langchain.embeddingsOpenAi316
- @n8n/n8n-nodes-langchain.mcpTrigger300
- @n8n/n8n-nodes-langchain.toolWorkflow250
- @n8n/n8n-nodes-langchain.informationExtractor216
- @n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter215
- @n8n/n8n-nodes-langchain.toolThink187
- @n8n/n8n-nodes-langchain.lmChatGroq173
- @n8n/n8n-nodes-langchain.toolCalculator154
- @n8n/n8n-nodes-langchain.vectorStorePinecone146
- @n8n/n8n-nodes-langchain.lmChatAzureOpenAi141
- @n8n/n8n-nodes-langchain.agentTool141
- @n8n/n8n-nodes-langchain.mcpClientTool139
- @n8n/n8n-nodes-langchain.textClassifier118
- @n8n/n8n-nodes-langchain.outputParserAutofixing114
- @n8n/n8n-nodes-langchain.vectorStoreSupabase106
- @n8n/n8n-nodes-langchain.memoryPostgresChat98
- @n8n/n8n-nodes-langchain.vectorStoreQdrant94
- @n8n/n8n-nodes-langchain.toolCode88
- @n8n/n8n-nodes-langchain.toolHttpRequest83
- @n8n/n8n-nodes-langchain.toolVectorStore82
- @n8n/n8n-nodes-langchain.toolSerpApi77
- @n8n/n8n-nodes-langchain.chainSummarization77
- @n8n/n8n-nodes-langchain.lmChatOllama72
- @n8n/n8n-nodes-langchain.embeddingsGoogleGemini71
- @n8n/n8n-nodes-langchain.lmChatDeepSeek52
- @n8n/n8n-nodes-langchain.vectorStoreInMemory51
- @n8n/n8n-nodes-langchain.lmChatMistralCloud50
- @n8n/n8n-nodes-langchain.chat50
- @n8n/n8n-nodes-langchain.toolWikipedia45
- @n8n/n8n-nodes-langchain.anthropic39
- @n8n/n8n-nodes-langchain.sentimentAnalysis36
- @n8n/n8n-nodes-langchain.textSplitterTokenSplitter35
- @n8n/n8n-nodes-langchain.rerankerCohere34
- @n8n/n8n-nodes-langchain.chainRetrievalQa31
- @n8n/n8n-nodes-langchain.textSplitterCharacterTextSplitter30
- @n8n/n8n-nodes-langchain.retrieverVectorStore29
- @n8n/n8n-nodes-langchain.memoryRedisChat27
- @n8n/n8n-nodes-langchain.lmOllama26
- @n8n/n8n-nodes-langchain.lmChatXAiGrok21
- @n8n/n8n-nodes-langchain.vectorStorePGVector21
- @n8n/n8n-nodes-langchain.embeddingsOllama19
- @n8n/n8n-nodes-langchain.memoryManager19
- @n8n/n8n-nodes-langchain.guardrails19
- @n8n/n8n-nodes-langchain.code15
- @n8n/n8n-nodes-langchain.embeddingsCohere14
- @n8n/n8n-nodes-langchain.memoryMongoDbChat13
- @n8n/n8n-nodes-langchain.vectorStoreMongoDBAtlas12
- @n8n/n8n-nodes-langchain.embeddingsMistralCloud12
- @n8n/n8n-nodes-langchain.mcpClient9
- @n8n/n8n-nodes-langchain.outputParserItemList8
- @n8n/n8n-nodes-langchain.lmChatGoogleVertex7
- @n8n/n8n-nodes-langchain.modelSelector6
- @n8n/n8n-nodes-langchain.vectorStoreWeaviate5
- @n8n/n8n-nodes-langchain.lmOpenAi5
- @n8n/n8n-nodes-langchain.vectorStoreMilvus5
- @n8n/n8n-nodes-langchain.lmOpenHuggingFaceInference4
- @n8n/n8n-nodes-langchain.embeddingsAzureOpenAi4
- @n8n/n8n-nodes-langchain.manualChatTrigger4
- @n8n/n8n-nodes-langchain.lmChatAwsBedrock4
- @n8n/n8n-nodes-langchain.googleGeminiTool4
- @n8n/n8n-nodes-langchain.vectorStoreRedis3
- @n8n/n8n-nodes-langchain.embeddingsHuggingFaceInference3
- @n8n/n8n-nodes-langchain.chatHitlTool3
- @n8n/n8n-nodes-langchain.toolWolframAlpha2
- @n8n/n8n-nodes-langchain.lmChatCohere2
- @n8n/n8n-nodes-langchain.ollama2
- @n8n/n8n-nodes-langchain.retrieverWorkflow2
- @n8n/n8n-nodes-langchain.toolSearXng1
- @n8n/n8n-nodes-langchain.vectorStoreSupabaseInsert1
- @n8n/n8n-nodes-langchain.lmChatMoonshot1
- @n8n/n8n-nodes-langchain.anthropicTool1
- @n8n/n8n-nodes-langchain.microsoftAgent365Trigger1
- @n8n/n8n-nodes-langchain.ollamaTool1
- @n8n/n8n-nodes-langchain.lmChatVercelAiGateway1
- @n8n/n8n-nodes-langchain.memoryZep1
- @n8n/n8n-nodes-langchain.embeddingsAwsBedrock1
A LangChain node whose type also contains "agent", "chainLlm" or "chainSummarization" — the roots that hang models, tools and memory beneath them. A subset of aiNode.
5 node types matched — show
- @n8n/n8n-nodes-langchain.agent3,718
- @n8n/n8n-nodes-langchain.chainLlm1,006
- @n8n/n8n-nodes-langchain.agentTool141
- @n8n/n8n-nodes-langchain.chainSummarization77
- @n8n/n8n-nodes-langchain.microsoftAgent365Trigger1
A base-package code, function or functionItem node. The LangChain Code Tool (@n8n/n8n-nodes-langchain.code) is a different node and is not counted here.
Any node with an onError setting other than the default "stopWorkflow". Workflow-level error workflows are not visible in template JSON and are not counted.
Sticky notes (n8n-nodes-base.stickyNote) are annotations, not steps, and are excluded from every node count. They are reported separately.
Counts key on the full node type. Where two packages share a short name — code, openAi, mcpClient and five others — the label is qualified, e.g. "code · base" versus "code · langchain".
Take the data
All three files are output of the same script that produced this page. Between the two CSVs every figure above can be recomputed from scratch — the per-template rows carry the size, shape, trigger and feature numbers, the per-node-type rows carry the ranked tables and the concentration. The JSON is the aggregate the page renders from, so treat it as convenience rather than as evidence: checking a number against it only tells you the page read its own file correctly. CC BY 4.0 — use them anywhere, credit the page.
Method, limits and reuse
Source. The public n8n.io template library, read through its public API — the id list from the paginated search endpoint, then each template fetched individually, throttled and cached. Every one of the 11,015 listed templates was requested. 58 ids returned no workflow and were skipped. No Pixtex user data was used, and none ever will be — the value of these numbers is that anyone can reproduce them from the same public source.
Limits. Public n8n.io templates only. Templates are built to be shared, so they skew simpler than production workflows and over-represent whatever the library is promoting — currently AI. This describes a published n8n template, not a private production workflow. Beyond that: a census has no sampling error, but it is still a snapshot — the library grows weekly, and these figures are dated accordingly. Sticky notes are excluded from node counts. A template is counted once per feature however many matching nodes it contains. Error handling is only visible where a node sets onError; workflow-level error workflows do not appear in template JSON at all, so the true rate is somewhat higher than the one reported here.
Reuse. Everything here is CC BY 4.0 — quote it, chart it, build on it, with attribution to Pixtex — The anatomy of a published n8n template. The raw data is above. If you want a cut we did not publish, ask and we will run it.
See your own workflow properly
If yours is past the 18-node mark, a screenshot is not going to do it. Drop the JSON in and export a real image.