Nuclear solution to self hosted n8n disk space growing and creating disk full problem

DELETE FROM execution_entity WHERE startedAt < datetime(‘now’, ‘-100 hours’);

sqlite> DELETE FROM execution_data
WHERE executionId NOT IN (SELECT id FROM execution_entity);
sqlite> VACUUM;

Unless someone can show me otherwise n8n pruning is completely broken. I have given my evidence later in this post. If I didn’t no better I would think that this is a bug on purpose to limit the usefulness of self hosting. Certainly google shows MANY posts with people having uncontrolled n8n disk usage with no solution that works I could find.

In the meantime here in my NUCLEAR fix which I run in a crontab daily and works perfect.

Manual proof it works (for the technical sceptics like me)

root@srv1008667:/var/lib/docker/volumes/n8n_data/_data# sqlite3 database.sqlite “DELETE FROM execution_data WHERE executionId NOT IN (SELECT id FROM execution_entity);”
root@srv1008667:/var/lib/docker/volumes/n8n_data/_data# ls -lh database.sqlite
-rw-r–r-- 1 ubuntu ubuntu 3.3G Nov 25 07:55 database.sqlite
root@srv1008667:/var/lib/docker/volumes/n8n_data/_data# sqlite3 database.sqlite “VACUUM;”
root@srv1008667:/var/lib/docker/volumes/n8n_data/_data# ls -lh database.sqlite
-rw-r–r-- 1 ubuntu ubuntu 762M Nov 25 07:55 database.sqlite

3.3GB down to less than 1GB :slight_smile: Nice.

To all my fellow IT professionals YES I KNOW I DIDN’T TAKE MY DOCKER N8N INSTANCE DOWN. Pruning live at worst case will cause access problems for log tables. But taking the db down forces inability to access. That’s my sloppy logic anyway lol.

How to configure the nuclear solution:

I am on hostinger so your path may vary:

40 4 * * * sqlite3 /var/lib/docker/volumes/n8n_data/_data/database.sqlite “DELETE FROM execution_entity WHERE id NOT IN (SELECT id FROM execution_entity ORDER BY startedAt DESC LIMIT 1000); DELETE FROM execution_data WHERE executionId NOT IN (SELECT id FROM execution_entity); VACUUM;” 2>&1 | logger -t n8n-prune

Edit root’s crontab (since you need access to /var/lib/docker)

sudo crontab -e

Add the line above, save and exit

Note: Alternate approach is time based purge: DELETE FROM execution_entity WHERE startedAt < datetime(‘now’, ‘-100 hours’);

EVIDENCE N8N IS BROKEN:

Here are my env settings via docker inspect just to prove i dont have some crazy syntax error in my yaml file:

docker inspect root-n8n-1 | grep -A 20 “Env”
“Env”: [
“N8N_SMTP_SSL=false”,
“DB_SQLITE_VACUUM_ON_STARTUP=true”,
“N8N_SMTP_USER=xxxxxxxxxxxxxxxxxx”,
“N8N_SMTP_PASS=xxxxxxxxxxxxxxxx”,
“EXECUTIONS_DATA_PRUNE=true”,
“N8N_SMTP_PORT=587”,
“N8N_HOST=n8n.xxxxxxxxx.hstgr.cloud”,
“EXECUTIONS_DATA_PRUNE_MAX_COUNT=1000”,
“N8N_EMAIL_MODE=smtp”,
“N8N_PROTOCOL=https”,
“NODE_ENV=production”,
“N8N_SMTP_SENDER=xxxxxxxx”,
“WEBHOOK_URL=https://n8n.xxxxxxxxxx.hstgr.cloud/”,
“N8N_PORT=5678”,
“GENERIC_TIMEZONE=America/Toronto”,
“N8N_SMTP_STARTTLS=true”,
“EXECUTIONS_DATA_MAX_AGE=100”,
“N8N_SMTP_HOST=smtp.fastmail.com”,
“PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”,
“NODE_VERSION=22.21.0”,

All pruning options are being ignored as far as i can see. I have restarted the docker with no effect.

Docker logs show no pruning is even being attempted and I waited about 30 min before checking these logs:

root@srv1008667:/var/lib/docker/volumes/n8n_data/_data# docker logs -f root-n8n-1
Permissions 0644 for n8n settings file /home/node/.n8n/config are too wide. This is ignored for now, but in the future n8n will attempt to change the permissions automatically. To automatically enforce correct permissions now set N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true (recommended), or turn this check off set N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false.
Last session crashed
Initializing n8n process
n8n ready on ::, port 5678

There are deprecations related to your environment variables. Please take the recommended actions to update your configuration:

  • DB_SQLITE_POOL_SIZE → Running SQLite without a pool of read connections is deprecated. Please set DB_SQLITE_POOL_SIZE to a value higher than zero. See: Database environment variables | n8n Docs
  • N8N_RUNNERS_ENABLED → Running n8n without task runners is deprecated. Task runners will be turned on by default in a future version. Please set N8N_RUNNERS_ENABLED=true to enable task runners now and avoid potential issues in the future. Learn more: Task runners | n8n Docs
  • N8N_BLOCK_ENV_ACCESS_IN_NODE → The default value of N8N_BLOCK_ENV_ACCESS_IN_NODE will be changed from false to true in a future version. If you need to access environment variables from the Code Node or from expressions, please set N8N_BLOCK_ENV_ACCESS_IN_NODE=false. Learn more: Security environment variables | n8n Docs
  • N8N_GIT_NODE_DISABLE_BARE_REPOS → Support for bare repositories in the Git Node will be removed in a future version due to security concerns. If you are not using bare repositories in the Git Node, please set N8N_GIT_NODE_DISABLE_BARE_REPOS=true. Learn more: Security environment variables | n8n Docs

[license SDK] Skipping renewal on init: license cert is not due for renewal
Currently active workflows:

  • Jarvis Personal (ID: fpSsLu462VHdqW9k)
  • GHL Estimate Manager (ID: GMcZQqIDVTZHDtYm)
  • Sync Facebook Lead Ads to Google Sheets & Salesforce CRM (ID: wbIDvlm87CmWojFC)
  • Customer Chat STAGE SPLITTER (ID: 1o8gcAi3K5LtV6sU)
  • Nano Banana Parallel Processing Sub Workflow (ID: eSyt8CBo21pCmlBt)
    Version: 1.119.2
    Start Active Workflows:
    Activated workflow “Jarvis Personal” (ID: fpSsLu462VHdqW9k)
    Activated workflow “GHL Estimate Manager” (ID: GMcZQqIDVTZHDtYm)
    Activated workflow “Sync Facebook Lead Ads to Google Sheets & Salesforce CRM” (ID: wbIDvlm87CmWojFC)
    Activated workflow “Customer Chat STAGE SPLITTER” (ID: 1o8gcAi3K5LtV6sU)
    Activated workflow “Nano Banana Parallel Processing Sub Workflow” (ID: eSyt8CBo21pCmlBt)

Editor is now accessible via:

SQLITE_BUSY: database is locked
SQLITE_BUSY: database is locked
Received request for unknown webhook: The requested webhook “POST 89530b2c-f575-4501-a0bc-82d6a3f48e6c” is not registered.
Received request for unknown webhook: The requested webhook “POST 89530b2c-f575-4501-a0bc-82d6a3f48e6c” is not registered.
Received SIGTERM. Shutting down…
Deregistered all crons for workflow

Stopping n8n…
Permissions 0644 for n8n settings file /home/node/.n8n/config are too wide. This is ignored for now, but in the future n8n will attempt to change the permissions automatically. To automatically enforce correct permissions now set N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true (recommended), or turn this check off set N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false.
Initializing n8n process
n8n ready on ::, port 5678

There are deprecations related to your environment variables. Please take the recommended actions to update your configuration:

  • DB_SQLITE_POOL_SIZE → Running SQLite without a pool of read connections is deprecated. Please set DB_SQLITE_POOL_SIZE to a value higher than zero. See: Database environment variables | n8n Docs
  • N8N_RUNNERS_ENABLED → Running n8n without task runners is deprecated. Task runners will be turned on by default in a future version. Please set N8N_RUNNERS_ENABLED=true to enable task runners now and avoid potential issues in the future. Learn more: Task runners | n8n Docs
  • N8N_BLOCK_ENV_ACCESS_IN_NODE → The default value of N8N_BLOCK_ENV_ACCESS_IN_NODE will be changed from false to true in a future version. If you need to access environment variables from the Code Node or from expressions, please set N8N_BLOCK_ENV_ACCESS_IN_NODE=false. Learn more: Security environment variables | n8n Docs
  • N8N_GIT_NODE_DISABLE_BARE_REPOS → Support for bare repositories in the Git Node will be removed in a future version due to security concerns. If you are not using bare repositories in the Git Node, please set N8N_GIT_NODE_DISABLE_BARE_REPOS=true. Learn more: Security environment variables | n8n Docs

[license SDK] Skipping renewal on init: license cert is not due for renewal
Version: 1.119.2
Start Active Workflows:
Activated workflow “Jarvis Personal” (ID: fpSsLu462VHdqW9k)
Activated workflow “GHL Estimate Manager” (ID: GMcZQqIDVTZHDtYm)
Activated workflow “Sync Facebook Lead Ads to Google Sheets & Salesforce CRM” (ID: wbIDvlm87CmWojFC)
Activated workflow “Customer Chat STAGE SPLITTER” (ID: 1o8gcAi3K5LtV6sU)
Activated workflow “Nano Banana Parallel Processing Sub Workflow” (ID: eSyt8CBo21pCmlBt)

Editor is now accessible via:

  • n8n version: 1.119.2
  • Database (default: SQLite): sqlite3
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app): self hosted docker
  • Operating system: ubuntu on hostinger
1 Like

We execute database.sqlite "VACUUM;" once per week, and the n8n SQLite database size remains stable at around 1 GB. With approximately 30,000 executions per week, I consider this result to be quite satisfactory.

1 Like

Thanks for the feedback. It is good to know it is working for some. Not sure why it is so much of a problem for many including myself. Anyway I posted this alternative for those struggling to get the proper way working.

Nice workaround , but I prefer Postgres for production.

Why? … n8n suggest that in docs.

And never had any kind of issue… and hope it stays like that ! :slight_smile:

Cheers!