# What Database Does n8n Use and How Is the Schema Structured with TypeORM?

> Discover which databases n8n utilizes and how its schema is structured with TypeORM. Learn about entity definitions and supported databases like SQLite, PostgreSQL, MySQL, and MSSQL.

- Repository: [n8n - Workflow Automation/n8n](https://github.com/n8n-io/n8n)
- Tags: internals
- Published: 2026-02-24

---

**n8n uses TypeORM to persist data across SQLite (default), PostgreSQL, MySQL/MariaDB, and MSSQL, with the schema defined declaratively through decorated Entity classes in `packages/@n8n/db/src/entities/`.**

The **n8n** workflow automation platform stores all persistent data—including workflows, executions, and credentials—using **TypeORM**, a TypeScript-first ORM. This architecture allows the **n8n database** layer to remain agnostic while supporting multiple relational backends through a unified schema definition system.

## Supported Databases in n8n

n8n supports four relational database engines, configurable via the `DB_TYPE` environment variable defined in `packages/@n8n/db/src/database.service.ts`.

- **SQLite**: The default for local development and Docker quick-starts. Zero-configuration, file-based storage.
- **PostgreSQL**: Recommended for production deployments requiring scalability and robust transactional support.
- **MySQL / MariaDB**: Supported for organizations with existing MySQL-compatible infrastructure.
- **MSSQL**: Available for Microsoft SQL Server environments.

Configuration requires setting `DB_TYPE` to `sqlite`, `postgres`, `mysql` (or `mariadb`), or `mssql`, along with corresponding connection parameters such as `POSTGRES_DB`, `POSTGRES_USER`, and `POSTGRES_HOST` for PostgreSQL instances.

## How n8n Defines the Database Schema with TypeORM

Rather than maintaining raw SQL migration files as the source of truth, n8n expresses its **TypeORM schema** through TypeScript entity classes. These classes use TypeORM decorators (`@Entity`, `@Column`, `@ManyToOne`, etc.) to define tables, columns, and relationships. At startup, TypeORM reads these entities and synchronizes the database structure or executes pending migrations.

### Core Entities Overview

The schema centers on five primary entities located in `packages/@n8n/db/src/entities/`:

- **WorkflowEntity**: Stores workflow definitions, JSON-encoded nodes, connections, and versioning metadata.
- **ExecutionEntity**: Records individual workflow runs, including status, timestamps, and execution data.
- **CredentialsEntity**: Contains encrypted credential data used by nodes.
- **TagEntity**: Manages user-defined labels for workflow organization.
- **FolderEntity**: Implements hierarchical folder structures via self-referencing relationships.

### WorkflowEntity Structure

The `WorkflowEntity` class in `packages/@n8n/db/src/entities/workflow-entity.ts` demonstrates how n8n handles complex JSON data and many-to-many relationships:

```typescript
// packages/@n8n/db/src/entities/workflow-entity.ts
@Entity()
export class WorkflowEntity extends WithTimestampsAndStringId implements IWorkflowDb {
  @Index({ unique: true })
  @Length(1, 128)
  @Column({ length: 128 })
  name: string;

  @Column({ type: 'text', nullable: true })
  description: string | null;

  @JsonColumn()
  nodes: INode[];

  @JsonColumn()
  connections: IConnections;

  @ManyToMany('TagEntity', 'workflows')
  @JoinTable({
    name: 'workflows_tags',
    joinColumn: { name: 'workflowId', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'tagId', referencedColumnName: 'id' },
  })
  tags?: TagEntity[];

  @ManyToOne('Folder', 'workflows', { nullable: true, onDelete: 'CASCADE' })
  @JoinColumn({ name: 'parentFolderId' })
  parentFolder: Folder | null;
}

```

The `@JsonColumn()` decorator is a custom wrapper around TypeORM's `@Column({ type: 'json' })` that includes a SQLite-compatible transformer to handle JSON serialization across database types.

### ExecutionEntity and Data Storage

The `ExecutionEntity` in `packages/@n8n/db/src/entities/execution-entity.ts` illustrates database-specific column typing for JSON storage:

```typescript
// packages/@n8n/db/src/entities/execution-entity.ts
@Entity()
export class ExecutionEntity extends WithTimestampsAndStringId {
  @Column({ length: 36 })
  workflowId: string;

  @ManyToOne('WorkflowEntity', { nullable: false })
  @JoinColumn({ name: 'workflowId' })
  workflow: WorkflowEntity;

  @Column({ type: dbType === 'sqlite' ? 'text' : 'json', transformer: sqlite.jsonColumn })
  data: IDataObject;

  @Column({ type: 'int', default: 0 })
  status: number;
}

```

This conditional column type ensures that SQLite stores JSON as text while PostgreSQL and MySQL use native JSON columns, maintaining cross-database compatibility.

## Database Migrations in n8n

While entities define the desired schema state, n8n manages schema evolution through TypeORM migration files located in `packages/cli/src/migrations/`. These files use the `queryRunner` API to execute incremental changes—such as adding columns or indexes—ensuring production databases upgrade without data loss. Migrations run automatically at startup when the `runMigrations` flag is enabled.

## Summary

- **n8n** uses **TypeORM** as its database abstraction layer, supporting SQLite, PostgreSQL, MySQL/MariaDB, and MSSQL through a single `DataSource` configuration in `packages/@n8n/db/src/database.service.ts`.
- The **schema** is defined declaratively via TypeScript entity classes using decorators like `@Entity`, `@Column`, and `@ManyToMany`, located in `packages/@n8n/db/src/entities/`.
- **WorkflowEntity**, **ExecutionEntity**, **CredentialsEntity**, **TagEntity**, and **FolderEntity** form the core schema, handling JSON data through custom transformers for SQLite compatibility.
- Schema changes are managed through versioned migration files in `packages/cli/src/migrations/` that execute via TypeORM's `queryRunner`.

## Frequently Asked Questions

### What is the default database for n8n?

**SQLite** is the default database for local development and quick-start Docker deployments. It requires no external server configuration, storing data in a local file. For production workloads, n8n recommends **PostgreSQL** configured via the `DB_TYPE=postgres` environment variable.

### How does n8n handle JSON data in SQLite?

n8n uses a custom `@JsonColumn()` decorator that wraps TypeORM's standard column definition with a SQLite-specific transformer (`sqlite.jsonColumn`). This converts JSON objects to text for SQLite storage while using native JSON types for PostgreSQL and MySQL, ensuring consistent behavior across supported databases.

### Where are the database entities defined in the n8n source code?

All entity definitions reside in `packages/@n8n/db/src/entities/`, including [`workflow-entity.ts`](https://github.com/n8n-io/n8n/blob/main/workflow-entity.ts), [`execution-entity.ts`](https://github.com/n8n-io/n8n/blob/main/execution-entity.ts), [`credentials-entity.ts`](https://github.com/n8n-io/n8n/blob/main/credentials-entity.ts), [`tag-entity.ts`](https://github.com/n8n-io/n8n/blob/main/tag-entity.ts), and [`folder-entity.ts`](https://github.com/n8n-io/n8n/blob/main/folder-entity.ts). These TypeScript classes use TypeORM decorators to define the database schema structure.

### Does n8n support database migrations for version upgrades?

Yes. n8n includes migration files in `packages/cli/src/migrations/` that use TypeORM's `queryRunner` API to modify existing schemas. These migrations run automatically when the application starts with migrations enabled, allowing seamless upgrades without manual SQL execution or data loss.