{"title":"Why du Overcounts On APFS","html_url":"https://deallocatedobjects.com/posts/why-du-overcounts-on-apfs","source_url":"","markdown_content":"Chrome keeps copies of itself in a temp folder on my Mac, 14 of them right now, and `du` says they take up 20 GB:\n\n```bash\n$ du -sh /var/folders/*/*/X/com.google.Chrome.code_sign_clone\n 20G\t/var/folders/l6/1y30n0fd2lg5fymm_086lcyh0000gn/X/com.google.Chrome.code_sign_clone\n```\n\nDeleting them would free far less than that. They're APFS clones, and nearly all of their blocks are shared with the copy of Chrome in `/Applications`. `du` adds up file sizes and has no idea two files can point at the same storage, so every clone gets counted in full.\n\nI learned this the expensive way while clearing space. I emptied a Trash that Finder said held 48.6 GB, and the free space on the disk went up by about 6 GB.\n\n### What A Clone Is\n\nWhen you copy a file on APFS with `cp -c`, or with Finder, or with anything that calls `clonefile()`, the new file is a clone. It gets its own name and metadata but points at the original's blocks. Nothing is written until one of the two files changes, and then only the changed blocks get new storage.\n\nHere's a 256 MB file of random data and three clones of it:\n\n```bash\n$ dd if=/dev/urandom of=original.bin bs=1m count=256\n$ cp -c original.bin copy1.bin\n$ cp -c original.bin copy2.bin\n$ cp -c original.bin copy3.bin\n$ du -sh .\n1.0G\t.\n```\n\nThe three clones changed the disk's free space by 92 KB. `du` reports 1.0 GB for the folder. A plain `cp` of the same file, for comparison, took 257 MB.\n\n### Checking Whether Two Files Share Storage\n\n`fcntl` with `F_LOG2PHYS_EXT` asks the file system where a byte of a file lives on the device. Clones of the same file give the same answer:\n\n```swift\nimport Darwin\n\n// Prints where the first byte of each file lives on disk.\n// Two files with the same device offset share storage (APFS clones).\nfunc physicalOffset(_ path: String) -> Int64? {\n    let fd = open(path, O_RDONLY)\n    guard fd >= 0 else { return nil }\n    defer { close(fd) }\n    var l2p = log2phys(l2p_flags: 0, l2p_contigbytes: 1, l2p_devoffset: 0)\n    guard fcntl(fd, F_LOG2PHYS_EXT, &l2p) != -1 else { return nil }\n    return l2p.l2p_devoffset\n}\n\nfor path in CommandLine.arguments.dropFirst() {\n    if let offset = physicalOffset(path) {\n        print(\"\\(offset)\\t\\(path)\")\n    } else {\n        print(\"?\\t\\(path)  (\\(String(cString: strerror(errno))))\")\n    }\n}\n```\n\nSave it as `shared-blocks.swift` and run it on the files you want to compare:\n\n```bash\n$ swift shared-blocks.swift original.bin copy1.bin copy2.bin copy3.bin plaincopy.bin\n955166838784\toriginal.bin\n955166838784\tcopy1.bin\n955166838784\tcopy2.bin\n955166838784\tcopy3.bin\n852936241152\tplaincopy.bin\n```\n\nThe clones all start at the same place on the disk, and the plain copy has its own.\n\nIt only checks the first byte, which is enough to tell a clone from a copy. A clone that has since been edited can share some blocks and not others, and this won't show you how many.\n\n### Where Clones Pile Up\n\nThe Chrome folder is the biggest one on my Mac. Each of those copies holds `Google Chrome Framework`, a 526 MB binary, and there are 28 of them across the 14 folders. The installed Chrome holds two versions of the framework, 156.0.8078.74 and 156.0.8078.80. Run the checker on all 28 copies and 27 of them share storage with one of those two. The last one is a clone of an older version.\n\n`node_modules` folders are the other big one. `bun install` uses `clonefile` on macOS by default (`--backend` lists it as the default), so the same package in several projects often shares one copy. Checking `typescript.js`, a 9 MB file, in a few of my projects:\n\n```bash\n853964869632\t2025-06-mcp-apple-mail/node_modules/typescript/lib/typescript.js\n853964869632\t2025-06-mcp-simple-email/node_modules/typescript/lib/typescript.js\n853964869632\t2025-06-namecheap-mcp-server/node_modules/typescript/lib/typescript.js\n153033752576\tagentenv/node_modules/typescript/lib/typescript.js\n153033752576\tagentic-sales-app/node_modules/typescript/lib/typescript.js\n445363130368\tagentic-todo/node_modules/typescript/lib/typescript.js\n```\n\nThe first three share one copy of TypeScript 5.8.3, and the next two share one copy of 5.9.3. The last project also has 5.9.3 but its own copy, so the same version number doesn't guarantee the files are shared.\n\nWhen you want to know what deleting something will free, check `df` before and after. That's the only number that counts clones correctly.\n\n### Keep Disk Scans Out Of iCloud Drive\n\nWhile I was hunting for space I ran into a second problem. My free space kept dropping by 10 to 30 GB and then coming back on its own a while later.\n\nThe cause was my own scans. iCloud Drive lives at `~/Library/Mobile Documents`, and with Optimize Mac Storage turned on, macOS evicts files you haven't opened in a while and keeps only a placeholder. Walking into those folders with `du` or `find` made macOS download evicted files again. Most of what came back down was Logic Pro projects of 30 to 150 MB each, and iCloud downloads a package like that whole. One `du` of iCloud Drive took it from 15.9 GB on disk to 26.4 GB, and a `find /Users` I left running pulled files down at about 1.1 GB a minute. macOS evicts them again later, which is why the space seemed to come back by itself.\n\nAnything that walks your home folder or `~/Library` will go in there unless you tell it not to. Both tools can skip it:\n\n```bash\ndu -sh -I \"Mobile Documents\" ~/Library\nfind ~ -path \"*/Mobile Documents\" -prune -o -name \"*.log\" -print\n```\n\nIf your disk is filling up and you suspect iCloud is downloading, `brctl status com.apple.CloudDocs` shows what's queued.","html_content":"<p>Chrome keeps copies of itself in a temp folder on my Mac, 14 of them right now, and <code>du</code> says they take up 20 GB:</p>\n<figure class=\"code\" data-lang=\"bash\"><figcaption><span class=\"lang\">Shell</span></figcaption><pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">$</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> du</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -sh</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> /var/folders/</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">*</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">/</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">*</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">/X/com.google.Chrome.code_sign_clone</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> 20G</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\t/var/folders/l6/1y30n0fd2lg5fymm_086lcyh0000gn/X/com.google.Chrome.code_sign_clone</span></span></code></pre></figure><p>Deleting them would free far less than that. They’re APFS clones, and nearly all of their blocks are shared with the copy of Chrome in <code>/Applications</code>. <code>du</code> adds up file sizes and has no idea two files can point at the same storage, so every clone gets counted in full.</p>\n<p>I learned this the expensive way while clearing space. I emptied a Trash that Finder said held 48.6 GB, and the free space on the disk went up by about 6 GB.</p>\n<h2 id=\"what-a-clone-is\" data-level=\"3\">What A Clone Is</h2>\n<p>When you copy a file on APFS with <code>cp -c</code>, or with Finder, or with anything that calls <code>clonefile()</code>, the new file is a clone. It gets its own name and metadata but points at the original’s blocks. Nothing is written until one of the two files changes, and then only the changed blocks get new storage.</p>\n<p>Here’s a 256 MB file of random data and three clones of it:</p>\n<figure class=\"code\" data-lang=\"bash\"><figcaption><span class=\"lang\">Shell</span></figcaption><pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">$</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> dd</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> if=/dev/urandom</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> of=original.bin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> bs=1m</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> count=</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">256</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">$</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> cp</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -c</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> original.bin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> copy1.bin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">$</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> cp</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -c</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> original.bin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> copy2.bin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">$</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> cp</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -c</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> original.bin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> copy3.bin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">$</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> du</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -sh</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> .</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">1.0G</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\t.</span></span></code></pre></figure><p>The three clones changed the disk’s free space by 92 KB. <code>du</code> reports 1.0 GB for the folder. A plain <code>cp</code> of the same file, for comparison, took 257 MB.</p>\n<h2 id=\"checking-whether-two-files-share-storage\" data-level=\"3\">Checking Whether Two Files Share Storage</h2>\n<p><code>fcntl</code> with <code>F_LOG2PHYS_EXT</code> asks the file system where a byte of a file lives on the device. Clones of the same file give the same answer:</p>\n<figure class=\"code\" data-lang=\"swift\"><figcaption><span class=\"lang\">Swift</span></figcaption><pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Darwin</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Prints where the first byte of each file lives on disk.</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Two files with the same device offset share storage (APFS clones).</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">func</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> physicalOffset</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">_</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> path: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">String</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">-></span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> Int64</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">?</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    let</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> fd </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> open</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(path, O_RDONLY)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    guard</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> fd </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">>=</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> else</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">return</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> nil</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    defer</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">close</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(fd) }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    var</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> l2p </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> log2phys</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">l2p_flags</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">l2p_contigbytes</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">l2p_devoffset</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    guard</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> fcntl</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(fd, F_LOG2PHYS_EXT, </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">&#x26;</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">l2p) </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">!=</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -1</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> else</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">return</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> nil</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> l2p.l2p_devoffset</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">for</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> path </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">in</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> CommandLine</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">arguments</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">dropFirst</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    if</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> let</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> offset </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> physicalOffset</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(path) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        print</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\\(offset)</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">\\t</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\\(path)</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    } </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">else</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        print</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"?</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">\\t</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\\(path)</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  (</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\\(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">String</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">cString</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">strerror</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">(errno)))</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">)\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre></figure><p>Save it as <code>shared-blocks.swift</code> and run it on the files you want to compare:</p>\n<figure class=\"code\" data-lang=\"bash\"><figcaption><span class=\"lang\">Shell</span></figcaption><pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">$</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> swift</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> shared-blocks.swift</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> original.bin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> copy1.bin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> copy2.bin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> copy3.bin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> plaincopy.bin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">955166838784</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\toriginal.bin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">955166838784</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\tcopy1.bin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">955166838784</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\tcopy2.bin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">955166838784</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\tcopy3.bin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">852936241152</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\tplaincopy.bin</span></span></code></pre></figure><p>The clones all start at the same place on the disk, and the plain copy has its own.</p>\n<p>It only checks the first byte, which is enough to tell a clone from a copy. A clone that has since been edited can share some blocks and not others, and this won’t show you how many.</p>\n<h2 id=\"where-clones-pile-up\" data-level=\"3\">Where Clones Pile Up</h2>\n<p>The Chrome folder is the biggest one on my Mac. Each of those copies holds <code>Google Chrome Framework</code>, a 526 MB binary, and there are 28 of them across the 14 folders. The installed Chrome holds two versions of the framework, 156.0.8078.74 and 156.0.8078.80. Run the checker on all 28 copies and 27 of them share storage with one of those two. The last one is a clone of an older version.</p>\n<p><code>node_modules</code> folders are the other big one. <code>bun install</code> uses <code>clonefile</code> on macOS by default (<code>--backend</code> lists it as the default), so the same package in several projects often shares one copy. Checking <code>typescript.js</code>, a 9 MB file, in a few of my projects:</p>\n<figure class=\"code\" data-lang=\"bash\"><figcaption><span class=\"lang\">Shell</span></figcaption><pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">853964869632</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\t2025-06-mcp-apple-mail/node_modules/typescript/lib/typescript.js</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">853964869632</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\t2025-06-mcp-simple-email/node_modules/typescript/lib/typescript.js</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">853964869632</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\t2025-06-namecheap-mcp-server/node_modules/typescript/lib/typescript.js</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">153033752576</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\tagentenv/node_modules/typescript/lib/typescript.js</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">153033752576</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\tagentic-sales-app/node_modules/typescript/lib/typescript.js</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">445363130368</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\tagentic-todo/node_modules/typescript/lib/typescript.js</span></span></code></pre></figure><p>The first three share one copy of TypeScript 5.8.3, and the next two share one copy of 5.9.3. The last project also has 5.9.3 but its own copy, so the same version number doesn’t guarantee the files are shared.</p>\n<p>When you want to know what deleting something will free, check <code>df</code> before and after. That’s the only number that counts clones correctly.</p>\n<h2 id=\"keep-disk-scans-out-of-icloud-drive\" data-level=\"3\">Keep Disk Scans Out Of iCloud Drive</h2>\n<p>While I was hunting for space I ran into a second problem. My free space kept dropping by 10 to 30 GB and then coming back on its own a while later.</p>\n<p>The cause was my own scans. iCloud Drive lives at <code>~/Library/Mobile Documents</code>, and with Optimize Mac Storage turned on, macOS evicts files you haven’t opened in a while and keeps only a placeholder. Walking into those folders with <code>du</code> or <code>find</code> made macOS download evicted files again. Most of what came back down was Logic Pro projects of 30 to 150 MB each, and iCloud downloads a package like that whole. One <code>du</code> of iCloud Drive took it from 15.9 GB on disk to 26.4 GB, and a <code>find /Users</code> I left running pulled files down at about 1.1 GB a minute. macOS evicts them again later, which is why the space seemed to come back by itself.</p>\n<p>Anything that walks your home folder or <code>~/Library</code> will go in there unless you tell it not to. Both tools can skip it:</p>\n<figure class=\"code\" data-lang=\"bash\"><figcaption><span class=\"lang\">Shell</span></figcaption><pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">du</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -sh</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -I</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"Mobile Documents\"</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> ~/Library</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">find</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> ~</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -path</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"*/Mobile Documents\"</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -prune</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -o</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -name</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"*.log\"</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -print</span></span></code></pre></figure><p>If your disk is filling up and you suspect iCloud is downloading, <code>brctl status com.apple.CloudDocs</code> shows what’s queued.</p>","created_at":"2026-11-13T14:00:00.000Z","updated_at":"2026-11-13T14:00:00.000Z"}