Your email list is rotting right now. Email industry data consistently shows that B2B lists decay at 22-30% per year - people change jobs, companies get acquired, domains expire, and mailboxes get abandoned. If you haven't cleaned your list in the last six months, somewhere between one in ten and one in four of your subscribers can no longer receive your email at all.
In 2026, the cost of ignoring this is steeper than it has ever been. Gmail and Yahoo now enforce hard bulk-sender requirements, including keeping spam complaint rates below 0.3% (and realistically below 0.1% if you want reliable inbox placement). Microsoft has followed with its own sender requirements for high-volume domains. Mailbox providers measure your bounce rate in near real time, and once you cross roughly 2% hard bounces on a send, your domain reputation starts absorbing damage that can take weeks to repair.
The good news: cleaning a list is not a dark art. It is a repeatable, mechanical process that takes an afternoon - and most of that is waiting for a bulk verification job to finish. Across **50M+ emails processed through BounceZero's verification pipeline**, we see the same pattern again and again: a typical 100,000-address list that hasn't been cleaned in 12+ months loses **18,000-25,000 addresses** during a proper clean. That sounds painful until you realize those addresses were never going to convert - they were only ever going to bounce, complain, or trip spam traps.
This guide walks through the full workflow: exporting from your ESP, deduplicating and normalizing, pre-filtering junk, running bulk verification, interpreting every result category, deciding what to keep, re-importing safely, and setting a re-cleaning cadence so you never have to do a painful emergency clean again.
Step 1: Export Your Full List From Your ESP or CRM
Start by exporting everything - not just your "active" segment. The addresses doing the most damage to your sender reputation are usually the ones you've stopped looking at: old imports, event lists from three years ago, and suppressed-but-not-deleted contacts that a well-meaning teammate might reactivate.
From Mailchimp, Klaviyo, HubSpot, ActiveCampaign, Brevo, or any modern ESP, export as CSV and include at minimum these columns: email address, signup date, signup source, last open date, and last click date. You'll need the engagement columns later for the decision matrix in Step 6 - a *risky* address that clicked last week is a very different animal from a risky address that has been silent for two years.
A few export-specific gotchas worth knowing:
Export suppressions separately. Most ESPs exclude unsubscribed and previously-bounced contacts from a standard export. Export those lists too, but keep them in a separate file - you will never re-mail them, but you need them to make sure they don't sneak back in during re-import.
Watch for multi-list duplication. If you run multiple lists or audiences in one ESP account, the same person often exists on three of them. Export each list, then merge before deduplicating in Step 2.
CRMs lie about email fields. Salesforce and HubSpot exports frequently contain multiple email fields per contact (work, personal, "other"). Decide which field is canonical before you export, or you'll verify addresses you never actually send to.
Check the encoding. Export as UTF-8. Lists that pass through Excel on the way to a verifier often pick up encoding corruption in accented characters - josé@ becoming josé@ - which turns valid addresses into invalid ones before verification even starts.
Once exported, take a baseline snapshot: total row count, and your last three campaigns' bounce rate, open rate, and complaint rate. Email industry data shows the average unclean list produces a 2.1-3.5% bounce rate; you'll want the before/after comparison to prove ROI to whoever signs off on the process. If you need help quantifying that, our [ROI calculator](/roi-calculator) turns your list size and send frequency into a concrete cost-of-bad-data number.
Step 2: Deduplicate and Normalize Formats
Before any verification happens, get the raw file into a canonical state. This step is free, takes minutes, and typically shrinks a multi-source list by 3-8% on its own.
Lowercase everything. The domain part of an email address is case-insensitive by RFC, and in practice virtually every mailbox provider treats the local part as case-insensitive too. [email protected] and [email protected] are the same person - but your CRM counts them as two contacts, and your ESP bills you for both.
Trim whitespace and invisible characters. Copy-pasted addresses routinely carry leading/trailing spaces, tabs, and - the sneaky one - zero-width spaces and non-breaking spaces from web forms. A simple trim plus stripping non-printing characters fixes addresses that would otherwise fail verification for no real reason.
Strip mailto: prefixes and surrounding punctuation. Lists scraped or exported from documents often contain mailto:[email protected] or <[email protected]>.
Deduplicate exactly, then decide on Gmail dots and plus-tags. After lowercasing, remove exact duplicates first. Then make a policy decision on two Gmail-specific quirks: Gmail ignores dots in the local part ([email protected] = [email protected]) and everything after a + ([email protected] delivers to [email protected]). For deliverability purposes these are one mailbox. Most teams collapse dot-variants but *keep* plus-tagged addresses as distinct records, because the tag often encodes meaningful signup-source data - just make sure your frequency capping treats them as one recipient.
Fix the obvious typo domains. Across BounceZero's verification data, a consistent 0.8-1.4% of raw list entries are typos of major providers: gmial.com, gamil.com, hotmial.com, yaho.com, outlok.com. You have two options: correct them to the intended domain (defensible for gmial.com > gmail.com) or discard them. Be careful with correction - some typo domains like gmal.com are registered and actively used as spam trap domains, which is exactly why BounceZero's disposable and spam-trap checks flag them rather than guessing. When in doubt, let verification decide rather than auto-correcting.
Keep a change log of what you merged and corrected. When two records collapse into one, you need a deterministic rule for which engagement history and consent record survives - usually the record with the most recent explicit opt-in wins.
Step 3: Pre-Filter Obviously Invalid and Unwanted Addresses
Verification services charge per address, so there's no reason to pay to verify garbage you can catch with a spreadsheet filter or a 10-line script. This pre-filter pass typically removes another 2-5% of a raw list.
Syntactically broken addresses. Anything missing an @, containing spaces or consecutive dots, with nothing before the @, or with no dot in the domain. You don't need a full RFC 5322 parser - a pragmatic regex catches 99% of real-world breakage. (BounceZero runs full syntax validation as Stage 1 of its pipeline anyway, but invalid-format rows are wasted spend.)
Placeholder and internal junk. Every aged CRM contains [email protected], [email protected], [email protected], [email protected], and your own staff's addresses entered as placeholders during demos. Filter on the obvious local parts: test, none, noemail, fake, asdf, example.
Known-bad TLDs and impossible domains. Addresses ending in .con, .cmo, .local, or @localhost will never deliver.
Your own suppression history. Cross-reference against the unsubscribe and bounce exports from Step 1 and remove any overlap. Re-mailing a previously hard-bounced address is one of the fastest ways to signal to mailbox providers that you don't practice list hygiene - and re-mailing an unsubscriber is a compliance problem under GDPR, PECR, and CAN-SPAM, not just a deliverability one.
A decision, not a filter: role-based addresses. Addresses like info@, sales@, admin@, support@, and billing@ are read by rotating groups of people (or nobody). Email industry data shows role accounts generate 3-5× higher complaint rates than personal addresses, because the person who receives your email is often not the person who subscribed. For B2C newsletters, plan to remove them. For B2B outreach where info@ may be the only contact for a small business, you may keep them - flagged and segmented. Don't remove them manually here; BounceZero's dedicated role-account check will tag them all in Step 4, so you can apply the decision consistently in Step 6.
What remains after Steps 2 and 3 is your verification-ready file: one column of normalized, deduplicated, syntactically plausible addresses, with your engagement metadata preserved in adjacent columns.
Step 4: Run Bulk Verification Through BounceZero
Now the heavy lifting - which, conveniently, isn't yours to do. Upload your cleaned CSV to BounceZero's [bulk email verification](/bulk-email-validation), which accepts up to 1,000,000 addresses per dashboard job and processes a full batch in 5-10 minutes. A 100K list is typically done before your coffee cools.
Each address passes through six distinct verification checks:
1. Mailbox existence. The core check: a live SMTP-level conversation with the recipient's mail server to confirm the specific mailbox actually exists - without ever sending an email. This is what separates real verification from the format-checking that some "validators" sell.
2. Catch-all detection (3-probe). Catch-all domains accept mail for *any* address, valid or not, which makes naive verifiers return false positives. BounceZero uses a three-probe technique - testing the target address against deliberately fabricated addresses on the same domain - to distinguish genuinely configured mailboxes from accept-everything servers, and to classify catch-alls with far more confidence than single-probe tools.
3. Role account detection. Flags info@, admin@, support@ and dozens of other role patterns so you can apply your Step 3 policy consistently.
4. Disposable detection. Identifies temporary-mailbox services (Mailinator, 10-minute-mail clones, and the hundreds of rotating domains they use). Disposable addresses on a marketing list are pure dead weight - the mailbox expired minutes after signup.
5. MX record validation. Confirms the domain actually publishes mail exchanger records and can receive email at all. Roughly 4-6% of addresses on aged lists fail here because the company behind the domain no longer exists.
6. Spam trap detection. The highest-stakes check. Spam traps - recycled abandoned mailboxes and pristine honeypot addresses - never bounce; they silently report you to blocklist operators like Spamhaus. You cannot detect them by sending. BounceZero's trap detection draws on network-level signals and behavioral modeling across our 50M+ verification corpus.
The combined pipeline delivers up to 99.8% accuracy in internal testing on SMTP-verifiable addresses against an industry benchmark of roughly 95% - and that 4.8-point gap matters more than it sounds. On a 100K list, it's the difference between ~200 and ~5,000 misclassified addresses. Pricing is $3 per 1,000 verifications, so the full 100K clean costs $300 - compare that to the revenue impact of a domain reputation penalty, which email industry data puts at a 10-20% inbox placement drop lasting 4-8 weeks.
If your list lives in a product database rather than a CSV, the [verification API](/api-email-validation) does the same six checks in real time with a provider-dependent response time, which is fast enough to verify at the point of signup and prevent the mess instead of cleaning it.
Step 5: Understand Your Results - Valid, Invalid, Risky, Unknown, Catch-All
When the job completes, every address comes back tagged with a status and the underlying check results. Here's what each category actually means, and the distribution we typically see on a 12-month-old 100K list from BounceZero's verification data:
Valid (typically 70-80%). The mailbox exists, the domain has working MX records, and the address is not disposable or a known trap. These are safe to mail. Note that *valid* means *deliverable* - it doesn't promise engagement. A valid address that hasn't opened in 18 months is a deliverability risk of a different kind (more on that in Step 9).
Invalid (typically 12-18%). The mailbox definitively does not exist: the SMTP server rejected it, the domain has no MX records, or the syntax is unfixably broken. These *will* hard bounce. There is no judgment call here - every invalid address you mail is a direct hit to your bounce rate, and mailbox providers start throttling senders around the 2% hard-bounce threshold.
Risky (typically 4-8%). The address is technically deliverable but carries a flag: it's a role account, a disposable address, it shows spam-trap risk signals, or the mail server exhibited suspicious behavior (greylisting patterns, reputation-based acceptance). Risky is not a verdict - it's a category that demands the decision matrix in Step 6.
Catch-All / Accept-All (typically 5-12%, heavily B2B-skewed). The domain accepts mail for every address, so mailbox existence cannot be confirmed with certainty from the outside. On B2B lists this category balloons - many corporate domains and virtually all Google Workspace/Microsoft 365 tenants with catch-all routing fall here. BounceZero's 3-probe catch-all analysis sub-classifies these with a confidence score, which meaningfully shrinks the truly ambiguous set compared to single-probe tools.
Unknown (typically 1-3%). The mail server refused to give a definitive answer - timeouts, aggressive greylisting, or providers that block verification probes entirely. A quality verifier keeps this bucket small; if a tool returns 10%+ unknowns, it's giving up too early. BounceZero's retry logic and provider-specific handling keep unknowns at the low end of the industry range.
Add it up and the arithmetic behind the headline number becomes clear: on a typical 100K list, 18,000-25,000 addresses land in categories you'll remove or quarantine - invalid, disposable, trap-flagged, dead-domain, plus the duplicates and junk from Steps 2-3. That's not a loss. Those addresses had negative value: you were paying your ESP to store them and paying with your reputation to mail them.
Step 6: The Decision Matrix - What to Do With Each Category
The single biggest mistake teams make after verification is treating it as binary - keep the valid, delete the rest. The right move depends on both the category *and* your use case. Here's the matrix we recommend, built from patterns across BounceZero's customer base:
Invalid > Remove. Always. Every use case. No exceptions, no "maybe the server was down." Suppress them in your ESP (don't just delete - suppression prevents accidental re-import) and add them to a permanent do-not-import list.
Valid > Keep and mail. Segment by engagement recency for your first post-clean sends (see Step 7).
Risky - disposable > Remove for everyone. The mailbox is already dead. If disposables exceed ~2% of your signups, add real-time API verification to your forms, because someone is deliberately feeding you throwaways - often bot traffic or incentivized-signup abuse.
Risky - spam-trap flagged > Remove for everyone. The downside (a Spamhaus listing can suppress delivery to a majority of the world's mailboxes) is catastrophically asymmetric against the upside (one subscriber).
Risky - role accounts > Depends on use case. *Newsletter/B2C:* remove; complaint rates run 3-5× higher and the "subscriber" often isn't the reader. *B2B marketing:* segment and mail at reduced frequency with easy one-click unsubscribe prominent. *Transactional email:* keep - if a customer gave you accounts@ for invoices, that's genuinely where invoices should go.
Catch-all > Score-based, by risk tolerance. *Cold outreach / high-volume prospecting:* mail only catch-alls with high confidence scores, and cap them at a small share of each send so a pocket of bad ones can't spike your bounce rate. *Opted-in marketing:* keep catch-alls that have engagement history (an address that opened your email last month demonstrably exists); quarantine never-engaged catch-alls into a low-frequency re-confirmation track. *Transactional:* keep - the user gave you the address for a reason.
Unknown > Quarantine and re-verify. Don't mail them, don't delete them. Re-run them through verification after 72 hours - greylisting and temporary server issues resolve, and in our data 40-60% of unknowns resolve to a definitive status on a second pass. Whatever remains unknown after two passes, treat as invalid for mailing purposes.
One more cross-cutting rule: consent age trumps verification status. In the UK/EU, an address you collected five years ago with no interaction since is a lawful-basis problem even if it's perfectly deliverable. Verification tells you the mailbox exists; it doesn't refresh consent. For very old segments, a re-permission campaign to *valid* addresses only is the defensible path.
Step 7: Re-Import Your Clean List the Right Way
A clean list can be un-cleaned in one careless import. Follow this sequence:
Suppress before you import. In your ESP, add every removed address to the suppression list *first*. This is your safety net: if a stale export gets re-uploaded next quarter, the ESP silently blocks the bad addresses instead of mailing them. Deleting contacts without suppressing them leaves the door open.
Import with status tags, not just the survivors. Bring the verification result in as a custom field (bz_status: valid, bz_status: catch_all_high, bz_verified_date: 2026-07-07). Six months from now, when someone asks "has this segment been verified?", the answer should live on the contact record, not in a CSV on someone's laptop.
Rebuild your segments before your automations fire. Check every active automation, welcome flow, and dynamic segment against the new fields. A win-back automation pointed at a now-suppressed segment will either error or, worse, quietly mail quarantined contacts if your segment logic uses tags you didn't update.
Warm back in - don't blast. Counterintuitively, your first send after a major clean should be your *most* conservative. Mailbox providers notice volume and composition changes. Send first to your most-engaged valid segment (opened or clicked in the last 90 days), then expand to 180-day engagement, then the full valid list over 2-3 sends. Post-clean campaigns typically show immediate improvement - across BounceZero customers we routinely see bounce rates drop from 2-4% to under 0.3%, and open rates rise 10-25% within two or three campaigns as inbox placement recovers.
Measure against your Step 1 baseline. Compare bounce rate, complaint rate, open rate, and - the one finance cares about - effective cost per *deliverable* contact. If you were paying your ESP for 100K contacts and 22K were undeliverable, your real per-contact cost just dropped 22% too. Many ESPs bill by contact count, so a clean frequently pays for itself in the first billing cycle: a 100K>78K reduction on a typical mid-tier ESP plan saves more per month than the $300 the verification cost once.
Finally, archive the full verification results file somewhere durable. It's your audit trail for compliance questions and your baseline for the next clean.
Step 8: How Often Should You Re-Clean? A Cadence Framework
List cleaning is not a one-off project; it's maintenance with a schedule. The right cadence depends on three variables: how fast your list decays, how fast it grows, and how much a deliverability incident would cost you.
The decay math. Email industry data puts overall list decay at 22-30% annually, but it isn't uniform. B2B addresses decay fastest - ~2.5-3% per month - because they die when people change jobs, and average job tenure keeps shrinking. Consumer Gmail/Outlook addresses are more durable but still decay at roughly 1% per month through abandonment. Crucially, Gmail and other providers *recycle* long-dormant addresses into spam traps, which means an address that was merely "unengaged" 18 months ago can be an active trap today. This is why engagement filtering alone is not a substitute for re-verification.
Recommended cadences by profile:
High-volume senders (weekly+ campaigns, 50K+ list): verify quarterly. At 2%+ monthly decay, a quarterly cycle keeps accumulated invalids under the ~2% bounce threshold that triggers provider throttling.
Standard marketers (1-4 sends/month): verify every 6 months, plus event-triggered cleans (see below).
Occasional senders (monthly or less): every 6 months minimum - counterintuitively, infrequent senders need cleaning *more*, not less, because decay accumulates silently between sends and each send is a larger share of your reputation.
B2B/outbound teams: verify every 30-60 days for actively-worked segments. Job-change decay is brutal here.
Event-triggered cleans, regardless of schedule: before any send to a segment untouched for 90+ days; after importing any external or partner list (verify *before* the first send, always); after a bounce rate above 2% on any campaign; before migrating ESPs (arrive at your new provider with a clean file and clean metrics - new-ESP reputation starts from your first sends); and before high-stakes seasonal sends like Black Friday, when blocklist operators are most active and your revenue exposure is highest.
The economics of cadence. At $3 per 1,000, quarterly verification of a 100K list costs $1,200/year. A single Spamhaus listing or Gmail reputation degradation costs most senders more than that in a *week* of suppressed revenue. And you don't need to re-verify everything each cycle: addresses verified valid in the last 90 days with recent engagement can skip a cycle, cutting incremental cost 40-60%. Run your own numbers with the [ROI calculator](/roi-calculator).
The end-state: continuous hygiene. Mature senders eventually stop doing periodic cleans for *new* contacts entirely, by verifying at the point of capture with the [real-time API](/api-email-validation) - at provider-dependent response time, it fits inside a form submission without perceptible delay. Then periodic bulk cleans only need to handle decay of existing contacts, not inbound junk.
Step 9: Ongoing Hygiene - The Habits That Keep Your List Clean
Cleaning fixes the stock; hygiene fixes the flow. These practices prevent the next 20K-address purge:
Verify at signup. The single highest-leverage change. Real-time API verification at the form catches typos, disposables, and fakes before they enter your database. Across BounceZero's verification data, 5-12% of raw form signups fail verification - every one of them a contact you'd otherwise pay to store, mail, and eventually clean. Pair it with inline typo suggestion ("Did you mean gmail.com?") and you *recover* a chunk of those instead of losing them.
Use confirmed (double) opt-in for high-risk sources. You don't need it everywhere, but for paid lead gen, giveaways, and co-registration - the sources with the worst quality - a confirmation click filters bots and fat-fingered addresses at the cost of some list growth. Industry data consistently shows confirmed-opt-in lists produce 2-3× the engagement rates of single-opt-in lists at equal size.
Run a sunset policy. Define non-engagement thresholds and act on them automatically: at 90 days without an open or click, drop send frequency; at 180 days, trigger a re-engagement sequence; if that fails, suppress. Remember that Apple Mail Privacy Protection inflates open rates, so weight clicks and site visits more heavily than opens in 2026. Sunsetting is what protects you from the *engagement* half of deliverability that verification can't see.
Monitor the numbers that predict trouble. Watch hard bounce rate per campaign (investigate anything above 1%, act above 2%), spam complaint rate via Google Postmaster Tools v2 and Microsoft SNDS (stay under 0.1%, hard ceiling 0.3%), and unsubscribe spikes. A slow upward drift in bounces between cleans is normal decay; a sudden jump means a bad import or a segment error.
Guard your import pipeline. Institute one rule with no exceptions: *no external file gets mailed before it's verified*. Purchased lists shouldn't exist in your program at all, but partner lists, event lists, and sales-team uploads are routine - and they're where spam traps enter. A 5,000-row event list costs $15 to verify. Skipping that once is how senders end up writing blocklist delisting appeals.
Never re-mail suppressions. Keep your master suppression list (hard bounces, unsubscribes, complainers, verified-invalids) synchronized across every tool that can send email - ESP, CRM, sales engagement platform, transactional provider. Suppression lists that live in only one system are the root cause of most "how did we mail an unsubscriber?" incidents.
Do these consistently and your quarterly cleans become boring - a few hundred decayed addresses instead of a five-figure purge. Boring is exactly what deliverability should be.
Frequently Asked Questions
How much of my email list will cleaning typically remove?
For a list that hasn't been cleaned in 12+ months, expect to remove 18-25% - on a 100,000-address list, that's 18,000-25,000 addresses across invalid mailboxes, dead domains, disposables, spam-trap risks, duplicates, and role accounts you choose to drop. Recently cleaned lists lose far less: 3-7% per six-month cycle from natural decay. The removal rate is a feature, not a loss - those addresses could only bounce, complain, or damage your sender reputation. Most senders see open rates rise 10-25% within two or three campaigns after a clean, because mailbox providers restore inbox placement once bounce and complaint signals improve.
Is it safe to delete every address marked "risky"?
No - "risky" is a mixed category that needs per-flag decisions, not blanket deletion. Disposable and spam-trap-flagged addresses should always be removed; the downside is severe and the upside is nil. Role accounts (info@, support@) depend on context: remove them from B2C newsletters, but they're often legitimate in B2B and essential in transactional email. That's why BounceZero returns the specific check results - role, disposable, trap signal, server behavior - alongside the status, so you can apply a decision matrix instead of a blunt keep/delete. Deleting all risky addresses on a B2B list can cost you real, reachable contacts.
What should I do with catch-all addresses?
It depends on consent and risk tolerance. Catch-all domains accept mail for any address, so mailbox existence can't be externally confirmed with 100% certainty - but BounceZero's 3-probe catch-all analysis assigns a confidence score that separates likely-real mailboxes from ambiguous ones. For opted-in lists, keep catch-alls with any engagement history (an address that opened last month demonstrably exists) and put never-engaged ones in a low-frequency re-confirmation track. For cold outreach, mail only high-confidence catch-alls and cap their share of each send so a bad pocket can't spike your bounce rate. On B2B lists, catch-alls commonly run 5-12% of the total, so a blanket delete is usually too aggressive.
How long does it take to clean a 100,000-email list?
The verification itself is the fast part: BounceZero's bulk verification handles up to 1,000,000 addresses per dashboard job and processes a full batch in 5-10 minutes, so 100K completes well inside that window. Budget a half day for the full workflow end to end - an hour for export, deduplication, and pre-filtering; minutes for verification; then an hour or two for applying the decision matrix, setting suppressions, re-importing with status tags, and checking your automations. The cost at $3 per 1,000 is $300 for 100K addresses, which most senders recoup in the first ESP billing cycle from the reduced contact count alone.
Can't I just remove subscribers who haven't opened in a year instead of verifying?
Engagement filtering and verification solve different problems, and you need both. Engagement filters can't tell you whether an address exists - a subscriber who opened last month can still hard bounce next week after a job change, and B2B addresses decay at roughly 2.5-3% per month. Worse, providers recycle long-dormant mailboxes into spam traps that never bounce and never open; only verification-side trap detection catches those. Also, Apple Mail Privacy Protection inflates opens, so "opened recently" is a weaker signal than it looks in 2026. Use verification to establish deliverability, then engagement-based sunsetting on top to manage the reputation risk of mailing valid-but-uninterested subscribers.
How is BounceZero different from other list cleaning services?
Three measurable things. Accuracy: 99.8% versus an industry benchmark around 95% - on a 100K list that's roughly 200 misclassifications instead of ~5,000, meaning fewer good contacts wrongly deleted and fewer bad ones wrongly kept. Depth: six distinct checks per address, including 3-probe catch-all detection and spam-trap identification, rather than syntax-plus-MX checking dressed up as verification. Speed and cost: 1,000,000-address dashboard jobs processed in 5-10 minutes, a provider-dependent API response time for real-time use, and flat pricing at $3 per 1,000. You can test it on your own data first - every account includes 100 free verifications per month with no credit card required.
Clean Your List Today - See What Up to 99.8% accuracy in internal testing on SMTP-verifiable addresses Finds
Upload up to 1,000,000 addresses per dashboard job and get results in 5-10 minutes. Start with 100 free verifications every month - no credit card required.
Learn More