How to Clean Your Email List: A Step-by-Step Guide
Your email list is decaying right now. Not metaphorically — literally. People are changing jobs, abandoning accounts, switching providers, and letting domains expire. Industry research consistently shows that email lists degrade by 22–30% per year. A list of 50,000 contacts that was pristine in January has 10,000–15,000 dead addresses by December.
Most marketers know this in theory but don't act on it because the list looks fine. The addresses haven't changed. The CSV still has the same number of rows. But when you hit send, the invisible damage shows up: bounces climb, open rates drop, and Gmail starts quietly moving your campaigns to spam.
This guide walks through the complete process of cleaning an email list — what to remove, what to keep, how to automate it, and how often to do it.
Why List Cleaning Matters
A clean list isn't a nice-to-have. It directly affects whether your emails reach the inbox.
Deliverability
Email providers (Gmail, Outlook, Yahoo) use your bounce rate as a primary signal for sender reputation. Gmail's published threshold is 2% — exceed that consistently and your emails start landing in spam. A dirty list makes hitting 2% almost inevitable. For a deeper breakdown of how bounces affect your reputation, see our bounce rate guide.
Cost
Most ESPs charge based on list size or emails sent. Every dead address on your list is money spent sending emails that will never be read. On a list of 100,000 with 25% dead addresses, you're paying for 25,000 phantom subscribers every month.
Metrics Accuracy
Your open rate, click rate, and conversion rate are all calculated against your total send volume. Dead addresses drag every metric down, making your campaigns look worse than they are and distorting A/B test results.
Blacklisting
Old, abandoned email addresses are sometimes recycled by ISPs as spam traps. These are addresses that look normal but exist solely to catch senders with poor list hygiene. Hitting a spam trap can get your sending domain or IP blacklisted — a recovery process that takes weeks.
What to Remove
Not everything on your list needs to go. Here's a classification framework.
Definitely Remove
- Hard bounces — Permanently undeliverable addresses. Your ESP should automatically suppress these, but verify it's actually happening.
- Undeliverable addresses — Addresses that fail verification (invalid syntax, no MX records, non-existent mailbox).
- Spam trap addresses — If you've hit a known spam trap, remove it immediately and investigate how it got on your list.
- Repeated soft bounces — An address that has soft-bounced across 3+ consecutive campaigns is effectively dead.
Consider Removing
- Unengaged contacts — Subscribers who haven't opened or clicked in 6+ months. Run a re-engagement campaign first (see below), then remove non-responders.
- Role-based addresses —
info@,admin@,support@— shared inboxes that typically have low engagement and higher bounce rates. - Disposable email addresses — Temporary addresses that have already expired or will expire soon. More on this in our disposable emails guide.
Keep
- Active subscribers — Anyone who has opened or clicked within the last 3–6 months.
- Recent signups — New subscribers who haven't had time to engage yet. Give them at least 30–60 days.
- Transactional contacts — Customers who buy from you, even if they don't open marketing emails. Their email is needed for receipts and support.
Step-by-Step Cleaning Process
Step 1: Export Your List
Pull your complete subscriber list from your ESP. Include all available data:
- Email address
- Signup date
- Last open date
- Last click date
- Hard bounce history
- Soft bounce history
- Subscription source
Step 2: Remove Known Bad Addresses
Start with the obvious. Filter out:
- Any address that has hard-bounced
- Any address your ESP has already flagged as invalid
- Any address that has soft-bounced 3+ times consecutively
- Obvious junk entries:
test@test.com,asdf@asdf.com, keyboard mashes
Step 3: Verify Remaining Addresses
Run the cleaned-but-unverified list through an email verification API. This catches addresses that were valid when they signed up but have since become undeliverable.
# Verify in batches of 500
curl -X POST https://mailprobe.dev/api/v1/verify \
-H "Authorization: Bearer mp_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"emails": ["addr1@domain.com", "addr2@domain.com", "..."]}'
Process the results:
undeliverable→ Remove immediatelydeliverable→ Keeprisky→ Keep but flag for monitoringunknown→ Retry once; if still unknown, flag as riskydisposable: true→ Remove
For large lists, batch the verification:
const BATCH_SIZE = 500;
async function verifyAndClean(emails) {
const clean = [];
const removed = [];
for (let i = 0; i < emails.length; i += BATCH_SIZE) {
const batch = emails.slice(i, i + BATCH_SIZE);
const res = await fetch('https://mailprobe.dev/api/v1/verify', {
method: 'POST',
headers: {
'Authorization': 'Bearer mp_live_YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ emails: batch }),
});
const results = await res.json();
for (const result of results) {
if (result.status === 'undeliverable' || result.disposable) {
removed.push(result.email);
} else {
clean.push(result.email);
}
}
}
return { clean, removed };
}
Step 4: Segment by Engagement
After verification, segment your remaining list by engagement:
| Segment | Criteria | Action |
|---|---|---|
| Active | Opened/clicked in last 90 days | Keep — your core audience |
| Warm | Opened/clicked in last 91–180 days | Keep but monitor |
| Cold | No opens/clicks in 180+ days | Run re-engagement campaign |
| Ghost | No opens/clicks ever | Remove after one re-engagement attempt |
Step 5: Run a Re-Engagement Campaign
Before deleting cold contacts, give them one last chance. Send a dedicated re-engagement email:
- Subject line: Direct and honest. "Still interested?" or "Should we stop emailing you?"
- Content: Remind them what they signed up for. Offer a clear reason to stay.
- CTA: One-click to confirm they want to stay on the list.
- Deadline: Give them 7–14 days to respond.
Anyone who doesn't open or click the re-engagement email gets removed. This feels aggressive, but sending to perpetually unengaged contacts only hurts your deliverability.
Step 6: Update Your ESP
Import the cleaned list back into your ESP. Make sure to:
- Remove or suppress all addresses flagged for removal
- Update segments based on the new engagement data
- Keep a record of removed addresses so they don't get re-added through other import processes
How Often to Clean
Real-Time (Continuous)
- Suppress hard bounces immediately (your ESP should do this automatically)
- Verify new signups at the point of collection — catch bad addresses before they enter the list
Monthly
- Review and remove addresses that hard-bounced in the last 30 days
- Check for patterns (e.g., a sudden spike in bounces from one domain)
Quarterly
- Run a full verification of your entire list through an API
- Remove newly undeliverable addresses
- Review engagement metrics and segment accordingly
Bi-Annually
- Run a re-engagement campaign for cold contacts
- Sunset unresponsive addresses
- Audit your signup sources — if one source consistently produces low-quality addresses, fix the intake process
Automating List Hygiene
Manual cleaning works for small lists, but anything above 10,000 contacts needs automation.
Verify at Collection
Integrate email verification into your signup forms. This prevents bad addresses from ever entering your list.
# Real-time verification during signup
curl -X POST https://mailprobe.dev/api/v1/verify \
-H "Authorization: Bearer mp_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"emails": ["new_subscriber@example.com"]}'
If the result is undeliverable or disposable, reject the signup with a friendly error message.
Scheduled Batch Verification
Set up a monthly or quarterly job that exports your list, verifies it in bulk, and removes undeliverable addresses. Most ESPs support CSV import/export, and the MailProbe API handles batches of up to 500 emails per request.
Bounce Webhook Processing
If your ESP supports webhooks for bounce events, process them in real time:
app.post('/webhooks/bounce', (req, res) => {
const { email, type } = req.body;
if (type === 'hard') {
suppressFromAllLists(email);
}
res.sendStatus(200);
});
Common Mistakes
1. Cleaning Only After a Problem
If you're cleaning your list because deliverability already dropped, you're weeks behind. The damage from a dirty list accumulates before symptoms appear. Clean proactively on a schedule, not reactively after Gmail starts filtering you.
2. Keeping Contacts "Just in Case"
That list of 50,000 contacts feels like an asset. Deleting 15,000 of them feels like throwing away money. It's not — those 15,000 dead addresses are actively costing you money and reputation. A list of 35,000 engaged contacts will outperform a list of 50,000 that's 30% dead, every time.
3. Not Verifying Imported Lists
When a colleague hands you a spreadsheet of "leads from the conference," verify every address before importing. Event lists, purchased lists, and scraped lists are the most common source of bounce rate spikes.
4. Ignoring Soft Bounces
Soft bounces seem harmless because they're "temporary." But an address that soft-bounces repeatedly is not temporary — it's dead. Set a threshold (3 consecutive soft bounces) and treat persistent soft bouncers like hard bounces.
5. No Feedback Loop
If you don't know why addresses went bad, you can't prevent it from happening again. Track where your removed addresses originally came from. If 40% of your dead addresses came from one lead source, that source needs fixing.
The Math
Here's why list cleaning pays for itself.
Assume: 50,000 contacts, $50/month ESP fee, 25% dead addresses.
Before cleaning:
- Sending to: 50,000
- Actual reach: 37,500 (deliverable)
- Bounce rate: ~5% (hard bounces hitting dead addresses)
- Result: Gmail spam filtering triggered, real open rate drops 30–40%
After cleaning:
- Sending to: 37,500
- Actual reach: 37,500 (all deliverable)
- Bounce rate: <0.5%
- Result: Full inbox placement, open rates recover
Cost to verify 50,000 emails with MailProbe: $100 (Pro plan at $0.002/check)
That $100 one-time cost saves you from deliverability damage that can take weeks to recover from and costs far more in lost revenue.
Key Takeaways
- Email lists decay 22–30% per year. If you're not cleaning regularly, your list is getting worse every month.
- Remove hard bounces, undeliverable addresses, and persistent soft bounces immediately.
- Verify your full list quarterly using an email verification API.
- Run re-engagement campaigns before deleting cold contacts — give them a chance to stay.
- Verify at the point of collection to stop bad addresses from entering your list in the first place.
- Automate everything you can. Manual cleaning doesn't scale.
MailProbe verifies emails in real time — syntax, DNS, SMTP, disposable detection, and more. Clean your list before the next campaign goes out. Start with 100 free credits.
Ready to verify your email list?
Start verifying emails with a simple API call. 100 free credits included.
Get Started Free →