What is thin provisioning, and what's the catch with it?
Thin provisioning advertises more space than physically exists, allocating real blocks only as data is written — efficient, but the pool can fill up while tools still report "free" space.
Normally you reserve all of a volume's space up front (thick provisioning), even the empty part. Thin provisioning over-commits on purpose: it promises each filesystem a large size but only consumes physical blocks when data is actually written.
Advertised size: 1 TiB ← what applications see
Actually written: 100 GiB ← real blocks consumed
Pool capacity: 500 GiB ← total physically available
This is great for utilization — several filesystems share one pool and you don't waste capacity on empty space. The danger is over-commitment: the sum of advertised sizes can exceed the real pool, so if everyone fills up, the pool runs out before any single filesystem looks full.
This is why ordinary df is misleading on a thin-provisioned setup (e.g. Stratis): it reports the advertised 1 TiB and shows free space even though the underlying pool may be nearly exhausted. You must check the pool directly:
stratis pool list
# Name Total Physical ...
# pool1 5 GiB / 4.96 GiB ← 4.96 of 5 GiB used → nearly full!
Rule of thumb: with thin provisioning, monitor the pool's real usage, not the filesystem's df — and keep headroom so a write storm can't run the pool dry and cause out-of-space errors.
Go deeper:
Thin provisioning — Wikipedia — over-commitment and allocate-on-write (the "pool fills before df shows full" catch).