Skip to main content

mailcellar

CI Docs PyPI Python License

Gmail full? Keep every email on your own disk, and free the space.

Your mail lives on someone else's server, in a mailbox with a size limit. When it fills up you can pay for more storage, or delete mail you may need later. mailcellar gives you a third way: a complete, checked backup on your own disk, then old mail taken out of the mailbox by rules you write and review, still searchable and restorable whenever you need it. It works with Gmail and Google Workspace, and with any IMAP mailbox: iCloud Mail, Yahoo Mail, Fastmail, or your own server.

Why mailcellar

  • Your storage is full. Offload old mail by rule (older than five years, newsletters, large attachments) and keep it in the backup: the space comes back and nothing is lost.
  • You have no backup of your own. Providers keep your mail safe from their own failures, not from a deletion, a compromised account, or being locked out. A provider's export copies everything again each time, with nothing to say it's complete. mailcellar fetches only what changed, compares each account with its backup (count) and checks the files (verify).
  • Old mail must stay findable. search covers every backup, offloaded mail included, and restore puts back one message, a batch or a whole account.
  • Your mail is with more than one provider. One backup, one search and one set of reports cover Gmail and IMAP accounts side by side.
  • You're moving to another provider. restore --to copies mail from one account to another, Gmail to IMAP or back: labels become folders and folders labels, and the backup records what moved.

What it does

  • Back up every account incrementally, in Got Your Back's format; an existing gyb backup carries on where it is.
  • Offload old mail by rule, in stages you check: plan, review, mark, look in your mail client, then trash. The backup is checked for every message before it goes, and nothing is ever deleted permanently.
  • Find and restore: search the backups, offloaded mail included, and put mail back into the same account or another.
  • Deduplicate, export and report: remove duplicate copies within and across accounts, copy mail out as an mbox or a zip, and see what takes up the space.
  • Keep mail as it is: a hash chain shows the backup hasn't changed since each message was saved (verify --chain), and a legal hold keeps the mail a dispute or an audit needs out of reach of offloading, pruning and dedup, in the mailbox and in the backup.

What changes your mailbox. Only offload apply, dedup apply and restore --yes, and each is a dry run until you add a flag. Offload and dedup mark mail for review, then move it to Trash: nothing is ever permanently deleted, and Gmail keeps Trash for 30 days. On an IMAP server this happens only where the server can move mail safely; elsewhere mailcellar backs up only. restore only puts mail back: out of Trash, or as an upload. Everything else, backup included, only reads (details).

Your mail stays yours. mailcellar runs on your own computer: there is no service in between, and your mail goes nowhere but between the mailbox and your disk. Gmail is read through your own Google Cloud project (about ten minutes to set up, guide); an IMAP account needs only its password (an app password, where the provider asks for one). mailcellar is in beta: it is used on real mailboxes, and its backups are in gyb's fixed format, but commands and options may still change before 1.0. It runs on macOS and Linux and needs Python 3.14, which uv installs for you.

Commands

mailcellar setup   [ADDRESS]       add a Gmail account (OAuth client) or an IMAP one (--imap)
mailcellar backup  [ACCOUNT ...]   incremental backups in gyb's format
mailcellar count   [ACCOUNT ...]   compare the mailbox with the backup
mailcellar meta    [ACCOUNT ...]   fill the per-message sidecar for older mail
mailcellar verify  [ACCOUNT ...]   check that the backup's files are still intact
mailcellar schedule install|status|remove   run backups regularly, unattended
mailcellar dedup   …               find duplicates and remove them from the mailbox, in stages
mailcellar offload …               take old mail out of the mailbox, keeping it in the backup
mailcellar restore ACCOUNT …       put backed-up mail back, into its account or another
mailcellar export  ACCOUNT …       copy mail out as an mbox file or a zip of .eml files
mailcellar search  QUERY …         find mail in the backups, offloaded mail included
mailcellar hold    add|list|show|release   keep mail for a dispute or an audit
mailcellar report  …               storage, bulk mail, volume, threads, labels, correspondents,
                                   backup health, top senders
mailcellar config                  where the config and data live; each account's state

backup, count and meta take every configured account unless given some (an address, a config name like work, or a unique part of an address). Each command takes --help.

Results go to stdout; progress, warnings and errors go to stderr. Add -v anywhere on the line to also see the server's retries and rate-limit waits (waits of 10 seconds or more show without it), or -q to see only warnings and errors.

How it fits together: How it works.

Quick start

You need uv (it provides Python 3.14).

  1. Install.

    uv tool install mailcellar    # from PyPI; puts the mailcellar command on your PATH
    

    pipx install mailcellar works too, with Python 3.14. To run it from a clone instead, see Development.

  2. Add an account, one of these two ways.

    Gmail or Google Workspace. Create an OAuth client in the Google Cloud console: a project with the Gmail API enabled, a consent screen with yourself as a test user, and an OAuth client of type Desktop app. Download its JSON. The step by step version, including Testing versus In production (Testing tokens expire after 7 days), is Setting up Google Cloud. Then:

    mailcellar setup alex@example.org --client ~/Downloads/client_secret_*.json
    

    Any other mailbox, over IMAP (iCloud Mail, Yahoo Mail, Fastmail, your own server). Most providers want an app password, made in their account settings; give setup the server, and it asks for the password:

    mailcellar setup alex@example.org --imap imap.mail.yahoo.com
    
    Provider Server Note
    iCloud Mail imap.mail.me.com --username with the part before @; backup only (no IMAP MOVE)
    Yahoo Mail imap.mail.yahoo.com add --review folder to offload: Yahoo keeps no custom keywords
    Fastmail imap.fastmail.com not yet tried with mailcellar

    More in Backing up an IMAP account.

    Either way, setup signs in read-only, changes nothing in the mailbox, and names the account after the address (alex; --name chooses another). The backups go in ~/mailcellar; to keep them elsewhere, set data_dir in ~/.config/mailcellar/settings.toml (Configuration).

  3. Back up, then check.

    mailcellar config         # the config and data folders; each account's state
    mailcellar backup alex    # the first backup; resumes where it left off if stopped
    mailcellar count alex     # what the mailbox has against what the backup has
    
  4. Schedule it.

    mailcellar schedule install     # macOS: a launchd agent, weekly; elsewhere: a cron line
    

    For Gmail, back up at least every four weeks: Gmail keeps change history about that long, and a longer gap lists the whole mailbox again. If its consent screen is in Testing, tokens expire after 7 days: publish it, or renew with mailcellar auth alex --scope readonly --renew. An IMAP account has no token to renew. See Scheduled backups.

Then keep the backup safe, and when you are ready to free space, offload old mail.

Documentation

The documentation site has the guides and the reference.

Guides, in the order you will want them:

Command reference, every command and option:

Development

To run mailcellar from a clone, with the tests and tools:

git clone https://github.com/mailcellar/mailcellar.git
cd mailcellar
uv sync                                    # the dependencies, and mailcellar in editable mode
uv run mailcellar config                   # every command, run from the clone
uv run pytest                              # all tests; no network, never the real config or data
uv run pytest --cov                        # the same, with a branch-coverage report
uv run ruff format && uv run ruff check

The code is one package, src/mailcellar/: cli.py dispatches to backup/, dedup/, offload/, restore/ and report/, which share paths.py, gmailapi.py and message.py. uv sync installs it in editable mode; python -m mailcellar works too. See How it works.

How to contribute, and the rules changes follow: CONTRIBUTING.md.

Acknowledgements

mailcellar's backups use the on-disk format of Got Your Back (gyb) by the GAM team, so backups made by either tool can be read by the other. mailcellar is a separate project and shares no code with gyb.

mailcellar is not affiliated with or endorsed by Google or the gyb project. Gmail and Google Workspace are trademarks of Google LLC.

License

Apache License 2.0: see LICENSE and NOTICE.

Metadata

Release files for mailcellar 0.18.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mailcellar 0.18.0
File Size Uploaded Provenance Actions
mailcellar-0.18.0.tar.gz 418.7 kB With provenance Details for mailcellar-0.18.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for mailcellar 0.18.0
File Interpreter ABI Platform Actions
mailcellar-0.18.0-py3-none-any.whl Python 3 none any Details for mailcellar-0.18.0-py3-none-any.whl

Total release size: 695.4 kB

Release files / mailcellar-0.18.0.tar.gz

Download URL mailcellar-0.18.0.tar.gz
Size 418.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9a846be9c5d3db0e63e070c41d027ad93b68086178b211dcd669185be8fd0f8c
BLAKE2b-256 checksum
How to use checksums
900cb66b28e61581f8286d8a96c574913908cf483e31bfe3793f853263a2cc41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Release files / mailcellar-0.18.0-py3-none-any.whl

Download URL mailcellar-0.18.0-py3-none-any.whl
Size 276.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d176467741784892a118e8a249f5b91d2861800cb61d881ac6681a72ca1a686f
BLAKE2b-256 checksum
How to use checksums
4b3c9d5d9f0f8f777e74d2f9a59d0e4479c326994f950d433b4933b5409466f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Security for mailcellar 0.18.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for mailcellar-0.18.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page