From f637a374779c1ac04b3c5d9685b62d0fca5a0182 Mon Sep 17 00:00:00 2001 From: Marvin Date: Tue, 18 Aug 2026 06:50:17 +0200 Subject: [PATCH 1/3] fix: clear attachments and headers in the email cleanup job The retention cleanup job only nulls text and html, but attachments (base64-encoded, typically the largest column) and headers survive it. Successful sends already clear both right after sending, so this mainly affects failed, cancelled and stuck emails, which keep their attachments forever even with EMAIL_CLEANUP_DAYS configured. Include both columns in the cleanup update and extend the filter so already-clean rows are still skipped. --- apps/web/src/server/jobs/cleanup-email-bodies.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/web/src/server/jobs/cleanup-email-bodies.ts b/apps/web/src/server/jobs/cleanup-email-bodies.ts index a8020c965..cb000bc4c 100644 --- a/apps/web/src/server/jobs/cleanup-email-bodies.ts +++ b/apps/web/src/server/jobs/cleanup-email-bodies.ts @@ -37,11 +37,15 @@ if (isSelfHosted() && isEmailCleanupEnabled()) { OR: [ {text: {not: null}}, {html: {not: null}}, + {attachments: {not: null}}, + {headers: {not: null}}, ], }, data: { text: null, html: null, + attachments: null, + headers: null, }, }); From d5346c1bbb7a4de7918357b27449819d4c756f49 Mon Sep 17 00:00:00 2001 From: Marvin Date: Tue, 18 Aug 2026 07:09:44 +0200 Subject: [PATCH 2/3] docs: document the EMAIL_CLEANUP_DAYS retention setting The setting existed in the env schema but was not mentioned in the self-hosting docs or the example env file. --- .env.selfhost.example | 5 +++++ apps/docs/self-hosting/overview.mdx | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/.env.selfhost.example b/.env.selfhost.example index 976d7782a..dd6da8125 100644 --- a/.env.selfhost.example +++ b/.env.selfhost.example @@ -41,5 +41,10 @@ AUTH_EMAIL_RATE_LIMIT=5 # Optional: prefix all Redis keys (useful for shared Redis with ACL isolation) # REDIS_KEY_PREFIX="" +# Optional: delete stored email content (text, html, attachments, headers) from +# the database after this many days. Runs daily at midnight UTC. Disabled if +# unset or not a positive number. +# EMAIL_CLEANUP_DAYS=30 + # used to send important error notification - optional DISCORD_WEBHOOK_URL="" diff --git a/apps/docs/self-hosting/overview.mdx b/apps/docs/self-hosting/overview.mdx index 0a44b56dd..cbe5bb4f6 100644 --- a/apps/docs/self-hosting/overview.mdx +++ b/apps/docs/self-hosting/overview.mdx @@ -80,6 +80,16 @@ Add the following environment variables. NEXTAUTH_SECRET="" ``` + + + By default, stored email content stays in the database forever. To bound database growth, set `EMAIL_CLEANUP_DAYS` to a positive number of days. A daily job (midnight UTC) then deletes the `text`, `html`, `attachments` and `headers` columns of emails older than the cutoff. Delivery status and event history are kept. + +```env +EMAIL_CLEANUP_DAYS=30 +``` + +Leave it unset to keep email content indefinitely. + From e18522b6e1a954caa423342aaaa6a29299bcd136 Mon Sep 17 00:00:00 2001 From: Marvin Date: Tue, 18 Aug 2026 09:21:39 +0200 Subject: [PATCH 3/3] docs: clarify cleanup wording Clears values, does not delete columns. Drop the claim about non-numeric values, since the setting is parsed leniently. --- .env.selfhost.example | 6 +++--- apps/docs/self-hosting/overview.mdx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.env.selfhost.example b/.env.selfhost.example index dd6da8125..2edfff36d 100644 --- a/.env.selfhost.example +++ b/.env.selfhost.example @@ -41,9 +41,9 @@ AUTH_EMAIL_RATE_LIMIT=5 # Optional: prefix all Redis keys (useful for shared Redis with ACL isolation) # REDIS_KEY_PREFIX="" -# Optional: delete stored email content (text, html, attachments, headers) from -# the database after this many days. Runs daily at midnight UTC. Disabled if -# unset or not a positive number. +# Optional: clear stored email content (text, html, attachments, headers) from +# the database after this many days. Runs daily at midnight UTC. Leave unset to +# keep email content indefinitely. # EMAIL_CLEANUP_DAYS=30 # used to send important error notification - optional diff --git a/apps/docs/self-hosting/overview.mdx b/apps/docs/self-hosting/overview.mdx index cbe5bb4f6..cadffa87d 100644 --- a/apps/docs/self-hosting/overview.mdx +++ b/apps/docs/self-hosting/overview.mdx @@ -82,7 +82,7 @@ Add the following environment variables. - By default, stored email content stays in the database forever. To bound database growth, set `EMAIL_CLEANUP_DAYS` to a positive number of days. A daily job (midnight UTC) then deletes the `text`, `html`, `attachments` and `headers` columns of emails older than the cutoff. Delivery status and event history are kept. + By default, stored email content stays in the database forever. To bound database growth, set `EMAIL_CLEANUP_DAYS` to a positive number of days. A daily job (midnight UTC) then clears the `text`, `html`, `attachments` and `headers` values for emails older than the cutoff. Delivery status and event history are kept. ```env EMAIL_CLEANUP_DAYS=30