<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Rmlint on rHomelab</title><link>https://rhomelab.com/tags/rmlint/</link><description>Recent content in Rmlint on rHomelab</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Mon, 21 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://rhomelab.com/tags/rmlint/index.xml" rel="self" type="application/rss+xml"/><item><title>Finding and Killing Duplicate Files at Scale: A Data Hoarder's Guide to Deduplication</title><link>https://rhomelab.com/data-hoarding/finding-duplicate-files-dedup-tools/</link><pubDate>Mon, 21 Sep 2026 00:00:00 +0000</pubDate><guid>https://rhomelab.com/data-hoarding/finding-duplicate-files-dedup-tools/</guid><description>Duplicate files creep into every large hoard from downloads, cloud sync overlap, and manual copies. Here&amp;#39;s how content-hash dedup tools actually work, which ones are safe to trust, and why hardlinks, reflinks, and plain deletion are not interchangeable.</description><content:encoded><![CDATA[<p>Every hoard past a certain size has duplicates in it, and not the kind you know about. It&rsquo;s not usually the obvious &ldquo;Copy of file (1).jpg&rdquo; pattern. It&rsquo;s the same movie sitting in three different folders because a download client, a manual import, and an old backup all landed a copy in a slightly different place. It&rsquo;s a photo library synced from two phones that both uploaded the same shot. It&rsquo;s a decade of &ldquo;just copy it over to be safe&rdquo; that never got cleaned up. None of this shows up until you actually go looking for it, and by then it can be a meaningful fraction of your total storage.</p>
<p>This isn&rsquo;t about the block-level dedup that Proxmox Backup Server or ZFS snapshots do under the hood (covered from that angle in the <a href="/proxmox/proxmox-backup-server-setup/">PBS backup guide</a>). This is about whole files, sitting in your actual working storage, that are genuinely redundant and safe to consolidate, if you find them correctly and handle the consolidation correctly.</p>
<h2 id="why-same-size-same-name-isnt-good-enough">Why &ldquo;same size, same name&rdquo; isn&rsquo;t good enough</h2>
<p>The naive approach to finding duplicates is matching on filename and size. It&rsquo;s fast, and it will absolutely miss real duplicates while flagging false ones. A renamed file with identical content won&rsquo;t match by name. Two unrelated files that happen to be the same size will match by size and nothing else, and if a tool stops there, you get false positives.</p>
<p>The correct approach, and what every dedup tool worth using actually does, is a content hash. The file&rsquo;s bytes get run through a hash function (commonly xxHash, BLAKE3, or SHA-256, depending on the tool and whether it prioritizes speed or cryptographic certainty), and two files with matching hashes are byte-identical, full stop, regardless of name, location, or timestamp.</p>
<p>Good tools do this in two passes to avoid hashing everything on disk, which would be brutally slow on a large hoard:</p>
<ol>
<li><strong>Group by file size first.</strong> Two files with different sizes can&rsquo;t possibly be duplicates, so this pass is nearly free and eliminates most of the search space instantly.</li>
<li><strong>Hash only the files that share a size with at least one other file.</strong> This is the expensive pass, but it&rsquo;s now running against a small fraction of your total file count.</li>
</ol>
<p>Some tools add a third shortcut: hashing just the first few KB of same-sized files before committing to a full hash, so two large files that happen to share a size but differ near the start get ruled out before a full read. If a tool you&rsquo;re evaluating only does step 1, or claims to detect duplicates from filename patterns, don&rsquo;t trust it with anything you&rsquo;d miss.</p>
<h2 id="the-tools-that-actually-do-this-well">The tools that actually do this well</h2>
<p><strong>rmlint</strong> is a long-standing, fast C implementation that deliberately does not delete anything on its own. Its default behavior is to scan and then emit a shell script (and a JSON report) listing exactly what it would do, that you review and run yourself. That review step is not a limitation, it&rsquo;s the entire safety model, and it&rsquo;s why it&rsquo;s a reasonable first tool to reach for.</p>
<p><strong>fclones</strong> is a newer Rust-based tool with the same safety-first philosophy: it separates &ldquo;find&rdquo; from &ldquo;act,&rdquo; supports multiple actions when you do act (delete, move, hardlink, or reflink, covered below), and handles very large file counts efficiently with a smaller memory footprint than older tools tend to need.</p>
<p><strong>jdupes</strong> is a modernized, actively maintained fork of the older <code>fdupes</code>, with first-class hardlinking support built directly into the tool rather than as a follow-up script.</p>
<p><strong>czkawka</strong> (and its GUI counterpart) goes further than exact-duplicate detection, it can also find similar-but-not-identical images and videos using perceptual hashing, useful if your duplicates problem is &ldquo;the same photo re-exported at a different resolution&rdquo; rather than a byte-identical copy. That&rsquo;s a fundamentally different and fuzzier kind of matching than the others here, worth knowing about but worth treating with more caution since &ldquo;similar&rdquo; is a judgment call a hash comparison isn&rsquo;t.</p>
<p>Any of these will get you a correct, hash-verified list of true duplicates on a modern homelab box in a reasonable amount of time. The tool matters less than what you do with the list it gives you.</p>
<h2 id="the-part-everyone-gets-wrong-what-deduplicate-actually-does-to-the-files">The part everyone gets wrong: what &ldquo;deduplicate&rdquo; actually does to the files</h2>
<p>Finding duplicates is the easy, safe part. Deciding what happens to them is where people get burned, because &ldquo;deduplicate&rdquo; can mean three genuinely different things with very different consequences.</p>
<p><strong>Straight deletion.</strong> You keep one copy, delete the rest. Simplest option, recovers the most space relative to effort, but it&rsquo;s irreversible and it means you now have exactly one copy where you used to have several. If those extra copies were accidentally serving as your only redundancy for something, you&rsquo;ve just reduced your safety margin, not just your clutter. Never run a delete pass without a current backup of the data you&rsquo;re touching, per the <a href="/data-hoarding/3-2-1-backup-strategy/">3-2-1 backup guide</a>, because the entire point of a dedup pass is bulk, fast, hard-to-fully-review changes across a lot of files at once.</p>
<p><strong>Hardlinking.</strong> Instead of deleting a copy, you replace it with a hardlink to the one you&rsquo;re keeping. Both filenames now point at the exact same inode on disk, so you get the space savings of deletion (the data is stored once) while every path that used to have its own file still resolves to something. The catch, and it&rsquo;s a real one: a hardlink is not a copy. If anything opens one of those linked paths and edits the file in place rather than replacing it, every other hardlinked path sees that edit too, because there is only one file, wearing multiple names. This is exactly fine for media files you never edit in place. It is a landmine for anything that might get modified later, like documents, configs, or database files that happen to have duplicate copies lying around.</p>
<p><strong>Reflinking.</strong> On filesystems that support it (Btrfs, XFS with reflink support, and recent enough setups of both), a reflink shares the underlying data blocks between two files copy-on-write style, the same space-saving benefit as a hardlink, but the moment either file is modified, the filesystem transparently splits the shared blocks so the edit only affects that one file. This is the safest of the three space-saving options if your filesystem supports it, since it behaves like an independent copy for every purpose except the storage cost, until an edit actually happens. It doesn&rsquo;t apply on ZFS or ext4, so check what you&rsquo;re actually running before assuming it&rsquo;s available.</p>
<p>If you&rsquo;re not certain which of these you want, straight deletion after a verified backup is the least surprising choice. Hardlinking is worth it specifically when you know the files in question are static (media libraries, archives, anything you treat as read-only), and reflinking is the best of both worlds exactly when your filesystem supports it.</p>
<h2 id="one-landmine-specific-to-a-media-library-setup-hardlinks-you-already-have-on-purpose">One landmine specific to a media library setup: hardlinks you already have on purpose</h2>
<p>If you&rsquo;re running the *arr stack (see the <a href="/data-hoarding/arr-stack-sonarr-radarr-prowlarr/">Sonarr/Radarr/Prowlarr guide</a>), you already have intentional hardlinks in your setup, between the download client&rsquo;s completed-download path and the media library&rsquo;s organized path, specifically so the same file exists in two locations without doubling your disk usage during the import step. That&rsquo;s the whole point of getting the path mapping right in that setup.</p>
<p>A dedup tool running across your entire library will correctly identify those as duplicates, because at the content-hash level, they are. Most decent tools (rmlint, fclones, jdupes all do this) will detect that two paths already share an inode and skip them automatically, since there&rsquo;s no space to reclaim there, they&rsquo;re already one file wearing two names. But it&rsquo;s worth confirming before you run a full pass, and it&rsquo;s a good reason not to point a dedup tool&rsquo;s delete or hardlink action at a media library directory without reviewing the report first. You want to catch the true accidental duplicate, the same episode imported twice into two different show folders, not undo the good kind of duplication your import pipeline set up deliberately.</p>
<h2 id="a-practical-workflow">A practical workflow</h2>
<ol>
<li><strong>Back up first.</strong> Not optional. Dedup passes touch a lot of files at once, exactly the kind of change you want a recent backup underneath before you start.</li>
<li><strong>Scan and review before acting.</strong> Every tool mentioned here supports a dry-run or a &ldquo;find only&rdquo; mode that produces a report without touching anything. Read it. Sanity-check a sample of the matches by hand, especially anything that surprises you.</li>
<li><strong>Start with the obvious offenders</strong>, not your whole hoard at once: Downloads folders, old manual-backup directories, duplicate photo-sync sources. These tend to have the highest ratio of true duplicates to total files, and mistakes there are lower-stakes than touching an organized media library.</li>
<li><strong>Pick delete, hardlink, or reflink deliberately</strong>, based on whether the files in question are static and whether your filesystem supports reflinks, not by default.</li>
<li><strong>Re-run the scan periodically</strong>, not once. Duplicates accumulate continuously from the same sources that created them the first time, so this is maintenance, not a one-time cleanup.</li>
</ol>
<p>None of this needs exotic tooling or a lot of manual effort once it&rsquo;s set up. The actual risk isn&rsquo;t the dedup tools themselves, all the ones covered here are careful by design. It&rsquo;s skipping the backup step, or pointing a delete action at a directory you didn&rsquo;t actually review first.</p>
]]></content:encoded></item></channel></rss>