Martin's Blog

Gmail Inbox Cleanup: Retention Policies, API Limits, and a CLI That Actually Works

Google launched Gmail in 2004. If you’ve been using it since then, you have 22 years of accumulated email — newsletters you never unsubscribed from, notification spam from services that no longer exist, and thousands of conversations you’ll never open again. Cleaning this up should be straightforward. It isn’t.

The 15 GB ceiling

Every Google account comes with 15 GB of free storage shared across Gmail, Drive, and Photos. A decade of email with attachments fills this quickly. When you hit the limit, Google’s solution is Google One — starting at a couple of euros per month for 100 GB.

Google has little incentive to make cleanup easy. The harder it is to delete old data, the sooner you reach that 15 GB ceiling, and the more likely you are to pay for additional storage. Whether this is by design or neglect, the result is the same: consumer Gmail provides almost no tools for managing data at scale.

Retention policies: available for Workspace, absent for consumers

Google Workspace administrators can configure retention policies that automatically delete emails after a specified period. Consumer Gmail offers nothing equivalent — no setting, no toggle, no hidden menu. You cannot tell Gmail “delete everything older than five years” and have it enforced automatically.

This is the single feature that would make inbox maintenance trivial. Its absence is what makes everything that follows necessary.

What Google provides instead

Manual deletion through the web UI

The Gmail web interface supports search filters like older_than:5y. This finds matching messages, but you can only select and delete approximately 50 conversations at a time. For a mailbox with 80,000 old messages, that’s 1,600 rounds of select-all, delete, wait for reload, repeat.

The “Select all conversations that match this search” option helps in theory. In practice, it frequently times out or silently fails on large result sets. There’s no progress indicator — you’re left guessing whether the operation completed.

Google Apps Script

The natural next step is programmatic access. Apps Script provides a JavaScript API for Gmail:

function deleteOldEmails() {
  var threads = GmailApp.search("older_than:5y");
  for (var i = 0; i < threads.length; i++) {
    threads[i].moveToTrash();
  }
}

This works for small mailboxes. The moment you process thousands of threads, you hit the hard execution time limit of 6 minutes. The script terminates mid-run.

You can work around this with batching and time-based triggers — process N threads per invocation and schedule repeated runs. But triggers have daily quotas, the search index sometimes returns stale results after recent deletions, and you end up building a fragile state machine to accomplish what should be a single operation. For mailboxes accumulated over 15+ years, Apps Script cannot keep up. The quota limits and timeouts make it impractical for serious cleanup.

Approach Limit Practical result
Web UI manual delete ~50 conversations per action Hours of repetitive clicking
Web UI “select all” Timeouts on large result sets Silent failures, no progress feedback
Apps Script 6-minute execution limit Partial runs, requires manual restarts or fragile trigger chains
Apps Script triggers Daily quotas Cannot process large backlogs in reasonable time

The Google Workspace CLI

The Google Workspace CLI (gws) is a command-line tool that talks directly to Google’s APIs. Unlike Apps Script, it runs on your machine with no execution time limits. It supports pagination, batch operations, and direct access to the Gmail API’s more powerful endpoints.

The relevant API capabilities:

Endpoint Behavior Limit
messages.list Search with pagination --page-all --page-limit 1000 for full retrieval
messages.batchDelete Permanent deletion Up to 1,000 message IDs per call
messages.batchModify Move to trash (add TRASH label, remove INBOX) Up to 1,000 message IDs per call

With gws, a script can paginate through an entire mailbox, collect all matching message IDs, and delete them in batches of 1,000. No timeouts, no quotas, no silent failures. A mailbox with 100,000 old messages processes in minutes rather than days.

Using a coding agent to generate the scripts

Writing shell scripts against a REST API is tedious — pagination logic, JSON parsing with jq, error handling, confirmation prompts, batch size management. This is exactly the kind of task where a coding agent is effective.

Claude Code with Google Workspace skills has direct knowledge of the Gmail API and the gws CLI. You describe the operation in plain language:

The agent generates working scripts that handle the details: pagination through messages.list, batching into groups of 1,000 for batchDelete or batchModify, dry-run modes for verification, and explicit confirmation before any destructive operation.

A practical example

A typical cleanup workflow:

  1. Authenticate the gws CLI: gws auth login
  2. Ask the coding agent to generate a deletion script for your criteria
  3. Run with --dry-run to count matching messages
  4. Review the count, confirm, and execute

For a mailbox with 80,000 messages older than 10 years, the process — from first prompt to completed deletion — takes roughly 20 minutes. The agent writes the script in under a minute; the rest is API execution time.

# Dry run: count messages older than 10 years
./delete-old-emails.sh --years 10 --dry-run

# Permanent deletion after confirmation
./delete-old-emails.sh --years 10

# Move to trash instead of permanent deletion
./delete-old-emails.sh --years 10 --trash

# Include spam and trash in the search
./delete-old-emails.sh --years 10 --all

The state of things

Consumer Gmail lacks the one feature — retention policies — that would make inbox management automatic. The web UI isn’t designed for bulk operations. Apps Script hits hard limits before it can finish the job. The practical effect is that users either live with bloated inboxes, pay for more storage, or invest significant effort into manual cleanup.

The gws CLI removes the technical constraints. A coding agent removes the scripting effort. Together, they provide the cleanup capability that Gmail should have offered from the start.

#Gmail #Google-Workspace #Automation #Coding-Agent