How to Find and Merge Duplicate Profiles in Klaviyo (Complete Cleanup Guide)
If you run a Klaviyo account of any real size — say, more than 10,000 profiles — you almost certainly have a duplicate problem, and Klaviyo isn't going to tell you about it. It'll just quietly count each of those duplicates toward your active profile total and charge you for them month after month.
The frustrating thing is that most of these duplicates are the same person. Jane Smith signed up on your homepage popup with jane@gmail.com, checked out on Shopify as Jane.Smith@gmail.com, and joined SMS as +1 (415) 555 0117. Klaviyo sees three profiles. You see three lines on your invoice.
This guide walks through how duplicates get in, why Klaviyo's built-in matching misses them, and the fuzzy-matching workflow ecommerce and marketing ops teams use to cut duplicate profiles by 8-15% in an afternoon.
How Klaviyo Handles Duplicates (And Where It Falls Short)
Klaviyo uses a very simple rule for identifying the same person: exact match on primary identifier. That means an exact match on email address, or, for SMS-only profiles, an exact match on the E.164-formatted phone number. If those exact identifiers match, Klaviyo merges the two profiles automatically.
Everything else creates a duplicate. Common cases where it fails:
- Different casing.
Jane@GMAIL.comandjane@gmail.comare technically the same address but Klaviyo has treated them as separate profiles in the past, especially for older data imported before its normalization improved. - Gmail dots and plus-addressing.
j.smith@gmail.com,jsmith@gmail.com, andjsmith+shop@gmail.comall deliver to the same inbox, but Klaviyo treats them as three distinct profiles. - Personal vs work email. The same customer signs up on personal email, then checks out on work email a year later. Two profiles, same person.
- Phone formatting variance.
4155550117,+14155550117, and(415) 555-0117may not all get normalized during a bulk import, particularly from a CSV or a legacy tool. - SMS vs email profiles. A subscriber joined SMS via a keyword campaign and separately signed up for email through a Shopify popup. Same person, no shared identifier, two profiles.
None of these are exotic edge cases. On the average Klaviyo account we've looked at, 8-12% of profiles are duplicates of someone else already in the list. On accounts that have run for 3+ years with multiple form providers, the duplicate rate can hit 20%.
Why This Matters (Beyond the Bill)
The obvious cost is money. Klaviyo pricing is tied to active profile count, so every duplicate is a line item on your bill you don't need. On a 100,000-profile plan, a 10% duplicate rate is 10,000 profiles — enough to push you a full pricing tier higher than you should be.
The less obvious costs are worse:
- Deliverability drag. Duplicates mean the same person gets the same email twice. They mark one as spam or unsubscribe once, but their other profile keeps receiving. Your complaint rate on the "engaged" segment gets inflated by people who already opted out of the same content under another profile.
- Broken personalization. Your abandoned cart flow fires on the profile that abandoned. Your post-purchase flow fires on the profile that checked out. Those are different profiles, so the customer gets a cart abandonment email after they've already bought — classic ecommerce email failure.
- Skewed LTV and RFM analysis. Every duplicate splits one customer's history across two profiles. Your "one-time buyer" segment is inflated. Your "VIP" segment is under-counted. Any RFM segmentation built on top of dirty profile data is going to mislead the merchandising team.
- Attribution errors. Klaviyo attributes revenue to the profile that clicked the campaign. If the buyer's other profile is the one that opened, but they bought on a different device with the other email, Klaviyo may not credit the send at all.
Quick estimate: Multiply your active profile count by 0.10. That's roughly the number of duplicate profiles you're carrying today. Multiply that by your per-profile cost. That's the monthly overpay. On a mid-sized ecom brand, this is usually $75-$250 per month — and 10x that in indirect deliverability and reporting cost.
Step 1: Export Your Klaviyo Profiles
You can't run fuzzy matching inside Klaviyo. The cleanup happens outside — typically in a spreadsheet or a dedup tool — then you write the merges back to Klaviyo via its API or CSV import.
To export:
- In Klaviyo, go to Audience → Lists & Segments.
- Create a segment: "Person can receive email marketing OR person can receive SMS marketing" (this includes everyone you're paying for).
- Once the segment builds, click Manage segment → Export segment to CSV.
- Choose the columns you'll need for matching:
Klaviyo ID,Email,Phone Number,First Name,Last Name,Consent Status,Created, and any custom identifiers you use (Shopify customer ID, etc.).
Klaviyo sends the export to your email as a CSV. Large accounts can take 15-30 minutes to build the file; be patient.
Step 2: Normalize Before You Match
Before you upload the file to a fuzzy matcher, do 10 minutes of cleanup in Excel or Google Sheets. This alone will find the easiest 30% of duplicates for free.
- Lowercase all emails.
=LOWER(A2). - Strip Gmail dots and plus tags into a "canonical email" helper column. Only apply this if the domain is gmail.com or googlemail.com. Example formula:
=IF(REGEXMATCH(A2, "gmail\.com|googlemail\.com"), REGEXREPLACE(REGEXREPLACE(SPLIT(A2, "@")[0], "\+.*", ""), "\.", "") & "@gmail.com", A2). - Normalize phone numbers to E.164. Strip everything except digits, prefix a country code if missing.
- Trim whitespace on first and last name.
After normalization, use Remove Duplicates on the canonical email column alone. On a typical export this collapses 2-4% of profiles right there — the pure exact duplicates that only differed in case or formatting.
Step 3: Fuzzy Match on Email + Phone + Name
The remaining duplicates are the ones where nothing exactly matches. Same person, different email; same person, phone on one profile but not the other; same person, email typo on one signup. These need fuzzy matching.
Upload the normalized CSV to a fuzzy matching tool. The configuration that works well for Klaviyo data:
| Column | Weight | Notes |
|---|---|---|
| Email (canonical) | 35% | Primary column. Catches typos and near-matches on personal emails. |
| Phone (E.164) | 30% | Strongest signal when present, but many email-only profiles will be blank. |
| Full name (first + last) | 25% | Handles the case where a customer used entirely different emails. |
| Created date | 10% | Small tiebreaker — profiles created weeks apart are more likely dupes than profiles created years apart with the same name. |
Set the mode to contact or generic depending on your tool. Run the match.
You'll get a ranked list of profile pairs with similarity scores. In practice, the distribution looks something like this on a typical ecommerce list:
- Score 95+: Nearly certain duplicates. Same phone or same normalized email, no ambiguity. Auto-merge.
- Score 85-95: Very likely duplicates. Different email, same name, same phone or overlapping activity. Review quickly — usually all merges.
- Score 70-85: Judgment call. Common family members ("John Smith" and "Jane Smith" at the same address) live here. Review carefully.
- Score below 70: Different people. Ignore.
Step 4: Decide the Winning Profile
For every duplicate pair, you need to pick which profile "wins" — the one that stays. The other's data merges in and the profile itself is suppressed or deleted.
Good winner-selection rules:
- Prefer the profile with SMS consent. SMS is harder to re-collect than email.
- Prefer the profile with the more recent engagement (last opened, last clicked, last purchased).
- Prefer the profile with a Shopify or ecommerce identifier attached — that's the one linked to purchase history.
- Break ties by earliest created date so long-standing subscribers keep their tenure.
Build these rules as formulas in the merged output so the choice is deterministic instead of manual.
Step 5: Push the Merges Back to Klaviyo
Klaviyo has a Merge Profiles API endpoint that takes a "destination" profile ID and a list of "source" profile IDs to fold in. The API keeps all events, list memberships, and metric aggregations from the source profiles.
For small cleanups (under a few hundred merges), you can do this manually in the Klaviyo UI: open a profile, click Merge profile, paste the other profile's identifier. Tedious but safe.
For larger cleanups, script it. A short Python script that reads your merge decisions from CSV and hits the Klaviyo Merge Profiles endpoint one row at a time will run a thousand merges in a few minutes. Rate limit yourself to Klaviyo's guidance (currently around 350 requests/minute) and log every merge for audit purposes.
Safety tip: Before running any merge script, export the raw profile data first and store it somewhere offline. Klaviyo's merge is reversible in the UI for a limited time, but a full backup means you can always reconstruct a profile you shouldn't have merged.
Common Mistakes to Avoid
Matching on email alone. Half the duplicates you have are the same person with different emails. If you only match on email you'll miss them all and find yourself running another cleanup in six months.
Weighting name too high. Names are noisy. "John Smith" matches "Jon Smith" matches "John Smyth" — those may all be different people. Keep name as a helper column at 20-30%, not the primary.
Merging suppressed profiles into engaged ones. If someone unsubscribed under one email and re-subscribed under another, respect the unsubscribe. Filter out suppressed profiles as merge targets, or explicitly cross-check consent status before merging.
Not documenting the merge decisions. If your merchandising team asks why customer counts dropped 10%, you want to be able to show them the merge log. Keep the CSV of source/destination pairs and the merge reason (score, matched columns) as an audit trail.
Assuming this is a one-time task. Duplicates accumulate. New popup forms, Shopify checkout changes, third-party enrichments — they all create new duplicates. Run this cleanup quarterly. On the second run, you'll only find 2-3% new duplicates instead of 10%, and it takes 20 minutes instead of an afternoon.
How Much Does This Actually Save?
Rough numbers from typical ecom brand cleanups:
- 25k profile plan, 10% duplicate rate: ~2,500 profiles removed. Often enough to stay on the same tier a few months longer, saving a $30-$60/month upgrade for at least 6 months.
- 100k profile plan, 12% duplicate rate: ~12,000 profiles removed. Usually enough to drop a full pricing tier — direct savings of $150-$400/month, ongoing.
- 500k+ profile plan, 8% duplicate rate: 40,000+ profiles removed. Direct savings in the $600-$1,500/month range, plus material deliverability improvement as the send volume drops and complaint rate normalizes.
Even if the direct dollar savings weren't there, the deliverability and reporting benefits alone justify the work. Duplicates make every downstream analysis less trustworthy.
Wrapping Up
Klaviyo is a great platform, but its duplicate detection is designed to be conservative — it only merges when it's absolutely sure. That leaves the harder cases (Gmail dots, personal-vs-work email, SMS-only vs email-only, phone formatting) sitting in your list, quietly padding your bill and dragging your engagement metrics.
Fuzzy matching on email plus phone plus name catches the profiles Klaviyo can't. It's not a one-click fix — you export, normalize, match, decide winners, push merges — but the whole workflow takes a few hours and pays for itself in the first month of the reduced profile count.
If you haven't looked at your Klaviyo duplicate rate, it's the highest-ROI list hygiene project you can do today. Export the list, run a fuzzy match, and see what shows up.
Related Reading
- Find and Remove Duplicate Contacts in Mailchimp
- Find and Merge Duplicate Contacts in ActiveCampaign
- Clean an Email List Before Sending a Campaign
Ready to see how many duplicate profiles are hiding in your Klaviyo list? Export your profiles, upload the CSV, and match on email plus phone plus name. Free for 500 rows, no signup.
Try DedupFuzzy Free