Lab · Part 2 of 2 · System design · Google Apps Script + Gmail API · Nov 2026

Untangling 227,002 emails

With a brief in hand (my inbox is for people, opportunities and records) I designed and built a nine-folder system that sorts every hour, learns from one label and never deletes without a 30-day window. The inbox went from 227,002 conversations to 10,232 in six days.

Hundreds of pale teal threads tangle on the left and unravel into nine lanes: Jobs, People, The information, Newsletters, Events, Courses, Saved, Review and Unwanted. One deep teal thread runs to Jobs.

The 30-second version

8 min read

Role

Designer and builder

Partner

Claude Code, for data pulls and code

Built with

Google Apps Script, Gmail API

Timeline

3–8 Nov 2026

I designed for trust before speed: every destructive step is reversible, anything that could lose a receipt or a recruiter runs on fixed rules instead of guesses, and the whole system is taught with one label from my phone. I chose precision over recall and accepted the cost: 29% of new mail still lands in a Review pile I teach down.

−95%

conversations in the inbox, 227,002 → 10,232

0

emails deleted without a 30-day window

71%

of new mail placed automatically in week one; 29% to Review

The brief

Raise signal share from 1% without risking the 1%

The research in Part 1 showed that only 1 in 100 emails needed me, and that the 1% mattered more than everything else combined: interview invites, replies from people, receipts. That made the design problem lopsided. A system that clears 99% of the noise but buries one recruiter email has failed.

My inbox is for people, opportunities and records. Everything else has to earn its place.

The design brief, 3 Nov 2026

Constraint

Why it shaped the design

227,002 conversations to start

A one-by-one approach would take weeks; everything had to batch

Apps Script stops at 6 minutes a run

Work had to be resumable, logged and safe to stop halfway

Mid–job search

A missed recruiter email had a real cost, so Jobs had to win every conflict

I manage mail on my phone

Any teaching gesture had to be one tap, not a settings screen

Principles

Three principles I wrote before any code

  1. Reversible by default. Archive, never delete. Anything headed for Trash waits 30 days in a folder I can see.

  2. The inbox is only for action. Being labelled isn’t enough; if I don’t need to act on it, it leaves the inbox.

  3. Teach with one gesture. Correcting the system has to be faster than ignoring its mistakes.

The system

Nine places, each with one rule

Every email gets exactly one category, and the category decides whether it stays in front of me. A label in Gmail works as a folder, so “sorted” means moved out of the inbox, not just tagged.

Folder

What goes there

Where it lives

★ Jobs

Hiring systems, recruiters, interviews

Inbox, starred, phone alert

People

Real people writing to me

Inbox

Saved

Receipts, orders, flights, appointments

Inbox 30 days, then archived

Review

Bulk mail it can’t place yet

Inbox, until I teach it

The Information

The one publication I pay for

Own folder

Newsletters

Substack, beehiiv and other writers

Folder

Events

Luma, Partiful, hackathons, invites

Folder

Courses

The learning I chose to keep

Folder

Unwanted

Confirmed retail and spam senders

Holding folder, Trash after 30 days

The order is the design

Each step only sees what earlier steps left alone, so what runs first wins. The order encodes my priorities.

  1. My corrections, so I always beat the machine

  2. Jobs, so nothing can bury a recruiter

  3. Saved, so no later rule can trash a receipt

  4. Known senders, from everything it has learned

  5. Unwanted, confirmed senders only

  6. Guesses for the rest, which land in folders, never in Trash

  7. People: what’s left from a real address stays in the inbox

  8. Tidy: anything older than six months is archived

Hard calls

Four trade-offs I made on purpose

Archive over delete

I chose archiving, a 30-day holding folder and then Trash over deleting on sight. It’s slower and keeps more storage, but I was only willing to let a script touch 227,000 emails because every step could be undone.

Rules over AI for anything destructive

Moving mail to Unwanted uses a fixed list of confirmed senders, never a guess, and never anything that looks like a receipt. A model would catch more, but a safety net that can make its own mistakes isn’t a safety net.

Precision over recall, at a cost

Because Unwanted only takes confirmed senders, 289 threads in the first week (29%) landed in Review instead. I accepted a bigger pile to teach over a single wrongly trashed email.

My mental model over the technically correct one

Version 1 labelled everything correctly and left it in the inbox. To me, nothing had happened. I changed it so reading folders leave the inbox, because a working system that feels broken is broken.

Every state

Designing the moments when it goes wrong

A script that runs every hour on 227,000 emails will fail. The design work was deciding what failure looks like from my side.

State

What I see

How I recover

Before any change

A dry run: what each rule would move, and how many

Fix the rule before it touches anything

Wrong folder

An email somewhere it shouldn’t be

Move it and add Learn; three consistent fixes make it permanent

Run out of time

A log that says where it stopped

Run it again; it continues where the mail is still unsorted

Gmail refuses a batch

A count of skipped emails

Retries one by one; the rest of the run continues

Something trashed by mistake

It’s still in Unwanted for 30 days

Move it back or star it; starred mail is never trashed

Every Sunday

A report: inflow per day, share from people, what it learned

Decide what to unsubscribe from

One label teaches it. The first version had seven “Teach” labels. On my phone that looked like homework, so I collapsed them into one: Learn, meaning “remember what I just did.”

What broke

Most of the design happened after version 1 met real mail

What I saw

What I changed

The “people” rule matched nothing: Gmail’s Primary tab is category:personal, not primary

Every rule now runs read-only against the real mailbox before it can change anything

Football promos were kept as receipts because “ticket” counted as a receipt word

Every protected word has to earn its place; “ticket” was removed

The first full run labelled 600 emails, then ran out of time

Sort the last 6 months; archive everything older in bulk, 500 at a time

One email Gmail refused to change stopped the whole run

Refused batches retry one by one, skip what Gmail won’t change, and report the count

About 400 emails a run meant days to catch up

Every label and move uses the batch API; only guessing stays slow

A six-minute run ended with an empty log

Each step logs as it finishes; runs stop themselves at 3½ minutes

Measuring it

Week one, by where the system put it

Once it was sorting every hour, I counted every thread that arrived from 1 to 7 November and where it landed.

Threads received, 1–7 Nov 2026 (1,006 total)
Newsletters
324
Review (unplaced)
289
Courses
180
Unwanted
64
The Information
56
Events
49
Saved (records)
34
Jobs
7
People
3
Stays in front of meRecordsNot yet placedFiled away

Measure, week one

Value

Read

Placed automatically

717 of 1,006 (71%)

Everything except Review

Sent to Unwanted

64 (6%)

Confirmed senders only, so low by design

Left in Review

289 (29%)

The cost of precision, and the main backlog

Jobs and people kept in front of me

10

1.0% of inflow

Outcome

An inbox I can read again

Measure

Before

After

When

Conversations in the inbox

227,002

10,232

2 → 8 Nov

After the first bulk archive alone

227,002

25,712

3 Nov

The Information in the inbox

~300

2

3 → 6 Nov

Job emails found and labelled

—

603

All time

Emails deleted without a 30-day window

—

0

By design

Phone alerts now come only from Jobs. What arrives in the inbox each day is mostly the 1% that needs me, plus the Review pile.

Not solved

Sorting isn’t the same as fewer emails

About 144 threads still arrive every day; the system only decides where they land. At a conservative 3 seconds a glance, that’s 7 minutes a day and about 44 hours a year spent on mail I don’t open.

Next version

Target

Extend the one-click unsubscribe list from Unwanted to any sender opened less than 5% of the time in 90 days

Inflow under 30 a day

Teach Review down with the Sunday report

Review under 10% of inflow

Track signal share weekly

From 1% to 25%

The 3-second glance is an assumption, not a measurement.
Reflection

Reversibility bought the trust to go fast

I could let a script touch 227,000 emails in days, not weeks, only because nothing it did was final. That’s the principle I’m taking into product work: reversibility buys trust, and the user’s mental model beats the technically correct one.

What I’d change: I sorted for days before I counted what arrived. Measuring inflow on day one would have pointed me at the real problem, too much mail, sooner.

Method notes
All counts come from Gmail, read-only, on the dates shown. Counts are conversations (threads) unless stated. Weekly inflow is every thread received 1–7 Nov 2026 by folder, counted exactly by paging through search results. “Placed automatically” is total inflow minus Review. Before-figures for The Information are a Gmail search estimate.
Jacqueline Yeung · Part 2 of 2 · Start with 208,274 unread