Database & Migrations
Relevant source files
The following files were used as context for generating this wiki page:
n8n utilizes a relational database architecture to manage persistent data such as workflows, executions, credentials, and user settings. The system is built on Node.js and uses TypeORM to interface with supported database engines, primarily SQLite and PostgreSQL.
The database layer is responsible for ensuring data integrity through a structured schema and a robust migration system. Migrations allow the schema to evolve safely across versions, with specific tooling like tbls used for documentation and n8n-io/migrations-review standards for quality assurance.
Sources: CONTRIBUTING.md:65-70, AGENTS.md:104-105, docker/images/n8n/README.md:92-95
Database Architecture
n8n supports two primary database types for different deployment scenarios. By default, the application uses SQLite for simplicity in local and single-user environments. For production or high-availability setups, PostgreSQL is the recommended choice.
Supported Database Engines
| Database Type | Usage Context | Default File Path / Connection |
|---|---|---|
| SQLite | Local development, single-user instances. | ~/.n8n/database.sqlite |
| PostgreSQL | Production environments, multi-user setups, high concurrency. | Configured via DB_POSTGRESDB_* env vars. |
Sources: docker/images/n8n/README.md:92-110, AGENTS.md:104-105
Connection Lifecycle
The application manages database connections through a dedicated connection utility. The lifecycle involves initialization at startup, maintaining a pool for PostgreSQL, and handling secure credential storage via an encryption key stored in the user folder.
The diagram shows the database initialization flow where the system selects the engine, loads the encryption key from the filesystem, and proceeds to migration checks.
Sources: docker/images/n8n/README.md:85-110, packages/@n8n/db/src/connection/db-connection.ts
Database Migrations
Migrations in n8n are the standard way to modify the database schema. They are authored in TypeScript and managed through TypeORM to ensure consistency across SQLite and PostgreSQL.
Migration Types and Structure
Migrations are classified into reversible and irreversible types. A ReversibleMigration includes both up (to apply) and down (to revert) methods, while an IrreversibleMigration only contains an up method.
| Component | Description |
|---|---|
MigrationContext | Provides the API for performing schema changes (e.g., creating tables, adding columns). |
DSL | A Domain Specific Language used for schema building and type mapping. |
tbls | Tool used to generate database schema documentation under docs/generated/. |
Sources: packages/@n8n/db/src/migrations/migration-types.ts:1-20, packages/@n8n/db/AGENTS.md:7-13, CONTRIBUTING.md:120-125
Migration Development Workflow
Developers must follow a strict process when modifying migrations to prevent data loss or service interruption.
- Scaffolding: Creating the migration file using the n8n CLI or provided templates.
- Authoring: Implementing the schema changes using the
MigrationContextand DSL. - Documentation: Running
tblsto update the generated schema docs. - Testing: Using
packages/@n8n/backend-test-utilsto verify the migration against both SQLite and PostgreSQL.
This sequence illustrates how schema documentation is automatically kept in sync with code changes via git hooks and the tbls tool.
Sources: CONTRIBUTING.md:120-130, packages/@n8n/db/AGENTS.md:7-13
Security and Performance
Prototype Pollution Prevention
n8n enforces security rules to prevent prototype pollution when handling database keys derived from user input. Values such as __proto__, constructor, or prototype are sanitized using helpers like isSafeObjectProperty and setSafeObjectProperty from n8n-workflow.
Sources: cubic.yaml:164-180, packages/nodes-base/AGENTS.md:65-80
Performance Guardrails
- Indexing: Migrations should include indexes on frequently queried columns.
- Pagination: Resource-intensive queries must implement pagination or limits to avoid OOM (Out of Memory) errors.
- Parameterized Queries: Raw SQL queries should be avoided in favor of TypeORM's query builder to prevent SQL injection.
Sources: cubic.yaml:135-145, packages/@n8n/workflow-sdk/src/prompts/best-practices/guides/data-analysis.ts:160-170
Configuration
Database behavior is primarily configured through environment variables, particularly for PostgreSQL and sensitive file-based secrets.
| Variable | Description |
|---|---|
DB_TYPE | Set to postgresdb to use PostgreSQL. |
DB_POSTGRESDB_HOST | The hostname of the PostgreSQL server. |
DB_POSTGRESDB_PORT | The port of the PostgreSQL server. |
DB_POSTGRESDB_PASSWORD_FILE | Path to a file containing the DB password (for Docker/K8s secrets). |
Sources: docker/images/n8n/README.md:113-125, AGENTS.md:104-105
Summary
The n8n database system is a dual-engine relational layer optimized for both simplicity and production scalability. By combining TypeORM with a strict, documented migration workflow and security-first coding patterns, the project ensures that user data remains safe and performance remains consistent as the software evolves.