Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developer.upsun.com/llms.txt

Use this file to discover all available pages before exploring further.

In our previous article, we showed how to host n8n on Upsun and automate your workflows. Since then, you might have noticed that your n8n instance is getting slower—especially if you’re adding more complex workflows or running frequent executions. By default, n8n uses SQLite, which works great for small setups but hits performance limits with high-volume workflows. The good news? It’s straightforward to upgrade to PostgreSQL and add Redis caching to unlock better performance and scalability. This guide walks you through the process.

Why upgrade from SQLite?

Performance limitations of SQLite:
  • SQLite has locking issues when multiple workflows execute simultaneously.
  • Database queries slow down as your workflow history grows.
  • No built-in clustering support—you’re limited to a single instance.
What PostgreSQL and Redis bring:
  • PostgreSQL provides a proper relational database with concurrent query support, better query optimization, and the ability to handle millions of executions.
  • Redis acts as a caching layer and queue backend, reducing database load and speeding up workflow execution lookups.

Prerequisites

Before you start, make sure you have:

Architecture overview

Here’s what your upgraded setup will look like: Architecture Stack Key benefits of this architecture:
  • n8n main process handles the web UI and API requests.
  • Worker processes execute workflows independently, preventing long-running jobs from blocking the main application.
  • PostgreSQL stores all workflow definitions, executions, credentials, and history.
  • Redis manages the job queue, ensuring tasks are processed reliably and can be retried if needed.

Step 1: Create an environment for PostgreSQL and Redis

As we never push major changes in production directly, we will first create a staging environment to test the new configuration before applying it to production.
Terminal
upsun branch add-postgresql-redis
This will create a new branch and environment named add-postgresql-redis where we will be able to test the new configuration without affecting the production environment.

Step 2: Add PostgreSQL and Redis services

First, update your .upsun/config.yaml to include PostgreSQL and Redis services:
.upsun/config.yaml
services:
  database:
    type: postgresql:16
  redis:
    type: redis:8.0
This minimal configuration creates:
  • A PostgreSQL 16 database for persistent workflow storage.
  • A Redis 8.0 instance for caching and the job queue.

Step 3: Configure n8n application

Update your n8n application configuration in .upsun/config.yaml to connect to PostgreSQL and use Redis:
.upsun/config.yaml
applications:
  app-n8n:
    type: 'nodejs:22'
    #...
    relationships:
      database:
      redis:
    workers:
      worker:
        commands:
          start: "n8n worker --concurrency=${N8N_WORKER_CONCURRENCY:-1}"
Key configuration points:
  • relationships link n8n to PostgreSQL (as database) and Redis as a job queue.
  • workers handle background job processing—scale the concurrency setting as needed.
  • n8n auto-detects PostgreSQL and Redis via services variables Upsun injects.

Step 4: Add .environment specific environment variables

# Config PostgreSQL
export DB_TYPE=postgresdb
export DB_POSTGRESDB_HOST=${DATABASE_HOST}
export DB_POSTGRESDB_PORT=${DATABASE_PORT}
export DB_POSTGRESDB_DATABASE=${DATABASE_PATH}
export DB_POSTGRESDB_USER=${DATABASE_USERNAME}
export DB_POSTGRESDB_PASSWORD=${DATABASE_PASSWORD}

# Config Redis
export N8N_CACHE_ENABLED=true
export N8N_CACHE_BACKEND=redis
export N8N_CACHE_REDIS_HOST=${REDIS_HOST}
export N8N_CACHE_REDIS_PORT=${REDIS_PORT}
export N8N_CACHE_REDIS_PASSWORD=${REDIS_PASSWORD}
export N8N_CACHE_REDIS_TTL=3600 # default to 1h

# Queue on Redis
export QUEUE_BULL_REDIS_HOST=${REDIS_HOST}
export QUEUE_BULL_REDIS_PORT=${REDIS_PORT}
export QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD}

export QUEUE_HEALTH_CHECK_ACTIVE=true
Once you’ve updated the configuration:
git add .upsun/config.yaml
git commit -m "Add PostgreSQL and Redis services"

Step 5: Migrate existing data

User accounts can’t be migrated automatically. The export:entities / import:entities CLI commands are still experimental and unreliable across different n8n versions — attempts may fail with migration timestamp mismatches.
Before migrating, make sure that nobody updates existing Workflows or Credentials in the current instance during the migration — changes will not be automatically re-exported.

Exporting n8n encryption key

N8n uses a default pre-generated TOKEN to store your data securely in your SQLite database. To be able to export and re-import your workflows and credentials into the new built version of n8n, your need to export and save this token on the project level, for environment inheritance.
Terminal
upsun variable:create \
  --name=N8N_ENCRYPTION_KEY \
  --prefix=env \
  --env=main \
  --sensitive=true \
  --level=project \
  --value=$(upsun ssh -e main -- "cat /app/.n8n/config | jq -r .encryptionKey")
This will create a new environment variable named N8N_ENCRYPTION_KEY with the value of the encryption key used in your current n8n production instance, and let all environments inherit it.

Exporting existing workflows

If you already have workflows in SQLite, you need to export them:
Terminal
upsun ssh -e main -- "mkdir -p /tmp/n8n-export && n8n export:workflow --all --output=/tmp/n8n-export/workflows.json"
upsun ssh -e main -- "cat /tmp/n8n-export/workflows.json" > workflows.json
This will create a new file named workflows.json in your local directory with all your workflows exported. This file is encrypted with the same encryption key as your current n8n instance, so you can re-import it in the new n8n instance without any issue.

Exporting existing credentials

If you already have credentials in SQLite, you need to export them:
Terminal
upsun ssh -e main -- "mkdir -p /tmp/n8n-export && n8n export:credentials --all --output=/tmp/n8n-export/credentials.json"
upsun ssh -e main -- "cat /tmp/n8n-export/credentials.json" > credentials.json
This will create a new file named credentials.json in your local directory with all your credentials exported. This file is encrypted with the same encryption key as your current n8n instance, so you can re-import it in the new n8n instance without any issue.

Step 6: Deploy

When all previous steps are done, deploy your new n8n application:
upsun push
During the deployment:
  1. PostgreSQL and Redis services are automatically provisioned.
  2. The main n8n application starts and connects to both services.
  3. Worker processes are spawned to handle background jobs independently.
  4. n8n automatically detects the database is empty and initializes its schema.
  5. Existing workflows and credentials from your SQLite database need to be reimported.

Step 7: Import Workflows and Credentials

To import your existing workflows and credentials into the new n8n staging instance, follow these steps:
Terminal
upsun ssh -- "n8n import:workflow --input=/dev/stdin" < workflows.json
upsun ssh -- "n8n import:credentials --input=/dev/stdin" < credentials.json
When import is finished, you can then open the frontend to check that everything is working correctly by using the following command line:
Terminal
upsun environment:url --primary

Step 8: Verify the setup

After deployment, verify that n8n is using PostgreSQL and Redis:
  1. Check the main application logs:
    Terminal
    upsun logs app-n8n
    
    Look for messages confirming PostgreSQL and Redis initialization.
  2. Check worker process logs:
    Terminal
    upsun logs worker
    
    Verify workers are listening for jobs:
    Terminal
    [INFO] Message Queue: Ready on queue "default"
    
  3. Confirm the connection from the n8n UI by running a test workflow—execution history should load instantly and background jobs should process via workers.
  4. In your Upsun console, verify all services and processes are running and healthy.

Step 9: Update production environment

Before merging to production, make sure to create a backup of your production environment, in case you need to rollback:
Terminal
upsun backup:create --environment=main

Merge to production

Once you’ve verified everything is working correctly in staging, you can merge your changes to the production branch:
Terminal
git checkout main
git merge add-postgresql-redis
upsun push
This will trigger a deployment to production with the new PostgreSQL and Redis configuration.

Reimport workflows and credentials to production

You can redo what you did in staging to export the encryption key, workflows and credentials from the current production instance, and re-import them in the new production instance:
Terminal
upsun ssh -- "n8n import:workflow --input=/dev/stdin" < workflows.json
upsun ssh -- "n8n import:credentials --input=/dev/stdin" < credentials.json
After importing is finished and you checked that everything is working correctly, make sure to delete the workflows.json and credentials.json files from your local directory, as they contain sensitive data that should not be stored unencrypted.

Step 10: Recreate N8N users

As the users are stored in the database, they will not be automatically migrated from the old n8n instance to the new one. You will need to recreate them manually in the n8n UI. Create first user

Performance tuning tips

Now that you’re using PostgreSQL and Redis with dedicated workers, optimize further:

Worker concurrency

Adjust the N8N_WORKER_CONCURRENCY environment variable to control how many jobs a worker processes simultaneously:
.upsun/config.yaml
applications:
  app-n8n:
    type: 'nodejs:22'
    #...
    variables:
      env:
        #...
        N8N_WORKER_CONCURRENCY: "2"  # Default is 1
Higher concurrency handles more workflows in parallel, but requires more memory—that’s why container_profile: HIGHER_MEMORY is recommended.

PostgreSQL optimization

  • Backup regularly: Enable automatic backups in your Upsun environment to protect your workflow data.
  • Monitor disk usage: As your execution history grows, the database will expand. Allocate enough disk space or set retention policies.
  • Monitor slow queries: Check PostgreSQL logs if workflow execution feels sluggish.

Redis optimization

  • Monitor queue depth: Use upsun ssh to check Redis memory and queue depth during peak times:
Terminal
upsun ssh
redis-cli
> INFO stats

Troubleshooting

Workers not processing jobs

  • Verify worker process logs: upsun logs worker
  • Check Redis is running: upsun logs redis
  • Ensure N8N_WORKER_CONCURRENCY is set to a reasonable value.

High memory usage

  • Confirm container_profile: HIGHER_MEMORY is set in your n8n app config.
  • Lower N8N_WORKER_CONCURRENCY if workers exceed available memory.
  • Monitor via: upsun sshtop or check environment metrics in the console.

PostgreSQL connection errors

  • Check app logs: upsun logs app
  • Ensure the relationship names match in both applications and services.
  • Verify environment variables are correctly set and injected.

Workflows not appearing after migration

  • Verify credentials were correctly re-entered (they don’t auto-migrate).
  • Check that all imports completed successfully in the UI.
  • Ensure .n8n mount has enough storage space.

Next steps

You now have a production-ready n8n setup on Upsun. From here, you can:
  • Add more workflows without performance concerns.
  • Enable API access for external integrations.
  • Set up monitoring with Upsun’s observability tools.
  • Integrate with your CI/CD pipeline for workflow deployment.
Want to share how you’re using n8n on Upsun? Tweet us @Upsun.

Resources

Last modified on April 29, 2026