n8n's Default SQLite Database Isn't Built for Production: Backup It Properly

Mike Holownych
Last verified: July 28, 2026
#n8n#automation
Share:

Quick Answer

n8n ships with SQLite as its default database — a single file, no configuration, fine for testing. n8n’s own documentation recommends PostgreSQL for production use, and for good reason: SQLite’s single-writer locking model doesn’t hold up well under concurrent workflow executions at volume, and a single corrupted database file takes your workflow history, execution logs, and (if not backed up separately) credentials with it. Whether you migrate to PostgreSQL or not, you need three backup layers: automated database dumps, workflow export automation, and a separate credential backup.

Why SQLite Struggles Under Production Load

SQLite corruption in production n8n instances tends to trace back to a handful of mechanisms:

Write-Ahead Logging (WAL) mode failures. n8n enables WAL mode for better concurrent access. If the process is interrupted during a WAL checkpoint — a crash, an OOM kill, a forced container restart — the main database file and the WAL file can desynchronize in a way that’s not always recoverable.

Concurrent write collisions. SQLite locks the whole database file during a write. Under heavy concurrent execution load, that produces lock timeouts and, in the worst case, partial writes — and a partial write to a SQLite file is a corrupted file.

Disk space exhaustion. n8n’s execution history grows without bound by default. If the volume backing .n8n/database.sqlite fills up mid-transaction, SQLite can’t complete the write, and the file can end up in a broken state.

Journal mode transitions. n8n can switch between journal modes depending on configuration; a mode transition that lands mid-transaction can corrupt the database header outright.

None of this is exotic — it’s the standard, documented set of reasons SQLite is a poor fit for a multi-writer, high-throughput workload, and it’s exactly why n8n’s own docs point production deployments at PostgreSQL instead. If you’re running SQLite in production anyway (common for smaller or self-hosted setups), the backup system below is how you limit the blast radius when — not if — something goes wrong with the file.

Build a Three-Layer Backup System

Layer 1: Database Backup Automation

A workflow that dumps the SQLite database on a schedule (adapt the cron rule to your actual write volume — every 6 hours is a reasonable starting point):

{
  "nodes": [
    {
      "name": "Schedule Backup",
      "type": "n8n-nodes-base.cron",
      "parameters": {
        "rule": {
          "hour": [0, 6, 12, 18]
        }
      }
    },
    {
      "name": "Create DB Backup",
      "type": "n8n-nodes-base.executeCommand",
      "parameters": {
        "command": "sqlite3 /home/node/.n8n/database.sqlite \".backup /backups/n8n-$(date +%Y%m%d-%H%M%S).sqlite\""
      }
    },
    {
      "name": "Upload to S3",
      "type": "n8n-nodes-base.aws",
      "parameters": {
        "service": "s3",
        "operation": "upload",
        "bucket": "n8n-backups",
        "key": "database/n8n-{{ $now.format('yyyy-MM-dd-HHmmss') }}.sqlite"
      }
    }
  ]
}

Using sqlite3 .backup rather than a raw file copy matters here — it’s SQLite’s own online backup mechanism, safe to run against a live database without risking a torn read.

Layer 2: Workflow Export Automation

A database backup protects you from corruption, but it’s still a single artifact. Exporting each workflow as its own JSON file gives you a per-workflow recovery path independent of the database:

{
  "nodes": [
    {
      "name": "Get All Workflows",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "method": "GET",
        "url": "http://localhost:5678/api/v1/workflows",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      }
    },
    {
      "name": "Process Each Workflow",
      "type": "n8n-nodes-base.splitInBatches",
      "parameters": {
        "batchSize": 1
      }
    },
    {
      "name": "Export Workflow",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "method": "GET",
        "url": "=http://localhost:5678/api/v1/workflows/{{ $json.id }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      }
    },
    {
      "name": "Save to File",
      "type": "n8n-nodes-base.writeBinaryFile",
      "parameters": {
        "fileName": "=workflow-{{ $json.id }}-{{ $now.format('yyyy-MM-dd') }}.json"
      }
    }
  ]
}

Layer 3: Credential Backup

Credentials live in the same database, encrypted with your N8N_ENCRYPTION_KEY — which means a database backup is only restorable if you still have that key. Export credentials separately and keep the encryption key backed up somewhere independent of the database backup itself:

{
  "nodes": [
    {
      "name": "Weekly Trigger",
      "type": "n8n-nodes-base.cron",
      "parameters": {
        "rule": {
          "dayOfWeek": [0],
          "hour": [2]
        }
      }
    },
    {
      "name": "Export Credentials",
      "type": "n8n-nodes-base.executeCommand",
      "parameters": {
        "command": "n8n export:credentials --output=/backups/credentials-$(date +%Y%m%d).json --encrypt --encryptionkey=$N8N_ENCRYPTION_KEY"
      }
    },
    {
      "name": "Upload Encrypted File",
      "type": "n8n-nodes-base.aws",
      "parameters": {
        "service": "s3",
        "operation": "upload",
        "bucket": "n8n-backups",
        "key": "credentials/credentials-{{ $now.format('yyyy-MM-dd') }}.json.enc"
      }
    }
  ]
}

The Real Fix Is PostgreSQL

Backups limit the damage; they don’t fix the underlying mismatch between SQLite’s concurrency model and a production workflow load. If you’re seeing lock timeouts or approaching meaningful execution volume, migrating to PostgreSQL (n8n supports this natively via the DB_TYPE environment variable) removes the single-writer bottleneck entirely rather than just backing it up more carefully.

See n8n Enterprise Architecture for the fuller production-readiness picture — environment separation, credential ownership, and disaster recovery beyond just the database layer.

MH

About Mike Holownych

Building AI Syndicate—governance infrastructure for AI agents in regulated environments. 20+ years enterprise operations, now applying that reliability discipline to AI deployment.