-
Notifications
You must be signed in to change notification settings - Fork 0
Feature Storage
English · Tiếng Việt · 中文
Settings ▸ Storage, hidden behind the storage flag from 0.1.0 until it
was turned on in 1.14.0. This page covers what the screen actually does
today — where cached message bodies live and how to move them, and why the
database section next to it is a runbook rather than a button.
Two unrelated decisions live on one screen because they are both about where SkimMail keeps its bytes: which blob engine holds cached message bodies (local filesystem, or an S3-compatible bucket), and which database engine holds everything else (SQLite by default, or Postgres/MySQL). This page covers the blob engine in full — it has real, working switch-and-test-and- migrate actions — and the database section honestly, which today is a copy of commands, not an automated migration.
Settings ▸ Storage, owner only. The screen carries an "Advanced" badge in its own header — not a technicality, a genuine warning that changing the active engine changes where your data physically lives.
The storage flag stayed off from 0.1.0 through 1.13.0 for one specific
reason, worth knowing if you read an old screenshot or an old release note:
the database section carried a "Migrate database…" button that opened a
wizard telling the operator to rebuild SkimMail with -tags postgres first.
That was never true for anyone running an official build — every released
tarball, .deb, and container image has folded in postgres, mysql and
s3 support since 1.4.3 — so the instruction was not merely unnecessary,
it described a step a self-hoster with no Go toolchain could not perform at
all. 1.14.0 didn't add a missing feature; it stopped a real screen from
claiming to be a different one, and turned the flag on now that the screen's
own words are true.
Two engines, picked with a toggle: Filesystem (the default — cached
bodies live under DATA_DIR/blobs, and backing them up is exactly "copy
DATA_DIR", see Operations) or S3-compatible (any endpoint
speaking the S3 API — MinIO, Cloudflare R2, Backblaze B2, Wasabi, or AWS S3
itself), configured with an endpoint, bucket, region, access key and secret
key, plus an optional path-style toggle for endpoints that need it.
Objects are always streamed through SkimMail, never served from a public bucket URL — even on S3, message content keeps the same sanitization, tracker-blocking and per-request authorization that filesystem storage has, and frequently-read blobs are cached locally for speed regardless of which engine is active. Choosing S3 does not turn your bucket into something a mail client or a browser talks to directly.
Test connection builds the candidate configuration and probes it with one
cheap Stat call against a sentinel key — a "not found" response counts as
success, since it proves the bucket and credentials are reachable without
requiring anything to already exist there. Run this before saving; a
misconfigured S3 target is refused at save/switch time by the same probe (see
below), but seeing the failure early costs nothing.
This is the one distinction worth reading twice before you press either:
- Save persists the new engine and switches the live blob cache to it immediately. If the new location is genuinely different from the old one (a different S3 bucket, or crossing from filesystem to S3 or back — rotating only an S3 access key does not count as a move), the old engine's cached bodies are left behind, unreferenced, and the index that pointed at them is dropped. Nothing is deleted from the old store — SkimMail will not reach into an S3 bucket that might also be your backup destination and start removing objects — but nothing that used to be cached is copied forward either. This is safe precisely because the body cache is a cache: anything abandoned this way is simply re-fetched from each account's IMAP server the next time it's opened.
- Switch & migrate does the same switch, then walks every key in the old store and copies it into the new one in the background, skipping keys already present (safe to re-run) and counting copied/skipped/failed as it goes. This is the one to use if you want yesterday's cached bodies to still be a local hit on the new engine instead of a fresh IMAP fetch.
Either way, the previous engine's stored objects are never deleted by this screen. A switch is safe to reconsider: point the configuration back and your old bytes, if you didn't already overwrite that bucket with something else, are still there.
Moving from SQLite to Postgres or MySQL is presented as a wizard that
prints commands for you to run, not an action SkimMail performs on your
behalf: pick a target engine, paste a connection string (checked only for
shape — a regex, not a real connection attempt), and get back a short script
using skimmail config set (or the equivalent environment
variables, which win over a config-set value) to point the server at the new
database, plus a reminder to sign in again afterward.
No rows are copied. SkimMail's message store is a cache it rebuilds from
each account's IMAP server, so "migrating" the database means standing up an
empty Postgres or MySQL instance, pointing SkimMail at it, and re-adding your
accounts — the sync that follows repopulates everything. Your existing
SQLite file under DATA_DIR is left completely untouched, which is what
makes the whole thing reversible: point the configuration back at
DB_DRIVER=sqlite and you are exactly where you started.
| Available since | 1.14.0 (flag turned on); the blob-engine mechanics themselves are 1.11.0 |
| Role | owner |
| Blob engines | filesystem, S3-compatible |
| Database "migration" | a runbook (commands to copy), not an automated action |
| Concurrency | one blob backfill at a time; starting a second while one runs is a no-op |
| S3 availability | compiled into every official build since 1.4.3 |
- It does not migrate the database for you. The wizard on this screen validates a connection string's shape and hands you commands; it makes no network call and copies no rows. See above.
- Switching the blob engine with plain Save does not carry old blobs forward. Only Switch & migrate does that; Save alone abandons them in the old store (never deletes them) and forgets the index.
- It never deletes objects in the store you are leaving. That bucket or directory might be a backup destination too (see Backup and restore); this screen will not guess that it's safe to clear it.
- A rotated S3 secret key is not treated as a location change. Only the endpoint/bucket/region/path-style identify "the same place" — updating credentials alone triggers neither an abandonment nor a migration.
-
Operations — filesystem backup, and where
blobs/sits underDATA_DIR - Message body cache — what is actually stored in a blob, its size/age limits, and at-rest encryption
-
Configuration — the three-plane model,
skimmail config, and the boot-onlyDB_DRIVER/DATABASE_URL/BLOB_STORE/S3_*variables
SkimMail · skimmail@base101.app · 2026-09-15 · commit dffbb18