# Data flow — n8n-io/n8n

> Canonical page: https://codevetter.com/unpack/n8n/data-flow

# Data flow — n8n-io/n8n

Scanned commit 1a370b965c1fe438dfa58f371a01080eb9cca776 (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Workflow JSON and credentials live in @n8n/db entities; credentials are encrypted through Cipher (AES-256-CBC/GCM with key-id prefixes). Incoming REST/webhook requests hit controllers/handlers, which delegate to services and repositories; executions run through WorkflowRunner -> WorkflowExecute, producing IRunExecutionData that lifecycle hooks persist via ExecutionPersistence into execution_entity/execution_data. In queue mode the main enqueues a Bull job consumed by a worker which runs the same engine and reports back over Redis pub/sub. The editor reads/writes the same REST API and receives live updates via Push (ws/sse).
- Core persisted state: WorkflowEntity (nodes/connections/settings/pinData), CredentialsEntity (encrypted data), WebhookEntity (path->workflow/node mapping), ExecutionEntity + ExecutionData, plus Settings rows with loadOnStartup that are re-applied to the convict config at boot. — [packages/@n8n/db/src/entities/index.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/%40n8n/db/src/entities/index.ts) [packages/cli/src/commands/start.ts#L407-413](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/start.ts#L407-L413)
- Request path: Express middleware (cookie-parser, browserId extraction, CSP) -> AuthStrategyRegistry (ApiKeyAuthStrategy then SessionCookieAuthStrategy) -> ControllerRegistry-activated routes -> services -> repositories -> TypeORM DataSource. — [packages/cli/src/server.ts#L191-268](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/server.ts#L191-L268) [packages/cli/src/controller.registry.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/controller.registry.ts)
- Execution path: controller/manual trigger -> WorkflowRunner.run -> WorkflowExecute.run (PCancelable<IRun>) which iterates the execution stack, calls node execute functions via NodeExecuteFunctions contexts, and emits lifecycle hooks (workflowExecuteBefore/After, nodeExecuteBefore/After) that persist progress. — [packages/cli/src/workflow-runner.ts#L108-130](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/workflow-runner.ts#L108-L130) [packages/core/src/execution-engine/workflow-execute.ts#L142-150](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/core/src/execution-engine/workflow-execute.ts#L142-L150) [packages/cli/src/execution-lifecycle/execution-lifecycle-hooks.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/execution-lifecycle/execution-lifecycle-hooks.ts)
- Credential secrecy: Cipher.encryptV2 encrypts with the active key from EncryptionKeyProxy, emitting 'keyId:ciphertext' for rotated keys or bare ciphertext for the legacy no-prefix format; decryptV2 parses the prefix, looks up the DEK, unwraps it with the instance key (AES-256-GCM), then decrypts. — [packages/core/src/encryption/cipher.ts#L54-135](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/core/src/encryption/cipher.ts#L54-L135)
- Webhook data path: request -> WebhookRequestHandler.handleRequest (method check, CORS) -> webhookManager.executeWebhook -> WebhookService.findTriggerWebhooksByPath against webhook_entity -> workflow execution -> WebhookResponse (static/stream/no-response) -> headers via WebhookResponseHeaders. — [packages/cli/src/webhooks/webhook-request-handler.ts#L43-120](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/webhooks/webhook-request-handler.ts#L43-L120) [packages/cli/src/webhooks/webhook.service.ts#L120-218](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/webhooks/webhook.service.ts#L120-L218)
- Queue-mode data path: main's ScalingService.setupQueue creates a Bull queue (maxStalledCount: 0) named by resolveQueueName(instanceType, poolName); workers run setupWorker(concurrency) -> JobProcessor executes the same WorkflowExecute and relays status through Redis pub/sub channels (command, worker-response, mcp-relay). — [packages/cli/src/scaling/scaling.service.ts#L97-132](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/scaling/scaling.service.ts#L97-L132) [packages/cli/src/commands/worker.ts#L208-243](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/worker.ts#L208-L243) [packages/cli/src/commands/start.ts#L329-351](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/start.ts#L329-L351)
- Binary data flows through BinaryDataConfig/BinaryDataService with pluggable stores: filesystem managers under cli/binary-data plus S3/Azure object stores via @n8n/blob-storage (S3ByteStore, AzureByteStore). — [packages/cli/src/commands/base-command.ts#L13](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/base-command.ts#L13) [packages/cli/src/binary-data/binary-data-access.service.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/binary-data/binary-data-access.service.ts)
- Frontend bootstrap: index.html is pre-split around HTML_NONCE_PLACEHOLDER and served per-request with a fresh CSP nonce by historyApiHandler; REST endpoint + Sentry config reach the client as base64 meta tags injected during generateStaticAssets. — [packages/cli/src/server.ts#L442-485](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/server.ts#L442-L485) [packages/cli/src/commands/start.ts#L140-205](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/start.ts#L140-L205)
- Node/credential type metadata: LoadNodesAndCredentials scans node_modules for n8n-nodes-base and @n8n/n8n-nodes-langchain, plus custom dirs and module-provided nodeLoaders; built types are written to staticCacheDir (/types/nodes.json, credentials.json, node-versions.json) served behind auth. — [packages/cli/src/load-nodes-and-credentials.ts#L103-137](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/load-nodes-and-credentials.ts#L103-L137) [packages/cli/src/server.ts#L497-524](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/server.ts#L497-L524)
- Expression evaluation: workflow expressions are evaluated by @n8n/tournament (an AST interpreter, not eval) wrapped by expression-evaluator-proxy and hardened by expressionSandboxHooks in expression-sandboxing.ts. — [packages/workflow/src/expression-evaluator-proxy.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/workflow/src/expression-evaluator-proxy.ts) [packages/workflow/src/expression-sandboxing.ts#L568-572](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/workflow/src/expression-sandboxing.ts#L568-L572) [packages/@n8n/tournament/src/index.ts](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/%40n8n/tournament/src/index.ts)
- Event bus: MessageEventBus is initialized per-process (workerId payload on workers) and LogStreamingEventRelay forwards events; execution/workflow lifecycle also feeds TelemetryEventRelay, ActivityEventRelay, and workflow-failure notifications. — [packages/cli/src/commands/worker.ts#L170-175](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/worker.ts#L170-L175) [packages/cli/src/commands/base-command.ts#L37-40](https://github.com/n8n-io/n8n/blob/1a370b965c1fe438dfa58f371a01080eb9cca776/packages/cli/src/commands/base-command.ts#L37-L40)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
