Blog Master How to Find D...
profile of the author - Ryan Martinez
Ryan Martinez 04/08/2026 • Last Updated

Master How to Find Duplicates in Google Sheets

Learn how to find duplicates in Google Sheets with 6 powerful methods. Covers conditional formatting, formulas, pivot tables, & scripts to clean your data.

Master How to Find Duplicates in Google Sheets

You open a lead list to prep an outreach campaign, sort by email, and spot the same contact twice. Then you notice the same company appears under two slightly different names. Then a rep points out a lead already got the same follow-up last week. What looked like a quick spreadsheet check has turned into a trust problem.

That is why learning how to find duplicates in google sheets matters. Duplicate rows do not just make a sheet look messy. They distort reports, create avoidable follow-ups, and force teams to waste time checking whether a record is real, repeated, or just entered differently.

The Hidden Cost of Duplicate Data in Your Sheets

Most duplicate problems start small. A CSV gets imported twice. A teammate copies rows from one tab into another. A Google Form submission lands next to older manual entries. On the surface, it feels like housekeeping. In practice, it affects decisions.

A sales team might overcount leads. A project manager might assign the same task twice because a shared list pulled from two tabs contains matching rows. A client list might trigger duplicate messages because nobody caught repeated contacts before a mail merge.

Why duplicate rows cause operational friction

The direct problem is obvious. The hidden problem is confidence.

Once people suspect the sheet contains duplicates, they stop trusting totals, filters, and summaries. They start checking the same data manually, often row by row. That slows down handoffs and creates side conversations like “which row is the correct one?” or “did we already contact this person?”

For teams that work inside Google Workspace all day, this becomes a workflow issue, not just a spreadsheet issue. Shared task lists, CRM exports, and cross-functional trackers all depend on one thing: a record should mean one thing, one time.

Cleanup works better when you treat it as governance

The most effective teams do not treat deduplication as random cleanup. They treat it as part of a broader data quality framework. That mindset changes the goal from “delete messy rows” to “protect reporting, communication, and handoffs.”

Practical rule: Do not pick a method until you answer one question first. Do you want to delete duplicates, review them, or monitor them over time?

Google Sheets gives you a full spectrum of options. Some are fast and destructive. Some are safer and reversible. Some are formula-driven and ideal for live datasets. Some are strong enough for multi-sheet operations where one tab is no longer the whole story.

The mistake is not choosing the wrong formula. The mistake is using a destructive method when the sheet still contains history you may need later.

Visual Methods to Highlight or Remove Duplicates Instantly

A sales coordinator imports a lead list, spots repeated contacts, and wants them gone before the next handoff. A project team working from a shared tracker has the opposite problem. They need to see possible duplicates without deleting history that someone still depends on.

That is the decision to make first. Use a destructive method for throwaway data. Use a non-destructive method for live operational sheets.

A hand selecting the Remove duplicates option from a Google Sheets data menu dropdown.

Use Remove duplicates when the sheet is disposable

The built-in command lives under Data > Data cleanup > Remove duplicates. It is fast, simple, and good for cleanup tabs that exist only to prepare data for the next step.

Use it when the source can be recreated and the duplicate rule is already clear:

  • Fresh imports: CSV exports from another tool
  • Staging tabs: Temporary sheets used before upload or merge
  • Standardized records: Datasets where a duplicate is defined by specific columns and there is little ambiguity

Avoid it in active CRMs, shared task lists, and client logs. In those sheets, deleting a row also deletes context. Notes, status changes, timestamps, and ownership history often matter as much as the duplicate itself.

Use conditional formatting when the sheet still matters

Conditional formatting is the safer review method. It marks suspect records and leaves the original data in place, which is usually the right call when several people edit the same sheet.

A simple single-column rule works for basic lists. For duplicate detection across several columns, the stronger approach is a custom COUNTIFS rule.

Highlight full duplicate rows

To check whether rows in A2:D1000 are duplicates across all four columns:

  1. Select the range A2:D1000.
  2. Go to Format > Conditional formatting.
  3. Under Format cells if, choose Custom formula is.
  4. Enter this formula:

=COUNTIFS($A$2:$A,$A2,$B$2:$B,$B2,$C$2:$C,$C2,$D$2:$D,$D2)>1

  1. Choose a format style, such as a red fill.
  2. Click Done.

This rule highlights rows only when all selected fields match. That is the standard I use for operational data, because a true duplicate in business sheets usually depends on a combination of fields, not one value alone. In a CRM, email plus company may matter more than name alone. In a task tracker, title, assignee, date, and status often define whether two rows are duplicated or just similar.

The trade-offs that matter in real sheets

Visual review sounds slower, but it prevents expensive mistakes.

Method Best for Risk
Remove duplicates One-time cleanup on replaceable data Deletes rows immediately
Conditional formatting Shared sheets and review workflows Can flag the wrong records if the range or formula is set up poorly

The setup details matter. Exact-match rules will treat Acme Inc, ACME INC, and Acme Inc as different values. If your team has inconsistent data entry, clean the inputs first or build that normalization into a later formula-based process.

Conditional formatting also has a maintenance cost. Each rule recalculates as people edit the sheet, so performance can drop in larger trackers with many formatting rules. I see this often in collaborative boards where teams keep adding visual logic instead of simplifying the process.

For teams running work from Sheets, a better pattern is to highlight duplicates, review them in context, and only then remove or merge records through a controlled workflow. That approach fits especially well with a Google Sheets Kanban workflow, where the sheet is not just storage. It is the system people use to decide what happens next.

Tip: If only part of a duplicate row gets highlighted, check Apply to range before changing the formula. Misaligned ranges cause more problems than the rule itself.

Using Formulas for Dynamic Duplicate Detection

A common failure point looks like this. A sales coordinator imports new leads into a shared sheet, someone else sorts by owner, and a third person updates notes on what turns out to be the second copy of the same record. The duplicate is no longer just messy data. It creates rework, conflicting edits, and bad handoffs.

Formula-based detection helps because it separates two decisions that teams often mix together. First, identify possible duplicates. Second, decide what to keep, merge, or remove. That non-destructive approach is usually the right call in live sheets where people are still working.

Infographic

UNIQUE is the safest starting point for live data

Use UNIQUE when you need a clean output without touching the source range:

=UNIQUE(A2:A)

This works well for review tabs, import staging areas, and approval flows. The original data stays intact, which matters if the sheet is tied to an active process and not just an archive.

I use this method first when the business risk of deleting the wrong row is higher than the annoyance of reviewing extra records. That is common in shared task lists, lead trackers, and operations logs, where one "duplicate" may contain the latest comment, status, or assignee change.

Use helper formulas when the team needs a review queue

A unique list is useful, but it does not answer the question teams usually ask next: which rows need attention right now?

For a row-by-row flag in column E, use:

=COUNTIF($A$2:$A,A2)>1

That returns TRUE or FALSE depending on whether the value in column A appears more than once. It is simple, readable, and easy to audit. If your team inherits the sheet later, that matters.

For duplicate rows across several columns, combine the values into a helper key, then count that key. In E2:

=A2&"|"&B2&"|"&C2&"|"&D2

Then in F2:

=COUNTIF($E$2:$E,E2)>1

This pattern is more maintainable than dropping a long all-in-one formula into the sheet. It also makes your matching logic visible. People can see exactly which fields define a duplicate.

Pull duplicates into a separate tab when review needs to be controlled

If multiple people are cleaning data, send them to a dedicated review view instead of asking them to scan the original sheet.

This formula returns only duplicated rows from A2:D:

=ARRAYFORMULA(UNIQUE(FILTER(A2:D, COUNTIFS(A2:A,A2:A,B2:B,B2:B,C2:C,C2:C,D2:D,D2:D)>1)))

That setup works best when duplicates need human judgment. A CRM import may contain two rows for the same company, but one row has the correct owner and the other has the latest activity note. Removing duplicates too early throws away context. A review tab preserves it.

A practical workflow looks like this:

  • Use UNIQUE for a cleaned reference list
  • Use COUNTIF or COUNTIFS to flag suspect rows
  • Use FILTER to create a queue for review
  • Make deletion the final step, not the first one

That sequence is slower than one-click removal. It is also safer.

Normalize first if your team enters data inconsistently

Formulas only catch what you tell them to match. If one person enters Acme Inc, another enters ACME INC, and a third leaves a trailing space, exact-match formulas treat those as different values.

Clean the values before checking for duplicates:

=ARRAYFORMULA(UNIQUE(TRIM(LOWER(A2:A))))

Use this version when the sheet is fed by manual entry, copied exports, or form submissions from different teams. The trade-off is straightforward. Normalization improves detection, but it also changes the display of the data, so keep the original values somewhere if case or formatting matters for reporting.

Count duplicates when you need a fast validation check

Sometimes you do not need a full cleanup pass. You just need to know whether an import created a problem.

Use:

=ROWS(A2:A1000)-ROWS(UNIQUE(A2:A1000))

This gives a quick duplicate count for the range. It is useful before monthly reporting, before syncing data into another system, or after a bulk paste by a teammate who may have introduced repeat entries.

I see this often in sheets used for operations, especially work logs and timesheets. In those cases, a quick duplicate check before payroll review is far safer than deleting rows on sight. The same review-first habit makes sense in Google Sheets time tracking workflows, where duplicate entries can affect billing or payroll.

Formula methods are best when the sheet is still doing real work

Built-in removal tools are fine for one-time cleanup on disposable data. Formula methods are better when the sheet is still active and the team needs evidence before making changes.

Choose formulas if you need to preserve the source data, expose all matching records, or review duplicates with other fields in context. Choose deletion only after the team agrees on the rule for what stays. That is the difference between cleaning a sheet and damaging one.

Advanced Duplicate Analysis Across Multiple Sheets

Duplicate problems get expensive once they spread across tabs and files. A sales lead gets contacted twice. A support record is updated in one sheet but not another. A task appears on both a team board and a manager’s planning tab, so two people assume the other one owns it.

A hand-drawn illustration showing how data from multiple Google Sheets files is compiled into a pivot table.

Use a pivot table to spot patterns before you change anything

Across multiple sheets, the first job is not deletion. It is understanding the pattern.

A pivot table is useful when you need to see which records repeat most often and where the duplication is concentrated. That matters in product catalogs, recurring lead imports, shared task libraries, and CRM exports where the repeated item may point to a broken process rather than a simple data-entry mistake.

Build the pivot from a consolidated range, put the fields that define the duplicate in Rows, and use COUNTA in Values. Start with the narrowest identifier that matters to the business. For a CRM, that may be email address. For operations, it may be order ID. For task tracking, it is often a combination such as project name plus task title.

That distinction matters. If you count duplicates on task title alone, "Kickoff Call" may look like a problem when it is a normal repeat across clients.

Multi-sheet duplicate checks fail when the rule is vague

The hard part is rarely the formula. The hard part is deciding what counts as the same record across systems.

In real client sheets, I usually see one of three cases:

  • The same unique ID appears in multiple tabs. This is the easiest case.
  • No unique ID exists, so the team has to match on a combination of fields.
  • Records are "kind of the same" but not identical because one sheet has cleaner formatting or newer updates.

The wrong move is to start with a destructive cleanup tool before that rule is settled. In a multi-sheet CRM, deleting a row because the email matches can erase a newer owner, note, or pipeline stage. In a collaborative task list, removing one "duplicate" can wipe out a different due date or assignee that the team still needs to review.

For cross-sheet work, review-first methods are usually safer.

A practical cross-sheet pattern using IMPORTRANGE

If you need to check whether a value in the current sheet already exists in another file, IMPORTRANGE plus COUNTIF is the fastest workable pattern:

=COUNTIF(IMPORTRANGE("sheetURL","A:A"), A1)>1

If the source file is not always connected, wrap it in IFERROR:

=IFERROR(COUNTIF(IMPORTRANGE("sheetURL","A:A"), A1)>1, FALSE)

Use it for targeted checks, not full-sheet surveillance. A focused comparison works well when one team owns the master customer list and another team needs to confirm whether a lead, account, or SKU already exists before adding a new row.

A clean workflow looks like this:

  1. Choose the one field that should stay unique across files.
  2. Import only that comparison column.
  3. Flag matches in the working sheet.
  4. Review flagged rows with their surrounding context before merging, deleting, or archiving anything.

That last step is where teams avoid bad cleanup decisions. The duplicate flag identifies risk. It does not decide which row deserves to survive.

Consolidate first when you are comparing many tabs

Within a single file, many-tab setups usually perform better when you stack the relevant data into one helper sheet and run duplicate analysis there.

For example, a company may keep separate tabs for inbound leads, qualified leads, renewals, and partner referrals. Instead of checking each tab against every other tab with nested formulas, pull the key columns into one analysis tab, add a source column so you know where each row came from, and then count duplicates against that combined table.

This gives the team two things standard tutorials often skip. First, it preserves traceability. Second, it shows whether the duplicate is a true error or a handoff between teams.

What breaks at scale

Cross-file formulas are fine for lightweight checks. They become a maintenance problem when people stack IMPORTRANGE, QUERY, lookup formulas, and duplicate logic across large shared sheets.

The symptoms are familiar: slow recalculation, broken permissions, partial imports, and duplicate flags that appear to change after someone edits an unrelated tab. At that point, the method is no longer just technical. It becomes an operations decision.

Use this rule set:

  • One tab, one-time review: use direct formulas or built-in highlighting.
  • Many tabs in one file: consolidate into a helper sheet, then analyze.
  • Many files owned by different teams: import only the key identifier fields and treat the result as a review queue, not an auto-delete system.
  • Records with notes, owners, timestamps, or status history: keep the process non-destructive until someone defines which row is authoritative.

Tip: If performance drops, shrink the imported range before adding duplicate logic. Pull the exact column you need, not the full sheet.

For business sheets, that is usually the right trade-off. Broad formula stacks look clever, but narrow checks tied to a clear duplicate rule are easier to audit, explain, and trust.

Automating Cleanup with Google Apps Script

A weekly duplicate check is manageable. A sheet that collects form submissions every day, feeds a CRM tab, and gets edited by three or four teammates is a different problem. At that point, duplicate handling stops being a spreadsheet trick and becomes a process design choice.

A digital sketch of a robotic hand manipulating mechanical gears over a Google Sheets interface.

Apps Script is useful because it lets you enforce the choice you already made. If the sheet is disposable, a script can remove repeats and keep the file tidy. If the sheet contains notes, owners, timestamps, or status updates, the safer choice is usually non-destructive: flag, separate, archive, and review.

That distinction matters in real business sheets. In a collaborative task list, two rows with the same title might reflect rework, not an error. In a multi-sheet CRM, the same contact can appear twice because sales and support touched the record at different stages. A delete-first script hides that context. An archive-first script preserves it.

A simple script that archives duplicate rows

This pattern keeps the first occurrence in place and moves later duplicates to an Archive sheet for review.

function archiveDuplicateRows() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const source = ss.getSheetByName("Data");
  const archive = ss.getSheetByName("Archive") || ss.insertSheet("Archive");

  const values = source.getDataRange().getValues();
  if (values.length < 2) return;

  const headers = values[0];
  const rows = values.slice(1);

  const seen = new Set();
  const keepRows = [headers];
  const duplicateRows = [headers];

  rows.forEach(row => {
    const key = [row[0], row[1], row[2], row[3]].join("||"); // adjust columns as needed

    if (seen.has(key)) {
      duplicateRows.push(row);
    } else {
      seen.add(key);
      keepRows.push(row);
    }
  });

  source.clearContents();
  source.getRange(1, 1, keepRows.length, keepRows[0].length).setValues(keepRows);

  if (duplicateRows.length > 1) {
    archive.clearContents();
    archive.getRange(1, 1, duplicateRows.length, duplicateRows[0].length).setValues(duplicateRows);
  }
}

The script is simple on purpose. The important decision is the duplicate key. row[0], row[1], row[2], row[3] might make sense for a lead list where email, company, country, and source define uniqueness. It would be a poor fit for a task tracker where duplicate task names are common, and the key is task title plus assignee plus due date.

A few practical adjustments make a big difference:

  • Change the key columns to match the business rule, not just the visible layout.
  • Append to Archive instead of clearing it if you need a running review log.
  • Add a timestamp or reviewer-status column in the archive tab if multiple people will validate duplicates.
  • Test in a copy first, especially if the source sheet includes formulas or protected ranges.

Set a trigger based on risk, not convenience

Apps Script becomes more useful when it runs on a schedule, but the trigger type should match the sheet.

  1. Open Extensions > Apps Script
  2. Paste the script
  3. Save the project
  4. Add a trigger
  5. Choose either On edit or a timed trigger such as nightly

For high-collaboration sheets, I usually prefer a timed trigger over On edit. An edit-based trigger can fire too often, interrupt active work, or archive rows before someone finishes entering the full record. Nightly cleanup is slower, but it is easier to audit and less likely to create confusion.

For import tabs that refresh on schedule, timed automation is usually the right call. For controlled intake sheets with clear data-entry rules, On edit can work if the duplicate key is stable.

For a walkthrough on setting up automation in Google Workspace, this video is a useful visual companion:

Where Apps Script fits best

Use Apps Script when duplicate handling needs to be repeatable and explainable:

  • Scheduled imports from forms, CSV uploads, or connected tools
  • Shared operational sheets where several people touch the same records
  • Review workflows that need an archive, not silent deletion
  • Downstream processes that depend on clean records, such as reports, outreach, or document generation

Google Sheets can now help generate formulas with AI-assisted features, but formula suggestions do not solve the harder part: deciding what should happen to the extra row. Scripts are stronger when you need versioned behavior, archive tabs, triggers, and a process another teammate can inspect later.

If duplicate records feed customer communication, preserve a review step before anything goes out. That is especially important in workflows tied to document sends or mail merge with PDF automation, where one bad duplicate can send the wrong file twice or reach the same contact from two different rows.

Choosing the Right Deduplication Strategy for Your Work

The best method depends less on spreadsheet skill and more on what the sheet represents.

If the sheet is a throwaway import, remove duplicates and move on. If it is a live task board, preserve history. If it is a CRM working list, flag first, review second, remove third.

A practical decision guide

  • Project managers with shared task sheets: Use conditional formatting or helper-column formulas. Shared task lists often contain status notes, assignees, and timing context. Deleting too early creates confusion.
  • Sales teams managing lead lists: Use a hybrid workflow. First identify possible duplicates with formulas. Then review ownership, source, and notes. Only after that should you remove confirmed repeats.
  • Operations or admin teams merging tabs and files: Consolidate first. Then run duplicate checks on the combined set. Cross-sheet noise is harder to reason about when each file uses slightly different structure.
  • Freelancers or solo operators: UNIQUE is often enough. It is quick, non-destructive, and easy to validate.

Pro tips that prevent most cleanup mistakes

  • Normalize text first: TRIM removes trailing spaces. LOWER helps expose capitalization differences.
  • Define the duplicate key: A name alone is rarely enough. Name plus company, or task title plus assignee, is often more useful.
  • Protect the original tab: Keep a raw import tab before any cleanup.
  • Archive instead of erase: If the row contains history, move it rather than deleting it.
  • Think beyond cleanup: A repeat problem is often a process problem. That is where broader data lifecycle management becomes useful, because it forces teams to ask how duplicate-prone data enters, changes, and gets reused.

Final takeaway: The safest workflow is usually non-destructive first, destructive second. Review before deletion is not overkill. It is what keeps records trustworthy.

Knowing how to find duplicates in google sheets is useful. Knowing when not to delete them is what saves teams from avoidable cleanup damage.


Tooling Studio helps teams keep work inside Google Workspace with focused tools for task management, shared workflows, and growing operational processes. If your team is juggling Gmail, Google Tasks, Sheets, and client or project tracking, explore Tooling Studio for a more unified way to manage the work around your data.

Kanban Tasks
Shared Kanban Boards with your Team
Start using Kanban Tasks for free. No credit card required. Just sign up with your Google Account and start managing your tasks in a Kanban Board directly in your Google Workspace.