How I clean up my Gmail inbox
Manual Cleanup
Every so often, my e-mail inbox fills up with unread messages -- newsletters, promotions, payment confirmation and other messages I don't need. If the number is still relatively low (say 100-200), I just do a manual cleanup. I do a search using this query: is:unread category:primary
, then I go through each sender, delete what I don't need and unsubscribe if necessary. To find the e-mails from each sender I just extend the search query to is:unread category:primary from:<the-sender-address>
. This works well as most of the times there's a small number of senders sending a large number of e-mails.
However, when the number of unread e-mails gets too large, this approach becomes tedious. Therefore, I'm using a small Google Apps Script to find top senders.
Enter Light Automation
It automates just the search part as I still want to manually delete/unsubscribe what's no longer needed.
const MAX_THREADS = 1000;
const TOP_SENDERS = 20;
function findTopSenders() {
const query = 'is:unread category:primary';
const batchSize = 500;
const senderCount = {};
let totalThreadsProcessed = 0;
for (let start = 0; start < MAX_THREADS; start += batchSize) {
Logger.log(`Processing batch starting at thread #${start + 1}`);
const threads = GmailApp.search(query, start, batchSize);
if (threads.length === 0) {
Logger.log("No more threads found. Ending early.");
break;
}
totalThreadsProcessed += threads.length;
for (const thread of threads) {
const firstMsg = thread.getMessages()[0];
const senderRaw = firstMsg.getFrom();
const sender = senderRaw.replace(/.*<(.+?)>/, '$1').trim();
if (senderCount[sender]) {
senderCount[sender]++;
} else {
senderCount[sender] = 1;
}
}
Logger.log(`Batch complete. Threads processed so far: ${totalThreadsProcessed}`);
}
Logger.log(`\nFinished processing ${totalThreadsProcessed} threads.`);
const sorted = Object.entries(senderCount).sort((a, b) => b[1] - a[1]);
Logger.log(`\nTop ${MAX_THREADS} senders:`);
for (let i = 0; i < Math.min(MAX_THREADS, sorted.length); i++) {
Logger.log(`${i + 1} -- ${sorted[i][1]}: ${sorted[i][0]}`);
}
}
Once it runs, the log will look something like this:
Top 20 senders:
5:51:31 PM Info 1. refactoring@substack.com: 53
5:51:31 PM Info 2. inmail-hit-reply@linkedin.com: 49
5:51:31 PM Info 3. updates-noreply@linkedin.com: 47
...
5:51:31 PM Info 5. info@email.meetup.com: 39
5:51:31 PM Info 6. office@standartmag.com: 31
...
What's left to do is select each sender, rerun the search in Gmail and take action - delete, unsubscribe or mark as read. As already mentioned, this is quite fast as most of the e-mails come from a small number of senders.
Why this approach
Out of curiosity, I also tested the Gemini assistant but it's unable to handle this task correctly. It either produces wrong results or plain refuses to help with the task.
Reasonable, low-code or no-code alternatives would be using a paid service or finding a free extension. However, almost always it'a hassle going over their privacy policies (critical since they will have access to my e-mail account) or they are too expensive for something this simple.
Why not fully automate it? For now, the little time I spend manually cleaning up doesn't justify spending time on correctly automating the process.
That said, I've started to consider automating the process by implementing a lightweight AI agent that learns to triage incoming e-mail automatically.