A small cross-platform desktop utility that continuously empties the Gmail Trash folder over IMAP —
built for mailboxes with millions of messages, where the web UI's “Empty Trash now” hangs and gives up.
Русская версия
On very large mailboxes Gmail's “Empty Trash now” button is unreliable: the operation stalls, times out and has to be restarted by hand. This tool connects over IMAP and grinds through the Trash in batches for as long as it is running — surviving connection drops, Gmail throttling errors and hour-long sessions without supervision. The Trash may keep being refilled from outside (e.g. you keep deleting mail in the web UI); the cleaner just keeps draining it.
- Batch deletion —
STORE +FLAGS.SILENT (\Deleted)+EXPUNGEby sequence numbers, 1–10 000 messages per batch (default 1000). - Runs unattended for hours — automatic reconnect 30 s after a connection drop; 120 s backoff on Gmail's
[ALERT] Too many simultaneous connections; unlimited retries. - Gmail-aware error handling — sporadic
NO System Error (Failure)responses on STORE/EXPUNGE are treated as routine: logged, then the loop continues. - Single IMAP connection for both the cleaning worker and the counters — Gmail's ~15-connection limit is shared with your other mail clients.
- Live statistics — messages left in Trash, messages in All Mail, deleted this session, speed (messages/min) and ETA.
- Real-time chart — Trash and All Mail counts over time (ScottPlot).
- Log panel — timestamped, auto-scrolling, last 500 lines.
- Idle-aware — when the Trash is empty it keeps polling every 15 s and resumes deleting as soon as the Trash refills.
- Soft stop — Stop (or closing the window) waits for the current IMAP operation to finish instead of killing the connection mid-command.
- The app only ever modifies
[Gmail]/Trash. All Mail is read withSTATUS— never written. - The password is never stored — you type it on every launch. Only the email and batch size are saved to a local JSON file.
- Expunging messages from Trash is permanent. That is the entire point of this tool — but make sure it is what you want.
- .NET 10 SDK
- A Gmail account with:
- IMAP access enabled (Gmail → Settings → Forwarding and POP/IMAP),
- an App Password (requires 2-Step Verification) — OAuth is deliberately not used,
- the Trash folder visible over IMAP (Gmail → Settings → Labels → Trash → Show in IMAP).
dotnet run --project src/GmailTrashCleanerWorks on Windows, macOS and Linux (Avalonia UI, no platform-specific dependencies).
loop while not stopped:
SELECT "[Gmail]/Trash" -> count
if count == 0: update counters, wait 15 s, continue
n = min(count, batch size)
STORE 1:n +FLAGS.SILENT (\Deleted) # sequence numbers, not UIDs
EXPUNGE
update statistics and chart
- IMAP endpoint:
imap.gmail.com:993, SSL-on-connect, LOGIN with the app password. - Socket timeout is 300 s — Gmail operations on huge folders can legitimately take minutes.
- Counters (
STATUS "[Gmail]/All Mail"/ Trash count) refresh roughly every 30 s and after every deleted batch, over the same connection.
Email and batch size are stored in:
| OS | Path |
|---|---|
| Windows | %APPDATA%\GmailTrashCleaner\settings.json |
| Linux | ~/.config/GmailTrashCleaner/settings.json |
| macOS | ~/Library/Application Support/GmailTrashCleaner/settings.json |
The password is never written to disk.
Avalonia UI 12 · MailKit · ScottPlot 5 · CommunityToolkit.Mvvm · .NET 10
