Decide which file is the audience and which is the reference
Two email files only become useful when you can say what each one is. One file is usually the audience you might contact: this week's form export, a newsletter segment, or a conference list you are allowed to use. The other file is a reference: last month's export, your customer table, an unsubscribe log, a bounce file, or a list of people already in another sequence. Until those roles are written down, every later count is ambiguous. 'New' might mean new to the company, new since last Tuesday, or simply absent from a file that was filtered badly.
Write the roles on the files themselves. 'Audience, webinar form, 24 October 2026' and 'Do not mail: unsubscribes plus current customers' will still make sense next month. 'List A' and 'final final v3' will not. The labels also stop the most expensive mistake in this job, which is swapping the boxes. Subtraction keeps the first file and removes anything that also appears in the second. If the do-not-mail file is in the keep box, the result is a list of people you meant to exclude.
Keep the source exports untouched. Comparison reads them and writes a new result. You will need the originals when a row looks wrong, when someone asks why a person was left out, and when next month's file has to be compared with this month's. A working copy can be lowercased, sorted, or trimmed. The source should stay as the platform exported it, including names, dates, and the column that says how the address was collected.
Pick the operation that matches the question
People say 'compare these lists' and mean three different jobs. The first job is a map: for every address, say whether it is only in the audience, only in the reference, or in both. The second job is a send file: start from the audience and remove anyone who appears on the do-not-mail file. The third job is the overlap: keep only the addresses that appear in both files, such as subscribers who are also customers. Running the wrong one produces a file that looks tidy and answers a question you did not ask.
| Question you actually have | Operation | What you should keep |
|---|---|---|
| Who is new, who disappeared, and who is in both files? | Full comparison | The labelled table, not a single blended list |
| Who can stay in this audience after I remove a do-not-mail file? | Subtraction (audience minus reference) | Addresses that were in the audience and not in the reference |
| Who shows up in both sources? | Overlap | Addresses present on both sides, once each |
The map is the right first pass when you are reconciling two exports and you do not yet know which side matters. Subtraction is the right pass when the decision is already made: these people are candidates, these people must not be mailed this time. The overlap is the right pass when the interesting rows are the ones the files share, and everyone else should stay out of the result. You can run more than one. Many teams look at the map, then produce a subtraction file for the send and an overlap file for the customer-success note. Those are three outputs, stored separately.
If you cannot finish the sentence 'I need the addresses that...', you are not ready to paste. The sentence picks the operation. The files only supply the rows.
Shape each file before you compare
A comparison can pull addresses out of messy text. A display name such as 'Amira Shah <amira@northwind.example>', a cell with two addresses separated by a semicolon, and a paragraph copied from a signature all yield the addresses inside them. A header cell that says Email, a blank line, and the words 'not an address' are ignored, because they are not addresses. That is helpful, and it is also a reason to look at the result rather than trusting the line count of the paste.
Repeated rows inside one file are collapsed before the two files are compared. If sam@northwind.example appears twice in the audience, the unique count is one person. Capitalisation is part of that collapse: Sam@Northwind.example and sam@northwind.example are the same key. When the address is in List A, the spelling from that file is the one shown. This within-file pass is not the same job as comparing two sources. It only stops one export from counting the same mailbox several times. Cleaning repeats inside a single file can still be its own task, done before you import anywhere. Here, the collapse happens so the between-file counts describe people rather than repeated lines.
Still fix obvious damage before you rely on the result. A space in the middle of an address, a missing dot in the domain, or two addresses glued together with no separator can fail to extract or can extract as something you did not mean. Open the source row and correct only what you can see. Guessing a domain ending creates a stranger's address and then, on the next comparison, a stranger's 'match'. Leave the broken row out and keep it in a review file with the original cell beside it.
Put one decision in each file. A do-not-mail file can hold unsubscribes, confirmed hard bounces, current customers, and people you already wrote to this week, as long as every row is there because they should be excluded from this send. Do not mix 'nice to know' notes into that file. A comment, a company name, or a status word is fine around an address, because the address is what gets extracted. A status word that is not an address will not exclude anyone. If the exclusion rule is 'everyone at example.com', you need a domain rule, not a hope that the company name will match.
What the matcher treats as the same address
The tools on this site match the whole address with a case-insensitive key. The local part, the @ sign, and the domain all have to agree after lowercasing. amira@northwind.example matches Amira@Northwind.example. It does not match amira@northwind.co.example, amira@mail.northwind.example, or amira.shah@northwind.example. Those are different strings, and they are often different mailboxes. A comparison that 'almost' matches is a comparison that did not match.
That behaviour is a practical choice, and it is worth knowing where it sits relative to the mail standard. RFC 5321, section 2.4, says the domain is not case sensitive, because domains follow DNS rules. The same section says the local part must be treated as case sensitive, and that SMTP software must preserve the case it was given. It also says that exploiting that case sensitivity gets in the way of interoperability and is discouraged. In ordinary lists, providers treat the whole address as case insensitive. Matching without regard to case is the right default for reconciliation. It is not a claim that every mail server on earth is incapable of distinguishing Smith from smith.
When both files contain the address, the spelling from List A is the one shown. If the audience has Sam@Northwind.example and the reference has sam@northwind.example, the row is one person. You do not need to lowercase either file for the match to work. Lowercasing is useful later, when a sending platform or a spreadsheet treats the two spellings as different strings and would otherwise import both. Do that as an explicit option on the output you are about to import, and leave the source export in its original case.
A match is a string match. It does not confirm that the mailbox exists, that the person still works there, or that two similar addresses belong to one human.
Provider rules the matcher does not apply
Some providers deliver more than one written form to a single inbox. The comparison, the subtraction, and the overlap on this site do not apply those rules. They compare the address as written. If you want two forms treated as one person, you have to put both forms in the files yourself, and only for domains where you have checked the provider's own documentation.
Plus tags stay in the address
A plus tag is the extra word some providers let a person add after a plus sign, as in jules+news@mailbox.example. Google's Gmail Help page 'Send emails from a different address or alias', in the section 'Use Gmail aliases', says messages sent to janedoe+school@gmail.com, janedoe+notes@gmail.com, and similar tags are delivered to janedoe@gmail.com. That page was reviewed for this guide on 24 October 2026. It describes Gmail. It does not describe every domain that happens to contain a plus sign.
Because the matcher keeps the tag, jules+news@mailbox.example and jules@mailbox.example are two rows. A do-not-mail entry for jules@mailbox.example will not remove jules+news@mailbox.example. That is the safe default. Stripping every plus tag on every domain would merge addresses that a given server really does treat as different, and some signup systems use the tag as the only thing that distinguishes them. If you have confirmed the rule for a specific domain, add the tagged form to the do-not-mail file, or remove the tag in a working copy of that domain only, and say so in the file name.
Dots in a Gmail local part are a Gmail rule
Google's Gmail Help page 'Dots don't matter in Gmail addresses', also reviewed on 24 October 2026, says dots in a consumer @gmail.com address do not create a different mailbox. johnsmith@gmail.com and john.smith@gmail.com are the same inbox, and Google will not let someone else register the dotted form. The same page draws a boundary that list work often misses: if the address is Gmail through work, school, or another organisation, on a domain such as yourdomain.com or yourschool.edu, dots do change the address. A custom domain on Google Workspace is not consumer Gmail.
The matcher does not delete dots. r.patel@gmail.com and rpatel@gmail.com stay separate, on purpose. If your do-not-mail file contains one of them and the audience contains the other, subtraction will keep the audience row. When you know both rows are consumer @gmail.com addresses, and you have read Google's rule, you can add the other spelling to the do-not-mail file yourself. Do not apply that dot-stripping rule to a company domain, including a company domain that uses Google, because Google's own note says those dots matter. Do not apply it to Outlook, Yahoo, or a private domain either. Those providers are not covered by that Gmail Help page.
Other lookalikes fail the match for the same reason. A trailing space that survived as part of a broken copy, a full-width @ sign, or a zero-width character copied from a web page can make two rows that look identical to a person compare as different strings. If a pair you know should match is labelled as only in one file, paste the two cells into a plain text editor and look for a character that does not belong. Fix the source. Do not force the match by deleting a character you have not identified.
Read a full comparison when you need the map
Use the Email List Comparison Tool when you need every address labelled. Paste the audience in List A and the reference in List B. The result is one table with two columns: the address, and a status of Only in A, Only in B, or In both. The statistics panel reports unique addresses in each list, then the size of each status. The table is sorted alphabetically by the lowercased address, so you can scan it. Nothing is uploaded. The comparison runs in the browser.
Read the statuses as descriptions of the files, not as a story about why a person moved. Only in A means the address is in the audience and not in the reference. If the reference is last month's export, that row is new relative to that export. It might be a new signup, a spelling you corrected, or a row last month's export silently dropped. Only in B means the address is in the reference and missing from the audience. If you hoped to measure churn, confirm the absence against the platform before you treat it as an unsubscribe. A filtered export, a date range, or a column that stopped being included will manufacture 'lost' people.
In both means the same address key is in each file once the within-file duplicates are collapsed. It is the overlap. It is the right set to inspect when you are asking how much of a new source you already had, or how much of last month is still present. It is a poor set to mail on its own unless the question you wrote down was 'who is in both, and those are the people this message is for'.
Export the table if someone else needs to see the reconciliation. A CSV of address plus status is a record. A screenshot of the counts is not, because nobody can audit a screenshot against a later complaint. Keep the export next to the two source files and a one-line note of what A and B were.
Subtract a suppression file to make a send list
When the decision is already 'mail the audience, except anyone on this other file', use the Email List Difference Checker. It computes audience minus reference. List A is the keep side. List B is the remove side. Any address in A whose key also appears in B is dropped. Addresses that are only in B never appear in the output, which is what you want: a suppression file often contains people who were never in this audience. They do not need to be 'missing' from the result. They were never candidates.
Build List B from rules you can say out loud. Unsubscribes belong there. So do people who asked not to be contacted, complaints, and hard bounces you have already confirmed as permanent. Current customers belong there when the message is only for prospects. People already booked into another sequence this week belong there when the goal is one conversation at a time. A hunch does not belong there. If you cannot point at the event that put a row on the do-not-mail file, leave it off and decide the row in the audience on its own merits.
The statistics panel is the check that the subtraction did what you think. It shows unique A, unique B, how many were removed, and how many remain. Removed plus remaining equals unique A. If it does not, you are looking at a different run. If removed is zero, either the files really share nobody, or you pasted the same side twice, or the spellings differ by a plus tag or a dot the matcher will not ignore. Spot-check one address you know is on both sides and one address you know is only on the audience. Those two checks catch a swapped paste faster than reading the whole file.
Optional lowercasing and A-to-Z sorting change the output, not the match. Leave them off if you need the original spelling for a CRM lookup. Turn lowercasing on if the next system would treat Sam@ and sam@ as two subscribers. Sorting helps a human scan. It is not required for a correct exclusion.
Subtraction does not create permission. A row that survives is an address that was in the audience and absent from the do-not-mail file. You still need a lawful reason to contact that person, and a working way for them to opt out.
Walk through a six-address example
The rows below are invented, on the reserved example domain, so the arithmetic can be checked by hand. They are not a sample from a real campaign and they are not a benchmark. List A is a form export. List B is a do-not-mail file.
| List A, as pasted | List B, as pasted |
|---|---|
| Amira Shah <amira@northwind.example> | sam@northwind.example |
| sam@northwind.example | jules@mailbox.example |
| Sam@Northwind.example | old.customer@harbor.example |
| jules+news@mailbox.example | r.patel@gmail.com |
| info@harbor.example | rpatel@gmail.com |
| r.patel@gmail.com | |
| not-an-address |
Unique A has five addresses. The display name around Amira's address contributes one address, not a name and an address. The two spellings of Sam collapse. 'not-an-address' is dropped. Unique B has five addresses as well: Sam, Jules without a tag, the old customer, and both Patel spellings.
The full comparison then labels eight distinct keys, because two of the ten unique-side rows are the same people counted twice if you add the file sizes. In both: sam@northwind.example and r.patel@gmail.com. Only in A: amira@northwind.example, jules+news@mailbox.example, and info@harbor.example. Only in B: jules@mailbox.example, old.customer@harbor.example, and rpatel@gmail.com. Only in A plus only in B plus in both is 3 + 3 + 2 = 8. Unique A plus unique B is 5 + 5 = 10. The difference of two is the overlap, which you would have double-counted by adding the file sizes.
Subtraction of B from A removes Sam and r.patel@gmail.com, because those exact keys are on both sides. Three addresses remain: Amira, jules+news@mailbox.example, and info@harbor.example. Jules remains because the tag was not stripped. The undotted rpatel@gmail.com is only in B, so it never enters the send file, and it does not match the dotted spelling. The dotted spelling is removed for a simpler reason: that exact address is also on List B. info@ remains because nobody put that role inbox on the do-not-mail file. Remaining plus removed is 3 + 2 = 5, which matches unique A.
The overlap is the two shared keys, Sam and the dotted Patel address. If the next step is a customer note, that two-row file is the start, not the send. You still check it against unsubscribes, and you still decide whether a role address would have belonged there if one had been shared. If the next step is the webinar audience, you do not paste the overlap back into the subtraction result 'so the count looks closer to the export'. That paste puts Sam and Patel back onto a file you just excluded them from.
Read the counts as sets, not as line totals
Line totals describe the paste. Unique totals describe addresses after extraction and case-insensitive collapse. A file can grow from 100 lines to 140 lines because 10 new people signed up and 30 existing rows were repeated by a join. The comparison of unique sets is what tells those stories apart. If you report the line totals as list growth, you will announce growth that is only duplication, and you will miss a real loss that was hidden by repeated rows.
The combined audience of two files is only-in-A plus only-in-B plus in-both. It is not unique A plus unique B. The second sum counts the shared people twice. When you are asked 'how many people do we have across both sources', use the first formula. When you are asked 'how many of the audience are also on the reference', use the in-both figure alone. When you are asked 'how many remain after suppression', use the subtraction remaining figure, which is unique A minus the number removed.
Percentages are optional and easy to distort. The share of the audience that is also on the reference is in-both divided by unique A. The share of the reference that the audience covers is in-both divided by unique B. Those are different numbers. 'We overlap by 20' is not a rate until you say 20 out of which side. This guide does not suggest a healthy overlap rate. The right rate depends on whether the reference was supposed to be the same people, a suppression history, or a different population entirely.
Write the three figures you will report before you open the result: unique audience, number removed or shared, and number remaining. If the panel does not show those figures, you ran a different operation.
Name the output after the decision
A result file with a vague name gets reused for the wrong send. Name it with the audience, the reference, the operation, and the date. send-webinar-minus-unsub-and-customers-2026-10-24.txt cannot be mistaken for overlap-subscribers-and-customers-2026-10-24.txt. The map export can be comparison-webinar-vs-september-export-2026-10-24.csv. Put a text note in the same folder with one paragraph: what A was, what B was, which tool you ran, and the four counts (unique A, unique B, removed or shared, remaining). Future you, and anyone else on the team, can audit the send without rerunning the paste.
Keep the do-not-mail file even when some of its rows were not in this audience. Those rows are there for the next audience. Deleting 'unused' suppression rows because they did not change today's count throws away the exclusion you will need next week. Add new unsubscribes to that file. Do not rebuild it from memory after each campaign.
Store the source exports under their own names, including the platform and the date of the download. When a later comparison says 40 people vanished, the first check is whether the new export used the same filters as the old one. The comparison can show the absence. It cannot tell you whether the platform hid the rows.
Limits of a match
A comparison answers a filing question: which strings are in which file. It does not answer a deliverability question. An address can match perfectly and still be a closed mailbox, a full mailbox, or a role inbox nobody reads. It can be absent from a bounce file and still bounce on the next attempt, because the bounce file only knows about bounces you have already seen. If you need a syntax check, a disposable-domain check, or a mail-routing check, that is a separate pass on the file you decided to keep. Do it after the comparison, on the remaining rows, so you are not spending checks on people you already meant to exclude.
A comparison also does not answer a permission question. The audience file might be a mix of people who asked for the message, people a colleague added, and people left over from a form that did not explain the mail they would receive. Surviving subtraction means 'not on the exclusion file you supplied'. It does not mean 'this person agreed'. If the source column is empty and nobody can say where the address came from, leave the row out of the send. A clean set operation cannot repair an unknown source.
Two addresses can belong to one person without matching, and one address can belong to a shared team. The plus-tag and Gmail-dot cases above are the common mechanical versions. A person can also have a work address and a personal address, with no string relationship at all. Comparison will not merge those. That is correct. Merging them requires a person record in a CRM, with both addresses on it, and a decision about which one this message should use. Doing it by eye, from similar names in a paste, will merge the wrong people.
Absence is not a verdict. Only in B can mean the person unsubscribed, the export was filtered, the address was edited, or the row lived in a different account of the same platform. Only in A can mean a new subscriber or a duplicate you collected under a slightly different spelling. Look at a sample of each status against the source system before you report a growth number or delete anyone from a master file. The comparison is the list of rows that deserve that look. It is not the look itself.
A sequence you can hand to a teammate
- Save both exports with the platform name and the download date. Do not clean these copies.
- Write one sentence: the audience is X, the reference is Y, and the output I need is the map, the subtraction, or the overlap.
- Paste the audience on the keep side and the reference on the other side. For a map, A is the audience and B is the reference.
- Run the operation. Check that removed plus remaining equals unique A, or that the three statuses add up to the combined unique set.
- Spot-check one known shared address, one known audience-only address, and one plus-tagged or dotted address if your files contain them.
- If the output might be mailed, subtract the do-not-mail file as well, even if you started from an overlap.
- Move role inboxes and any row with an unknown source into a review file. Do not leave them in the send file while you think about them.
- Save the output with a name that states the operation and the date, plus a note of the counts.
The spot-check is the part teams skip once the tool feels familiar. It takes a minute and it catches a swapped paste, a file that was truncated by a spreadsheet row limit, and a suppression export that contains names but no email column. Pick the rows before you look at the result, from your own knowledge of the files, so you are not choosing examples that happen to confirm the screen.
Hand the note over with the file. 'Three hundred remaining' is not a brief. 'Webinar form minus the unsubscribe export and the customer export, 24 October 2026, 300 remaining of 360 unique audience rows, 60 removed' is a brief. The next person can rerun it. They can also see that you did not claim those 300 people opted in, only that they were what remained after the files you named.
Mistakes that put the wrong rows back in the file
- Swapping the boxes, so the do-not-mail file becomes the keep side and the audience is used only as a filter.
- Adding the two unique counts and calling that the combined audience, which counts shared people twice.
- Reporting raw line counts as growth after a join duplicated rows inside one export.
- Expecting a plus tag to match the untagged address. The tools on this site do not strip tags.
- Stripping dots from every domain because a Gmail Help page says dots do not matter on consumer @gmail.com addresses. That page says the opposite for organisational domains.
- Deleting suppression rows that were not in today's audience. They are still exclusions for the next audience.
- Pasting the overlap back into the send file to make the count closer to the original export.
- Treating Only in B as confirmed churn without checking whether the export was filtered.
- Leaving info@ and other role inboxes in a personal sequence because subtraction did not remove them.
- Comparing a list you cannot explain the source of, then treating a clean result as permission to send.
Any one of those mistakes produces a file that opens, sorts, and imports. The failure shows up later, as a complaint, a second email to the same person, a merged pair of strangers, or a growth number nobody can reproduce. The fix is the same sequence every time: originals saved, roles labelled, the operation chosen in a sentence, the counts checked against that sentence, and a sample checked by hand.
Comparison is a small piece of list work, and it is the piece that stops two files from being treated as one audience by accident. Do it before you write the message, not after a colleague asks why the same person got both versions. Keep the map when you need to understand the files. Keep the subtraction when you need a send list. Keep the overlap when the shared rows are the point. Leave the provider-specific aliases alone unless you have named the provider rule and the domain it applies to. And leave out any row you cannot justify, even when the string match was perfect.
