Free duplicate file removers on Mac and what they miss

A drive is close to full, a free duplicate file finder reports forty gigabytes of duplicates, the duplicates get deleted, and the free space barely moves. That result is common enough on a Mac that it deserves an explanation rather than another list of tools. The short version is that APFS can store the same content twice while occupying it once, and almost every duplicate finder counts those as two files worth deleting.

What a duplicate costs on APFS

This was measured on macOS 26.6.2 with an 800 MB file of random bytes. Free space was read from df before and after each copy.

free before clone: 269935MB
free after cp -c : 269939MB  (delta -3MB)
free after cp    : 269139MB  (delta 799MB)

cp -c makes a clone, which points at the same blocks until one of the copies is written to. It consumed nothing. A plain cp consumed the full 799 MB. Now the important part, the same directory measured by du:

$ du -sh big2
2.3G	big2

Three files of 800 MB each, one of which costs nothing. du reports the clone at full size, and so does every duplicate finder that works from file size and content hashes, because from the file's point of view the bytes really are there. Deleting the clone frees nothing at all.

Clones are not exotic. Duplicating a file in Finder, copying within the same APFS volume in recent macOS versions, and several backup and asset tools all produce them. A machine that has been in use for a few years accumulates them quietly. When a scanner reports a large duplicate figure and the recovered space comes in far below it, this is usually the reason, and no setting in the scanner changes it.

There is a second consequence worth holding onto. Because a clone stops sharing blocks as soon as either side is written to, the space it costs is not fixed. A clone that has been edited becomes a real second copy, gradually, block by block. So the same pair of files can be free today and expensive next month with nothing visible having changed. Reported duplicate totals are a snapshot of an arrangement that moves, which is another reason to treat a large headline number as a starting point for investigation rather than as an amount of recoverable space.

The free tools, and their actual state

Names get recommended long after the projects behind them stop shipping. These were checked against Homebrew and the projects' own release feeds.

Tool Cost Licence Latest release macOS availability
jdupes Free MIT 1.31.1 Homebrew, prebuilt for macOS 26 on Apple silicon
fdupes Free Not stated in the formula 2.4.0 Homebrew
rmlint Free GPL-3.0-or-later 2.10.3 Homebrew, prebuilt for macOS 26 on Apple silicon
dupeGuru Free GPL-3.0 4.3.1, published 2022-07-09 macOS (10.12+) download offered on the project site
Czkawka Free Open source 12.0.1, published 2026-07-29 Prebuilt macOS binaries are arm64 only

Two entries there need reading carefully rather than ranking.

dupeGuru still has an active repository, with commits pushed as recently as 2026-01-06, and it is not archived. What it has not had is a release. The newest tagged version remains 4.3.1 from July 2022, and the download the project site offers is labelled macOS (10.12+). That is not a reason to avoid it. It is a reason to know that the binary predates several macOS releases and every Apple silicon transition detail before spending an afternoon on it.

Czkawka is the opposite case, releasing frequently, with 12.0.1 published in July 2026. Its published macOS binaries carry arm64 in every filename and there is no Intel Mac build in the release. On an Intel Mac that means building from source rather than downloading.

The command line tools are the least glamorous entries and the least likely to surprise. jdupes and rmlint both have prebuilt Homebrew bottles for macOS 26 on Apple silicon, which means installation is a download rather than a compile. They also differ from the graphical tools in a way that matters more than the interface. A command prints a list that can be read, saved, filtered, and diffed before anything happens, whereas a scanner window presents checkboxes and a delete button, and the review happens under time pressure inside a modal.

Whether a graphical review step is worth having at all is the real question behind the free versus paid comparison, and it is answered differently by people who live in the shell than by people who do not. The Compared with other file managers page lays out the same trade off for file management generally. Licence is worth a glance too, and not for legal reasons. A tool under an active licence with recent releases is one where a bug found today has somewhere to go. jdupes carries MIT and rmlint carries GPL-3.0-or-later, both currently packaged. For a tool that deletes files on request, that ongoing maintenance is the feature being chosen, more than any difference in matching algorithm.

A check to run before installing anything

Nothing has to be installed to find out how bad the situation is. Files of different sizes cannot be duplicates, so size is a free first pass, and only the survivors need hashing.

$ find target -type f -exec stat -f "%z %N" {} \; | sort -n

Sizes that appear once are done. For the rest, hash and group:

find target -type f -print0 | xargs -0 shasum -a 256 | sort > /tmp/h.txt
awk '{h=$1; $1=""; sub(/^ +/,""); if (h==p) print "DUP: " prev " <-> " $0; p=h; prev=$0}' /tmp/h.txt

Run against a small test tree this printed exactly the pairs that shared content, including a file created with cp -c. That last detail is the point. The pipeline cannot tell a clone from a real second copy either, because at the level of content they are identical. What the pipeline does give is a list short enough to look at before anything is deleted, which is more than a progress bar and a total.

For anyone whose work already lives in the shell, this is a reason to keep the file list and the prompt in one place rather than alt tabbing between a scanner window and a Terminal window. That single surface is what the Features page describes.

Find out where the space went before deduping at all

Duplicate removal is rarely the largest available win, and it is easy to spend an evening on it while a single folder holds most of the problem. One command sorts the top level of a directory by size:

$ du -d 1 -h ~/work | sort -hr | head -5
 11G	/Users/admin/work
3.2G	/Users/admin/work/tmp
3.2G	/Users/admin/work/scripts
2.9G	/Users/admin/work/backups
1.7G	/Users/admin/work/.git

Descending one level at a time through the largest entry reaches the actual weight in under a minute, and the answer is frequently something a duplicate scanner would never have flagged. Build caches, dependency directories, virtual machine images, old exports, and repository history are single large items rather than repeated ones. None of them are duplicates. All of them are recoverable space, and most are recoverable with far less risk than deleting files a scanner picked out.

Running this first also calibrates the duplicate scan that follows. If the top level shows 200 GB and a scanner then reports 40 GB of duplicates, the figure is worth investigating. If the whole tree is 20 GB and the scanner reports 40 GB of duplicates, something in the count is being double counted, and clones are the first suspect.

Three places a scanner must not walk

The photo library

~/Pictures/Photos Library.photoslibrary is a package, which means Finder shows one item and the disk holds a directory tree full of originals, renders, and a database. A content based scanner sees an original and its render as separate files, finds real byte level duplicates inside, and offers to delete them. The library's database keeps pointing at what is gone. Duplicate photos are handled from inside the Photos app, which has its own duplicates view, and never from a file scanner.

Files that are not actually downloaded

With iCloud Drive optimising storage, a file can exist as a name with no contents on this machine. The ls manual documents a -% option to mark them, and describes its behaviour as distinguishing dataless files and directories and not materialising dataless directories. The wording is the warning: normal traversal materialises them. Pointing a duplicate scanner at an iCloud folder can trigger a long, silent download of everything it walks, and then hash what it just pulled down.

Bundles and dependency trees

Application bundles and node_modules folders are full of identical small files by design. A scanner will find thousands of them and every deletion is a broken install. These directories belong on an exclusion list before the first scan, not after the first mistake.

Deciding which copy is the original

Once a real pair is confirmed, something has to choose which one survives. Modification date is the instinctive answer and it is unreliable, because copying destroys it:

$ touch -t 202001010000 orig.bin
$ cp orig.bin plain.bin ; cp -p orig.bin preserved.bin
Jan 1 00:00:00 2020 orig.bin
Sep 5 13:41:19 2026 plain.bin
Jan 1 00:00:00 2020 preserved.bin

A plain cp stamps the copy with the current time. The file that looks newest is frequently the copy, not the original. cp -p and mv preserve the timestamp, so a folder's dates reflect how each file arrived rather than when its contents were written. Path depth, folder naming, and whether anything links to the file are better signals than the date column.

Deletion also does not end at deletion. Files sit in the Trash until it is emptied, and Time Machine local snapshots can hold blocks from before the deletion, which tmutil listlocalsnapshots / will list. Free space measured immediately after a cleanup can understate what was actually recovered.

What a scanner cannot decide

Byte identical is a fact. Redundant is a judgement, and no tool makes it. Three categories come back as duplicates and should mostly stay where they are.

Deliberate copies are the first. A file kept in a project folder and again in an archive folder is doing a job in both places, and the second copy exists precisely so that reorganising the first does not lose it. A scanner sees waste. The person who put it there sees insurance.

Exported renditions are the second. A document exported to PDF twice with no edits in between produces two identical files with different names and dates, and which one downstream systems reference is not visible from the filesystem. Deleting the one that looks redundant breaks whatever pointed at it.

Files inside version controlled trees are the third. Identical files across branches, worktrees, or vendored dependencies are supposed to be identical. Removing one leaves the tree in a state the tooling did not create and cannot explain.

A practical order avoids all three. Work one directory at a time rather than pointing a scanner at a home folder. Start with the largest candidates, because a hundred small pairs are not worth the risk that a single wrong deletion carries. Move confirmed duplicates to a holding folder instead of deleting them, live with that for a week, and delete the holding folder only when nothing has broken. That last step costs a week of disk space and removes the category of mistake that cannot be undone.

What to change first

Before installing a duplicate finder, run the size pass above and see how much of the reported total survives it. Then check whether the large candidates are clones, because those cost nothing and deleting them returns nothing. A file manager that keeps the folder, the shell, and the answer in one window makes that check a few seconds of work instead of a context switch, which is the shape Atriens is built to.

Frequently asked questions

Why does deleting duplicates free far less space than the scanner promised?

Most likely the reported duplicates include APFS clones. A clone shares its blocks with the original and costs nothing extra, but reports its full size to du and to any tool that reads file sizes or hashes contents. Measured on macOS 26.6.2, cloning an 800 MB file consumed no free space while du still counted it at 800 MB.

Is a free duplicate finder good enough, or is a paid one needed?

For finding exact duplicates by content, free tools are not the limitation. jdupes and rmlint are both free, both install from Homebrew with prebuilt binaries for macOS 26 on Apple silicon, and both do exact matching well. Paid tools mainly buy similarity matching for photos and music, and a review interface. Whether that is worth paying for depends on how much of the library is near duplicates rather than exact ones.

Are duplicates inside the Photos library safe to delete?

No. The library is a package containing a database that tracks every file inside it, and a file scanner has no way to know which entries the database depends on. Deleting from inside it can leave the library inconsistent. Photos has its own duplicates view for this, and that is the only safe route.

Does a duplicate scan cause anything to download from iCloud?

It can. Files kept only in iCloud exist locally as names without contents, and walking the folder materialises them. The ls manual documents a -% option for spotting them precisely because ordinary traversal does not leave them alone. Excluding iCloud folders from the scan, or downloading deliberately first, avoids a surprise transfer.

Back to all posts