Apple silicon · APFS · storage

The 92 GiB cliff inside an Apple SSD

A sustained write, exposed NAND geometry, and a clean recovery trace show how free TLC becomes a dynamic pseudo-SLC write path.

M4 MacBook Air logic board photographed outside the laptop
Integrated Apple storage. The M4 MacBook Air logic board, where the NAND storage is soldered rather than packaged as a removable SSD. Photo: iFixit; resized and converted to AVIF under CC BY-NC-SA 3.0.

I started with a practical question: was this Mac's storage behaving badly, or was normal Apple SSD behaviour being mistaken for an APFS or swap problem?

The health checks were almost disappointingly clean. SMART was verified, TRIM was enabled, there were no thermal warnings, and the Data volume still had about 266 GiB free. The interesting answer appeared only after a queue-depth-one, uncached 100 GiB write made the NAND move from its fast path to its sustained path.

92 GiBhigh-speed write window in this free-space state
2.3–2.5 GiB/stypical rate before the transition
429 MiB/smedian across GiB 94–100
58% freeAPFS Data volume headroom during the test

The drive held roughly 2.3–2.5 GiB/s through GiB 92, fell during GiB 93, and then settled around a 429 MiB/s median. After the file was deleted and the blocks became reusable, a new 4 GiB write immediately returned to full speed.

The defensible conclusion is not that every APPLE SSD AP0512Z contains a fixed 92 GiB cache. It is that this drive, at this level of free space, exposed a dynamic pseudo-SLC window of about 92 GiB. Apple's firmware policy remains undocumented.

The result also answers the original tuning question. There is no hidden APFS switch worth chasing here. Free space, competing I/O and application write patterns matter; speculative filesystem surgery does not.

Start with the boring answer: the drive is healthy

Property Observed value
SSD model APPLE SSD AP0512Z
Controller AppleANS3CGv2Controller
Controller firmware 2973.120
Interface Apple Fabric, internal
Controller-reported capacity 512,000,000,000 bytes
macOS-visible namespace 500,277,792,768 bytes
Main APFS container Approximately 494.4 GB
Data volume Approximately 460 GiB
Data volume available Approximately 266 GiB
Data volume use Approximately 40% used, 58% free
Logical/physical block size 4 KiB
TRIM Enabled
SMART Verified
FileVault Enabled
Time Machine during testing Idle
Data-volume snapshots None
Thermal/performance warnings None recorded

The physical I/O device is disk0. APFS synthesized/container identifiers include disk3, so targeted iostat monitoring should use the physical device or the general iostat -d view rather than assuming disk3 is the hardware device.

The controller exposes more than I expected

IORegistry exposed the following controller characteristics:

Controller property Value
NAND vendor SanDisk
NAND identifier tlc_3d_g5_2p_512
Default bits per cell 3
Cell type 3, TLC
NAND page size 16 KiB
Native/TLC pages per block 1,344
SLC pages per block 448
Native/TLC sectors per full band 86,016
SLC sectors per full band 28,672
NAND buses 4
Dies per bus 2, 2, 2, 2
Total dies 8
Controller preferred I/O size 1 MiB
Controller command-pool size 64
Encryption type AES-XTS

The SLC geometry is exactly one-third of the native TLC geometry:

  • 448 / 1,344 = 1/3 pages per block.
  • 28,672 / 86,016 = 1/3 sectors per full band.
  • At 16 KiB per page, a block represents approximately 7 MiB in SLC mode and 21 MiB in native TLC mode.

This is the expected capacity tradeoff when TLC NAND temporarily stores one bit per cell instead of three. Pseudo-SLC is not a separate cache chip; it is the same TLC NAND operated in a faster, lower-density mode.

Making the cache show itself

The goal

Determine whether the SSD exhibits a capacity-dependent high-speed write region followed by a persistent lower plateau, while avoiding macOS page-cache distortion.

Method

  • Created a disposable test directory on the internal Data volume.
  • Marked the directory as excluded from Time Machine and Spotlight indexing.
  • Used 1 MiB write requests, matching the controller's preferred I/O size.
  • Enabled macOS F_NOCACHE on the file descriptor.
  • Issued F_FULLFSYNC after every 1 GiB.
  • Wrote a 100 GiB test file and reported throughput for each GiB.
  • Used random source data; FileVault's sector encryption also prevents a repetitive on-NAND zero pattern.
  • Deleted the file immediately after the test.
  • Performed a separate 4 GiB recovery test after cleanup.
  • Verified physical-device write counters, free space, snapshots, and thermal state afterward.

This was a queue-depth-one, strongly synchronized test. Its post-cache speed should not be treated as the maximum throughput achievable by every application, but it is well suited to identifying a write-cache transition.

The cliff

Test region Result
GiB 1–15 Variable warm-up/background range, approximately 1.6–2.8 GiB/s
GiB 16–92 Mostly 2.3–2.5 GiB/s
GiB 93 770.2 MiB/s; transition occurred within this segment
GiB 94–100 264.3–569.9 MiB/s
GiB 94–100 median 428.9 MiB/s
Approximate slowdown 5.7× versus a representative 2,445 MiB/s pre-cliff rate
Total 100 GiB elapsed time 60.6 seconds

Detailed transition and post-cache measurements:

Segment MiB/s
93 GiB 770.2
94 GiB 264.3
95 GiB 569.9
96 GiB 318.0
97 GiB 428.9
98 GiB 349.0
99 GiB 432.1
100 GiB 446.3

The fast path comes back

After the test file was deleted and its blocks became reusable, a new uncached 4 GiB write produced:

Recovery segment MiB/s
1 GiB 2,282.5
2 GiB 2,450.4
3 GiB 2,686.8
4 GiB 2,814.9

The return to full speed argues strongly against the earlier cliff being a lasting thermal limit. macOS also recorded no thermal or performance warning.

Proving the bytes reached disk0

Before the 100 GiB test, the physical-device write counter was:

23,067,131,904 bytes

Afterward it was:

130,736,635,904 bytes

The counter increased by 107,669,504,000 bytes. A 100 GiB write contains 107,374,182,400 bytes, leaving only about 295 MB attributable to concurrent system activity. This confirms that the benchmark reached the physical SSD rather than measuring a RAM-backed file cache.

The test and recovery check wrote 104 GiB in total. This is minor as a one-time diagnostic, but the benchmark should not be repeated routinely because synthetic writes consume NAND endurance.

What the cliff means

The evidence chain is:

  1. The drive identifies as native three-bit TLC.
  2. Apple exposes explicit one-bit SLC block and band geometry.
  3. SLC capacity is exactly one-third of TLC capacity.
  4. The drive maintained a high write plateau through 92 GiB.
  5. It entered a substantially lower, persistent plateau beginning during GiB 93.
  6. High initial speed returned after deletion/TRIM made blocks reusable.
  7. No thermal warning accompanied the transition.

The practical write path is therefore:

Host write
    |
    v
Available TLC blocks operated in one-bit pseudo-SLC mode
    |  approximately 2.4 GiB/s in this test
    |
    +--> background folding into native three-bit TLC
             |
             v
      Cache/folding headroom exhausted
             |
             v
      Direct TLC writes + folding + garbage collection
             |  approximately 429 MiB/s median in this test
             v
      Persistent native storage

Why 92 GiB fits the free-space geometry

At test time:

  • APFS reported approximately 266.389 GiB available.
  • The controller reported 512,000,000,000 bytes, while the exposed namespace was 500,277,792,768 bytes.
  • That namespace gap is 11,722,207,232 bytes, or approximately 10.917 GiB.

A simple one-bit-capacity model gives:

(266.389 GiB + 10.917 GiB) / 3 = 92.435 GiB

The measured high-speed extent was 92 GiB. The close alignment is strong evidence of a free-space-sensitive cache policy, but it is not an official allocation map. Apple does not expose whether every hidden block is eligible for pseudo-SLC or how firmware divides space among caching, garbage collection, metadata, and endurance reserves.

Proving the exact dynamic-size formula would require repeating destructive write tests at multiple disk-fill levels. The additional wear and temporary space consumption are not justified by the practical value of that result.

The hidden 10.917 GiB is not a cache partition

The 10.917 GiB figure is the difference between controller-reported capacity and the macOS-visible namespace. It is best described as hidden namespace headroom or over-provisioning, not as a dedicated cache partition.

The controller can dynamically use hidden headroom for overlapping purposes:

  1. Garbage collection: relocate live pages so entire NAND blocks can be erased and reused.
  2. Wear levelling: distribute writes across physical blocks.
  3. Bad-block replacement: retire factory-defective or worn blocks without reducing visible capacity.
  4. FTL metadata: maintain logical-to-physical mappings, allocation journals, erase counts, and recovery data.
  5. Pseudo-SLC staging and folding: provide temporary write locations and space for conversion into native TLC.
  6. Emergency free-block reserve: preserve write progress when the user-visible filesystem is almost full.

Important qualifications:

  • It is not a dedicated 10.917 GiB RAM or DRAM cache.
  • It is not necessarily dedicated exclusively to pseudo-SLC.
  • The NAND also contains factory spare-block capacity below the nominal 512 GB layer, so 10.917 GiB may not represent the SSD's total physical spare capacity.
  • Apple does not publish the precise allocation policy.

There is no magic APFS switch

APFS and the Apple storage controller are self-tuning. There is no supported global APFS performance setting for:

  • Pseudo-SLC cache size.
  • Flash garbage collection.
  • Queue depth.
  • Filesystem block size on the existing system volume.
  • Disabling copy-on-write or journaling.
  • Manual internal-SSD TRIM scheduling.

Changes that can help

  1. Keep substantial free space. At least 20–25% is a reasonable minimum; 30% or more is preferable for sustained-write workloads. The current 58% free is excellent.
  2. Exclude only disposable, high-churn data from indexing and backup. Examples include reproducible build output, dependency caches, VM scratch data, and disposable download/extraction directories.
  3. Keep high-churn scratch data outside iCloud Drive. This prevents cloud synchronization from competing with the workload.
  4. Improve application I/O patterns. Larger sequential writes, sensible batching, fewer unnecessary synchronous flushes, and workload-specific database settings can matter much more than filesystem changes.
  5. Avoid simultaneous heavy writers. Time Machine, Spotlight, cloud sync, extraction, VM images, and large downloads can compete for SSD bandwidth.
  6. Use a fast Thunderbolt NVMe SSD for scratch workloads that repeatedly exceed the internal drive's sustained post-cache behavior.

Changes I would not make

  • Do not disable FileVault; Apple Silicon provides hardware AES-XTS acceleration.
  • Do not disable journaling or attempt to disable APFS copy-on-write.
  • Do not run trimforce; TRIM is already enabled.
  • Do not defragment the SSD.
  • Do not use sudo purge or cache-cleaning tools as a performance treatment.
  • Do not routinely delete normal APFS snapshots.
  • Do not resize the APFS container merely to leave unpartitioned “over-provisioning.” Free, TRIMmed APFS blocks already provide controller headroom.
  • Do not create a separate APFS volume expecting higher physical throughput; volumes in one container share the same SSD and free-space pool.
  • Do not move or manually tune macOS swap.

Where free space still matters for swap

macOS stores dynamically allocated swap files under /private/var/vm on the APFS Data volume. The approximate pressure path is:

Unified-memory pressure
    -> cache reclamation
    -> memory compression
    -> dynamic swap files on APFS
    -> SSD pseudo-SLC/TLC and garbage collection

Free space affects swap in several ways:

Swap capacity

macOS creates and expands swap files as needed. If APFS cannot allocate additional blocks, macOS may spend time purging caches and reclaiming space, show an application-memory warning, or terminate processes when memory cannot be reclaimed.

Write latency and garbage collection

Swap produces small, latency-sensitive writes. With ample free blocks, the controller can allocate new pages and erase old blocks efficiently. Near full capacity it must relocate more live data, increasing write amplification and latency variability.

Pseudo-SLC headroom

More free NAND generally allows a larger pool of blocks to operate temporarily in SLC mode. The measured 92 GiB sequential allowance is not a literal swap-cache quota, because swap is more random and bursty, but the same free-block principle applies.

Swap-in contention

Free space primarily helps allocation and swap-out writes. Existing swap pages can be read without allocating space, but swap-in latency still suffers when the controller is busy with folding, garbage collection, backup, indexing, or other application I/O.

Conservative free-space rules of thumb:

Available space Expected behavior
25% or more Comfortable APFS and controller headroom
15–25% Usually fine; sustained writes may lose fast cache sooner
5–15% More garbage collection and higher latency risk
Below 5% Serious risk of stalls, failed allocations, and application-memory warnings

For this 512 GB drive, maintaining at least approximately 100–125 GB available is a reasonable target for workloads that regularly experience memory pressure. The observed 266 GiB available is well above that target.

Even under ideal storage conditions, swap remains dramatically slower than unified memory. Abundant free space keeps swap from becoming unnecessarily worse; it cannot make swap comparable to RAM.

What I would actually do

  1. Leave APFS, FileVault, TRIM, snapshots, and virtual-memory settings unchanged.
  2. Continue keeping substantial free space; the present 266 GiB is excellent.
  3. Use Spotlight and Time Machine exclusions only for genuinely disposable, high-churn directories.
  4. If an application is slow, profile its I/O and memory behavior rather than applying filesystem “tweaks.”
  5. Treat sustained writes above approximately 92 GiB as a special workload that may encounter the measured cache cliff under similar free-space conditions.
  6. Do not repeat the synthetic 100 GiB test unless a firmware update or material change in drive fullness creates a specific reason to revalidate it.

Reproducing the inspection

# Hardware and storage metadata
system_profiler SPHardwareDataType SPNVMeDataType
ioreg -r -c AppleANS3CGv2Controller -l
diskutil list
diskutil apfs list
diskutil info /

# Capacity and snapshots
df -h /System/Volumes/Data
diskutil apfs listSnapshots /System/Volumes/Data
tmutil listlocalsnapshots /

# Live physical-disk activity
iostat -d -w 1

# Memory pressure and swap
sysctl vm.swapusage
memory_pressure
vm_stat 1

# Time Machine and FileVault
tmutil status
fdesetup status

# Thermal/performance warnings
pmset -g therm

A useful external trace

A public sustained-write trace from another APPLE SSD AP0512Z also showed high, intermediate, and low write-speed regions, with its first major transition around 90 GiB:

That test used 4 KiB writes and periodic file synchronization, so its absolute throughput should not be compared directly with the local 1 MiB uncached test. Its transition pattern nevertheless agrees with the local result.

After the test

  • All temporary benchmark files and directories were deleted.
  • Available space returned to approximately 266 GiB.
  • No Data-volume snapshot retained the test file.
  • SMART remained verified.
  • TRIM remained enabled.
  • No thermal or performance warning was recorded.
  • No persistent system setting was modified.