A practical, evidence-based investigation into where the modern (File Provider–based) OneDrive macOS client physically stores data, why pinned files end up taking two copies of disk space while merely cached files take only one, how macOS itself tracks these states, and why there is no supported way to get the best of both (single copy + never evicted) on OneDrive.
Tested on macOS 26 (Tahoe-era), OneDrive client v26.x, APFS. Findings verified with
statblock counts, BSD file flags, extended attributes, the FileProvider SDK headers, andfileproviderctl evaluate. A companion read-only reporting tool,onedrive-cache-report.sh, is included in this gist.
- The OneDrive client stores data in two places (a user-facing mount and a private sync store). A file's footprint depends on its state: online-only = 0 copies, cached = 1 copy, pinned = 2 copies.
- OneDrive's "Always Keep on This Device" writes a real second physical copy. This is OneDrive's own implementation of "always keep" — not the same as iCloud's "keep downloaded", which keeps only a single copy (see below). That second copy is the root of the "OneDrive uses twice the space" complaints.
- For an individual file, macOS/Finder reads its online-vs-downloaded state
from a kernel BSD flag (
SF_DATALESS), not from a network check — which is why the file's cloud badge flips instantly. (A folder's badge is different: folders never carry that flag and instead aggregate their children — see below.) - Apple does have a real File Provider API for "keep downloaded" (this is what iCloud uses), but it is read-only to everyone except the owning provider: there is no public (or private) API, and no working xattr trick, to force-pin another provider's file. OneDrive did not implement an equivalent single-copy "keep downloaded" — so today you can't pin a OneDrive file without the second copy. The likely real fix is a third-party OneDrive client that keeps one copy.
- OneDrive doesn't use Apple's standard pin mechanism at all — it rolls its own (custom Finder actions + the second copy). So unlike iCloud, pinning costs a second copy, and there is no supported fix from Microsoft.
| Location | Role |
|---|---|
~/Library/CloudStorage/OneDrive-<Account>/ |
The user-facing mount (what you browse in Finder) |
~/Library/Group Containers/UBF8T346G9.OneDriveSyncClientSuite/OneDrive.noindex/OneDrive/ |
The sync client's private store |
(UBF8T346G9 is Microsoft's Apple Developer Team ID — it is the same string on
every Mac, not personal data.)
How much disk each file actually consumes depends on its state:
| Finder state | Icon | CloudStorage blocks |
OneDrive.noindex blocks |
Physical copies | Auto-evictable? |
|---|---|---|---|---|---|
| Online-only | ☁️ cloud | 0 | 0 | 0 | n/a |
| Cached (downloaded on access) | (no badge) | full | 0 | 1 | ✅ yes |
| Pinned ("Always Keep on This Device") | ✅ green check | full | full | 2 ❌ | ❌ no |
Pinned = two physical copies. Cached = one.
du walks each path independently and counts the same logical tree twice, so it
always makes it look like there are two full copies — even for cached files
that physically exist only once. Don't trust du across these two folders.
Use one of these instead:
- Per-file physical blocks:
stat -f "%z bytes %b blocks inode=%i" <file>(adataless/ online-only file reportsblocks=0). - Whole-volume truth:
df -m /System/Volumes/Databefore vs. after an action.
A file that has not been downloaded shows up like this:
-rwx------@ ... compressed,dataless 1004491141 somevideo.mp4
^^^^^^^^^^^^^^^^^^^^
BSD flags: not on disk yet (blocks=0)
Pick an online-only file (blocks=0, flagged dataless), record free space,
download it by reading it, then re-measure.
# before
$ stat -f "size=%z blocks=%b" video.mp4
size=1004491141 blocks=0 # ~958 MB, not on disk
$ df -m /System/Volumes/Data # Used = 613187 MB
# force download
$ cat video.mp4 > /dev/null
# after
$ stat -f "size=%z blocks=%b" video.mp4
size=1004491141 blocks=1961904 # now materialized (~958 MB)
$ df -m /System/Volumes/Data # Used = 614065 MB
Delta ≈ 878 MB ≈ 1× file size. A second copy would have cost ~1916 MB (2×).
Crucially, the same file inside OneDrive.noindex still reports blocks=0 —
it's just a placeholder. So a cached file is stored once.
Compare block counts for files that were pinned via "Always Keep on This Device", in both locations:
file CloudStorage_blocks noindex_blocks
projects/.../README.md 8 8
skills/.../SKILL.md 48 48
skills/.../image_gen.py 72 72
...
Both locations report the same non-zero block count for every pinned file. That is a real, independent second copy on disk (different inodes, real blocks).
Finder does not poll the network or scan file contents to draw a file's
☁️ badge. For an individual file the state lives in a kernel-level BSD file
flag, maintained by the File Provider system and visible via stat:
| State | st_flags (stat -f '%f') |
Decoded |
|---|---|---|
| Online-only | 0x40000060 |
SF_DATALESS + UF_COMPRESSED + UF_TRACKED |
| Cached / pinned | 0x40 |
UF_TRACKED only |
SF_DATALESS (0x40000000, "file is dataless object" in <sys/stat.h>) is
the bit that means "placeholder, not materialized". It is read-only (the
kernel/File Provider owns it) and flips the instant a file is downloaded or
evicted, which is why the Finder badge updates immediately.
Note: st_flags cannot tell cached from pinned — both are just 0x40. The
only way to detect the second copy is to cross-check block counts in the
OneDrive.noindex store (which is exactly what the companion script does).
Folders are different from files. A folder's own st_flags never carries
SF_DATALESS — it is always 0x00000000, even when every file inside it is
online-only. So Finder's folder-level ☁ badge is not a folder flag; it is an
aggregate of the descendants' download state.
The authoritative system signal is exposed by fileproviderctl evaluate <folder>:
| Folder contents | isDownloaded |
isRecursivelyDownloaded |
Finder ☁ on folder |
|---|---|---|---|
| All children cached/pinned | 1 | 1 | none |
| All children online-only | 1 | 0 | ☁ |
| Mixed (even one online-only child) | 1 | 0 | ☁ |
(isDownloaded = 1 for all three just means the folder's listing is present;
it says nothing about contents. The discriminator is isRecursivelyDownloaded.)
Verified by a controlled test: starting from an all-online folder
(isRecursivelyDownloaded = 0), reading one small file materialized exactly
that one file (the folder became 66 online / 1 cached) and the folder stayed
isRecursivelyDownloaded = 0. So:
A folder with no cloud badge ⟺
isRecursivelyDownloaded = 1⟺ every descendant is already downloaded. A single online-only child keeps the badge lit.
(Aside: downloading is per file, not per folder — reading one file does not pull its siblings. If you ever see a whole folder materialize at once, that's something else enumerating/previewing it, e.g. Finder/Spotlight/QuickLook.)
Why this still doesn't let a reporting tool skip the walk: this signal only
separates online-only from downloaded. It cannot distinguish CACHED from
CACHED+PINNED — both are "downloaded". Telling those apart (the whole point of a
disk-usage report) still requires descending to each file and checking for the
second copy in OneDrive.noindex. So a per-file walk is unavoidable for reporting.
This is the key new finding, and it explains everything above.
In the modern File Provider framework, "keep downloaded" is expressed through
NSFileProviderItem:
// FileProvider.framework/Headers/NSFileProviderItem.h
@property (nonatomic, readonly) NSFileProviderContentPolicy contentPolicy;
// ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
// NSFileProviderContentPolicyDownloadEagerlyAndKeepDownloaded
// = "Download eagerly… Prevent eviction on low disk pressure"Two things matter:
- The property is
readonlyand is declared by the provider extension, not by you. The comment in the header literally calls it a "declarative API" — the provider declares the policy; the system and any third party can only read it. - The older equivalent,
NSFileProviderItem.isPinned(macOS 11–13), was also read-only and is now deprecated in favor ofcontentPolicy.
Consequence: there is no public API for one app to set the pin / keep- downloaded state of another provider's file. Apple's developer forums confirm the same conclusion repeatedly — a third-party app can only observe the user's pin action (via Finder/Files), never set it for someone else's items. This is intentional.
Providers that delegate pinning to the system (iCloud Drive) get their pin state persisted by macOS as an extended attribute:
$ xattr -p com.apple.fileprovider.pinned <icloud-pinned-dir>
1
- It's set at the directory level and propagates to children
(the
#Pflag inxattr -loutput), with no second physical copy. - It is undocumented, system-managed, and not a supported write target. Apple's guidance is explicit: interact via the FileProvider API, do not read/write this xattr yourself.
OneDrive does not use the system pin mechanism at all:
- A OneDrive pinned file has no
com.apple.fileprovider.pinnedxattr. fileproviderctl evaluate <path>on a OneDrive pinned file still reportsisKeepDownloaded = 0— i.e. as far as the standard mechanism is concerned, it isn't pinned at all.- Instead, OneDrive ships custom Finder actions
(
com.microsoft.OneDrive.FileProviderActions.MarkPinned/MarkUnpinned) and implements "keep on device" by physically writing the second copy into itsOneDrive.noindexstore.
That's why OneDrive's pin badge is a separate icon next to iCloud's, and why its pin costs a second copy while iCloud's does not — they are different implementations, and the double-copy is OneDrive's own design choice, not a limitation forced by Apple's API.
Short answer: no. We tried the obvious hack — manually writing the xattr on a cached OneDrive file:
$ xattr -w com.apple.fileprovider.pinned 1 <onedrive-cached-file> # write "succeeds"
$ fileproviderctl evaluate <onedrive-cached-file>
… isKeepDownloaded = 0 # ← ignored. OneDrive doesn't read this.
The write is accepted by the filesystem but completely ignored by OneDrive,
because OneDrive's extension — not the system — is the source of truth for its
files. Combined with the fact that programmatic eviction is entitlement-gated
(NSFileProviderManager domain enumeration fails with "the application cannot
be used right now" from any unsigned CLI), there is no supported, working way
to get "single copy + never evicted" on OneDrive. You are limited to:
- cached → 1 copy, but macOS may auto-evict it under disk pressure, or
- pinned → never evicted, but 2 copies.
The only true fix would be a third-party OneDrive client that keeps a single local copy — a much larger undertaking.
There is no official Microsoft fix as of mid-2026; this is inherent to how the client implements pinning. Practical options:
- Don't pin. Leave files online-only and let them become cached on first use. Cached files are single-copy and auto-evicted under pressure. This is the lowest-footprint option.
- Pin selectively. Only pin small, truly must-be-offline folders. Avoid pinning large media trees.
- Reclaim space from already-pinned data. Right-click a pinned folder →
Free Up Space. This drops the second copy in
OneDrive.noindexand returns the items to online-only. (Programmatic eviction from a CLI is entitlement-blocked, so Finder is the supported path.) - Alternative clients (rclone, or a custom File Provider client) can keep a
single local copy, but each has trade-offs (weaker Finder integration; rclone
bisyncis still prone to "must run --resync" errors in 2025–2026, so it's risky for unattended two-way sync).
After unlinking/uninstalling, deleting these large folders may not immediately free space, because APFS local Time Machine snapshots still pin the deleted bytes. Thin them out:
sudo tmutil thinlocalsnapshots /System/Volumes/Data 999999999999 4
(Quote the trailing 4 in zsh: ... 999999999999 "4".)
Then re-check df -h /System/Volumes/Data.
This gist includes a small, dependency-free, read-only bash tool:
onedrive-cache-report.sh [PATH...] # count/size of ONLINE-ONLY / CACHED / CACHED+PINNED
# PATH defaults to the current dir (recursive)
- It is purely metadata (
find+stat+ theSF_DATALESSBSD flag + a block-count cross-check againstOneDrive.noindex). It never reads file contents, so it never triggers a download. It's the only reliable way to see, per folder, how much is online-only vs. cached vs. double-stored — something Finder never shows you. - It deliberately has no download / evict / pin operations. Those all live in Finder (click the ☁ to download; right-click → Free Up Space; right-click → Always Keep on This Device), and as shown above, eviction/pinning have no working or public CLI path anyway.
# online-only? -> flags include "dataless", blocks = 0
stat -f "%N blocks=%b flags=%f" file
ls -lO file # look for "dataless" in the flags column
# is a pinned file double-stored? compare blocks in both trees:
CS="$HOME/Library/CloudStorage/OneDrive-<Account>"
GC="$HOME/Library/Group Containers/UBF8T346G9.OneDriveSyncClientSuite/OneDrive.noindex/OneDrive"
stat -f "%b" "$CS/rel/path" # CloudStorage copy
stat -f "%b" "$GC/rel/path" # second copy if both > 0
# what does the system think about download/keep state?
fileproviderctl evaluate "$CS/rel/path" # look at isDownloaded / isKeepDownloadedIf both block counts are > 0, you're paying for two copies.