
You get 100+ emails a day. Most of them are garbage — calendar notifications, LinkedIn alerts, Promotions tab spam, CI/CD build reports, newsletters you subscribed to three years ago and never read.
You know you should clean up. But who has 30 minutes every morning to manually delete Slack notifications from last week?
I built a free, open-source Google Apps Script that does this automatically. It runs inside your own Google account, deletes email noise based on rules you set, and sends you a daily report. No extensions, no third-party apps, no subscriptions.
Here is the full walkthrough — from the problem to a working solution in under 10 minutes.
The Problem: Your Inbox Is a Landfill
The average professional receives 121 emails per day. According to McKinsey, we spend 28% of our workday managing email. Most of that time is not spent on important messages — it is spent scrolling past automated noise.
Here is what a typical founder’s inbox looks like:
- Google Workspace notifications — calendar invites, Drive shares, Docs comments. Useful for 5 minutes, then dead weight for months.
- SaaS notifications — Slack, Notion, Zoom, Calendly, HubSpot, Stripe. Every tool you use sends at least 3-5 emails per day.
- Social media — LinkedIn connection requests, Facebook notifications, X/Twitter alerts. Piling up in the Social tab.
- Promotions — Every SaaS vendor, every conference, every newsletter. The Promotions tab alone can accumulate thousands of unread emails.
- Developer noise — GitHub PR reviews, CI build results, Sentry alerts, npm security advisories. Critical in the moment, worthless after a week.
The result: 50,000+ emails sitting in your account, 15 GB of storage eaten up, and a constant low-grade anxiety every time you open Gmail.
Why Existing Tools Are Not the Answer
There are paid tools that promise to solve this. None of them are good enough to justify the cost or the trade-offs.
Clean Email — $10/month ($120/year)
Clean Email is a decent product, but it requires full access to your Gmail via OAuth. You are giving a third-party company read/write access to every email you have ever sent or received. For what? Bulk unsubscribe and auto-clean rules that Gmail can already do natively with filters and Apps Script.
SaneBox — $7 to $36/month ($84-$432/year)
SaneBox routes your email through their servers to classify and prioritize messages. The AI classification is good, but you are paying $7-36/month for something that could be a few lines of Gmail search queries. And again — your emails pass through someone else’s infrastructure.
Unroll.me — Free, But You Are the Product
Unroll.me was caught selling user email data to Uber. Their entire business model is scanning your inbox and selling anonymized (or not so anonymized) purchase data to market research firms. Free is not free when your data is the product.
Gmail Filters — Free, But Limited
Gmail’s built-in filters can auto-delete or auto-archive, but they are painful to manage at scale. You cannot set time-based rules (“delete LinkedIn emails older than 7 days”), you cannot get reports on what was cleaned, and you cannot use advanced search operators in filter conditions. For 3-5 rules, filters work. For 20+ rules with time-based logic, you need something better.
The Solution: A Free Open-Source Apps Script
I built Gmail Auto-Cleanup — a Google Apps Script that runs entirely inside your Google account.
Here is what it does:
- Deletes old email noise on a daily schedule based on rules you define using Gmail search syntax
- Sends you an HTML email report after every cleanup with exact counts and sample subject lines
- Sends Telegram notifications (optional) so you get a ping on your phone
- Logs everything to a Google Sheet so you have a full history of what was cleaned
- Runs in dry-run mode first so you can preview exactly what will be deleted before enabling auto-cleanup
- Trash, not permanent delete — emails go to Trash where they stay for 30 days, fully recoverable
The key difference from paid tools: your data never leaves your Google account. The script runs on Google’s own infrastructure (Apps Script), uses only Gmail APIs that Google provides, and you can read every line of code.
No servers. No OAuth grants to third parties. No monthly fees.
Step-by-Step Installation (5 Minutes)
This guide is written for non-technical users. If you can copy-paste, you can do this.
Step 1: Create a New Apps Script Project
- Open your browser and go to script.google.com
- Make sure you are logged into the Google account whose Gmail you want to clean
- Click New project (blue button, top left)
- Click “Untitled project” at the top and rename it to Gmail Auto-Cleanup
You will see a code editor with a file called Code.gs containing a default myFunction(). Delete everything in this file.
Step 2: Paste the Script
- Go to the Gmail Auto-Cleanup repository on GitHub
- Open the
Code.gsfile - Click the Copy raw contents button (the clipboard icon)
- Go back to your Apps Script editor
- Paste the entire code into
Code.gs(Ctrl+V / Cmd+V) - Press Ctrl+S (or Cmd+S) to save
That is the entire installation. The script is now in your Google account.
Step 3: Configure Basic Settings
At the top of the code, you will see the CONFIG object:
const CONFIG = {
TRIGGER_HOUR: 6, // When to run (24h format, 6 = 6:00 AM)
ACTION: 'trash', // 'trash' or 'archive'
MAX_THREADS_PER_RULE: 100, // Limit per rule (prevents timeout)
SEND_EMAIL_REPORT: true, // HTML report after cleanup
REPORT_EMAIL: '', // Leave empty = your Gmail address
INCLUDE_SAMPLES: true, // Show sample subjects in report
SAMPLES_PER_RULE: 3, // Number of samples per rule
SEND_TELEGRAM: false, // Enable after bot setup
TELEGRAM_BOT_TOKEN: '', // From @BotFather
TELEGRAM_CHAT_ID: '', // Your chat ID
LOG_TO_SHEET: true, // Log every cleanup to a spreadsheet
SHEET_NAME: 'Gmail Cleanup Log'
};
For now, the defaults are fine. The only thing you might want to change is TRIGGER_HOUR — set it to whatever hour you want the daily cleanup to run (in 24-hour format, so 6 = 6 AM, 22 = 10 PM).
Step 4: Run a Dry Run (Preview Mode)
Before the script deletes anything, run it in preview mode:
- In the Apps Script editor, find the function dropdown at the top (it probably says
cleanupGmail) - Change it to
dryRun - Click the Run button (the play icon)
First run — authorization prompt:
Google will ask you to authorize the script. This is normal — the script needs permission to read your Gmail and send you a report email. Here is what happens:
- A popup appears: “Authorization required” — click Review permissions
- Select your Google account
- You will see a warning: “This app isn’t verified” — this is expected for personal scripts that are not published to Google Workspace Marketplace. Click Advanced at the bottom left
- Click “Go to Gmail Auto-Cleanup (unsafe)”
- Review the permissions and click Allow
The “unverified app” warning looks scary, but it is completely normal. Every personal Apps Script shows this warning. The script is not an “app” — it is code running in your own account, written by you (or in this case, pasted by you). Google just warns about any script that accesses sensitive scopes like Gmail.
After authorization, the dry run will execute. Within a minute, you will receive an HTML email report showing:
- How many email threads matched each rule
- Sample subject lines from each category
- A summary of what would be deleted
Nothing is actually deleted during a dry run. Review the report. If a rule is catching emails you want to keep, adjust the query or increase the older_than value.
Step 5: Run the Real Cleanup
Once you are happy with the dry run results:
- Change the function dropdown to
cleanupGmail - Click Run
The matched emails will be moved to Trash. You will get another HTML report confirming what was cleaned.
How to Configure Rules (3 Options)
The script comes with universal rules that are safe for any Gmail account (Google notifications, Promotions, Social, LinkedIn). But the real power is in customization.
Option A: Let Claude AI Scan Your Inbox (Recommended)
This is the fastest way to get a personalized rule set.
- Open Claude
- If you have Gmail connected to Claude via MCP, it can scan your inbox directly. If not, you can describe your inbox or paste a list of your most frequent senders.
- Copy the prompt from the
claude-scan-prompt.mdfile in the repository - Paste it into Claude
- Claude will analyze your email patterns and generate a complete
RULESarray - Copy the output and paste it into the
YOUR CUSTOM RULESsection ofCode.gs
What Claude does:
- Identifies automated notifications you never open
- Finds newsletters piling up unread
- Detects platform noise from tools you may have stopped using
- Suggests safe retention periods (e.g., 3 days for OTPs, 7 days for social, 60 days for receipts)
- Flags any rules that need manual review (senders that send both important and noise emails)
- Lists senders you should fully unsubscribe from
This approach is better than guessing because Claude works from your actual email data, not generic assumptions.
Option B: Use a Starter Pack
The script includes pre-built rule packs for common roles:
Universal (active by default):
– Google Calendar, Drive, Docs notifications
– Old Promotions (30+ days)
– Old Social tab (14+ days)
– LinkedIn, Facebook, X/Twitter alerts
Founder / CEO pack:
– HubSpot, Notion, Slack, Zoom, Calendly, Stripe, Intercom
– Weekly digests, monthly newsletters
– Quora, Medium notifications
Developer pack:
– GitHub, GitLab, Travis CI, CircleCI
– Vercel, Netlify, Sentry
– AWS, DigitalOcean, Stack Overflow, npm
Marketer pack:
– Mailchimp, Semrush, Ahrefs, Hootsuite
– Buffer, Canva
– Google Analytics, Google Ads, Meta Ads
To enable a starter pack, open Code.gs, find the pack you want, and remove the // comment marks from each rule. Save and run a dry run to verify.
Option C: Write Your Own Rules
Each rule is one line of JavaScript using Gmail search syntax:
{ query: 'from:noreply@example.com older_than:7d', label: 'Example Notifications' },
Common Gmail search operators you can use:
| Operator | Example | What it does |
|---|---|---|
from: | from:noreply@github.com | Match sender |
subject: | subject:"weekly digest" | Match subject line |
older_than: | older_than:7d | Older than N days/months/years |
label: | label:Promotions | In a specific Gmail label/tab |
is:unread | is:unread older_than:30d | Unread messages |
has:attachment | has:attachment larger:10M | Has attachments |
larger: | larger:5M | Larger than 5MB |
You can combine operators for precision:
from:noreply@github.com subject:"CI" older_than:7d
This would only clean GitHub CI notification emails older than 7 days, leaving other GitHub emails untouched.
Retention guidelines:
- Verification codes, OTPs: 1 day
- Calendar notifications: 3 days
- Chat/messaging notifications: 3 days
- Social media notifications: 7 days
- Platform notifications (GitHub, Jira, Slack): 7-14 days
- Newsletters you read: 14 days
- Newsletters you never open: 3 days
- Promotions: 14-30 days
- Transaction receipts: 60 days
Setting Up Telegram Notifications (Optional)
If you want a daily Telegram ping when cleanup runs (in addition to the email report), here is how to set it up:
Step 1: Create a Telegram Bot
- Open Telegram and search for @BotFather
- Send
/newbot - Choose a name for your bot (e.g., “Gmail Cleanup Bot”)
- Choose a username (e.g.,
my_gmail_cleanup_bot) - BotFather will reply with a bot token — a long string like
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11. Copy it.
Step 2: Get Your Chat ID
- Send any message to your new bot (just say “hello”)
- Open this URL in your browser (replace
<TOKEN>with your actual bot token):
https://api.telegram.org/bot<TOKEN>/getUpdates - In the JSON response, find the
"chat"object and copy the"id"number — this is your chat ID
Step 3: Configure the Script
In Code.gs, update the CONFIG:
SEND_TELEGRAM: true,
TELEGRAM_BOT_TOKEN: 'your-bot-token-here',
TELEGRAM_CHAT_ID: 'your-chat-id-here',
Step 4: Test
- In the function dropdown, select
testTelegram - Click Run
- You should receive a test message in Telegram
Setting Up the Daily Trigger
The whole point is automation. Here is how to set the script to run every day without you touching it:
- In the Apps Script editor, change the function dropdown to
setupDailyTrigger - Click Run
Done. The script will now run every day at the hour you set in CONFIG.TRIGGER_HOUR (default: 6 AM).
To stop the daily trigger, run removeTrigger the same way.
You can verify the trigger exists by going to the Triggers page in Apps Script (clock icon in the left sidebar). You will see an entry for cleanupGmail with a daily time-driven trigger.
What Happens After Setup
Every morning at your configured hour:
- The script runs through all your rules
- For each rule, it finds matching Gmail threads
- Matching emails are moved to Trash (or archived, if you set
ACTION: 'archive') - You receive an HTML email report with a summary
- If Telegram is configured, you get a notification there too
- Everything is logged to a Google Sheet called “Gmail Cleanup Log” in your Drive
Over time, this adds up. In my case, the script cleans 50-80 emails per day — about 1,500-2,400 per month that I never have to see or think about.
FAQ
Is it safe?
Yes. The script runs inside your Google account on Google’s own Apps Script infrastructure. Your emails are never sent to any external server. You can read every line of code — it is about 200 lines of straightforward JavaScript. Emails go to Trash (not permanently deleted), and you have 30 days to recover anything.
What about the “This app isn’t verified” warning?
Every personal Google Apps Script shows this warning when it accesses sensitive scopes like Gmail. It does not mean the script is unsafe — it means the script has not been submitted to Google for review (which is only required for published apps, not personal scripts). Click “Advanced” then “Go to Gmail Auto-Cleanup (unsafe)” to proceed.
Can I recover deleted emails?
Yes. The script moves emails to Trash by default. Gmail keeps trashed emails for 30 days before permanently deleting them. If you accidentally clean something important, go to Trash and move it back. You can also set ACTION: 'archive' in the config to archive instead of trash — archived emails are never deleted, just removed from your inbox.
Will it delete important emails?
Only if your rules match them. That is why you should always run dryRun() first and review the report. Use specific from: addresses and appropriate older_than: values. The starter rules are conservative by design — they only target automated notifications and promotions that are safe to clean.
Does it work with Google Workspace (business Gmail)?
Yes. Apps Script works with both personal Gmail (@gmail.com) and Google Workspace accounts. If your company admin has restricted Apps Script, you may need to ask them to enable it.
How much storage does it free up?
Depends on your inbox. Email text is small, but attachments add up. If you have years of accumulated notifications with embedded images and attachments, you could free up several GB. Run the script for a month and check your Google Storage dashboard to see the impact.
Can I run it on multiple Gmail accounts?
Yes. Create a separate Apps Script project in each Google account and configure rules independently. If you manage multiple accounts frequently, you can also deploy using clasp (Google’s command-line tool for Apps Script) for version-controlled deployments.
What if the script hits a timeout?
Google Apps Script has a 6-minute execution limit. The MAX_THREADS_PER_RULE setting (default: 100) prevents this. If you have a massive backlog of old emails, the script will process 100 threads per rule per run. Over a few days of daily runs, it will catch up. You can temporarily increase this limit if needed, but 100 is safe for most accounts.
Get Started
The script is free, open-source (MIT license), and takes 5 minutes to set up.
GitHub repository: github.com/Yaroslavle/gmail-auto-cleanup
Clone it, fork it, modify it — it is yours.
If you have questions or suggestions, open an issue on GitHub or reach out on LinkedIn.
Built by Yaroslav Lehenchuk, Founder of O-CMO — Fractional CMO agency for B2B tech companies.
