~15 min · memory, fleet, bandwidth-per-gb, working-set, decode-ceiling, measured
Level 0Spec-Sheet Skimmer
0 XP0/91 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete
"Nine Macs, nine columns. Everything a language model will do on any of them is in this table before it runs."
The Table
Every column has an evidence label. Spec bandwidth is Apple's. Achieved bandwidth is the GPU track's streaming measurement, available for the four lab Macs and left blank elsewhere rather than guessed. The recommended GPU working set was read on all nine machines on 2026-09-15. GB/s per GB is arithmetic on the spec. The decode ceilings use the achieved figure where there is one and are marked as spec-based predictions where there is not.
Alias
Chip
Memory
Spec GB/s
Achieved GB/s
GB/s per GB
GPU working set
Ceiling, 9B (4.47 GB/token)
Ceiling, 27B (14.42)
office
M3 Ultra
512 GB
819
635–638
1.6
464.0 GiB (90.6%)
142 (achieved)
44 (achieved)
server
M3 Ultra
512 GB
819
—
1.6
464.0 GiB (90.6%)
183 (spec)
57 (spec)
worker
M2 Ultra
192 GB
800
—
4.2
161.3 GiB (84.0%)
179 (spec)
55 (spec)
music
M2 Ultra
192 GB
800
734–740
4.2
161.3 GiB (84.0%)
165 (achieved)
51 (achieved)
macbook
M5 Max
128 GB
614
— (not measured by rule)
4.8
107.5 GiB (84.0%)
137 (spec)
43 (spec)
pro2024
M4 Max
128 GB
546
—
4.3
107.5 GiB (84.0%)
122 (spec)
38 (spec)
pro2023
M3 Max
128 GB
400
359–391
3.1
107.5 GiB (84.0%)
87 (achieved)
27 (achieved)
mini
M4 Pro
64 GB
273
—
4.3
51.8 GiB (81.0%)
61 (spec)
19 (spec)
air
M3
24 GB
100
93–97
4.2
17.8 GiB (74.0%)
22 (achieved)
7 (achieved; fits only at short context)
Reading Across a Row
Take office. Spec 819, achieved 635 — the 78% from the GPU track. A 27B model at 4 bits reads 14.4 GB per token, so the ceiling from the achieved figure is 44 tokens per second; the lab track measured 32.6, and the physics track explains the remaining gap (per-token fixed overhead, the KV cache, the runtime). Its working set of 464 GiB is what makes it one of the two Macs in the house that can hold the largest open checkpoints at all. Its GB/s per GB of 1.6 is the lowest in the fleet: the machine that holds the most decodes its largest possible model the slowest, which is not a flaw but the shape of LPDDR.
Take air. Spec 100, achieved 97 — the memory delivers what the sheet says. Its 4.2 GB/s per GB is higher than office's, so a model that fills the Air decodes faster, relative to its size, than a model that fills office. But its working set is 17.8 GiB, so "a model that fills the Air" is a 16 GB model at a short prompt and a 9B model at any real context. The two machines are opposite corners of the same table, and the household uses them as opposite tools.
Reading Down a Column
The working-set column is the one that surprised this quest. The reserve the operating system keeps for itself grows with the pool but not in proportion: 6.2 GiB on 24, 12.2 on 64, 20.5 on 128, 30.7 on 192, 48 on 512. Every buying guide that says "the GPU gets about 75%" is describing the smallest row. The achieved column has its own surprise — the M3 Ultra's 78% against the M2 Ultra's 92% — and this quest reports it without explaining it, because nothing in user space can. The ceiling columns are what the lab track tests, one machine at a time, with the predictions written down first.
Code
fleet_memory.py — the table, generated from live reads and the measured achieved figures·python
#!/usr/bin/env python3
"""Per-Mac memory columns. Spec GB/s from Apple; achieved from stream.py where
measured (None elsewhere — never guessed); working set read live over ssh."""
import subprocess
SPEC = {"office": 819, "server": 819, "worker": 800, "music": 800, "macbook": 614,
"pro2024": 546, "pro2023": 400, "mini": 273, "air": 100}
ACHIEVED = {"office": 638, "music": 740, "pro2023": 391, "air": 97} # stream.py sum, 2026-09-15
BYTES_PER_TOKEN = {"9B": 4.47e9, "27B": 14.42e9}
READ = ("for p in ~/miniconda3/envs/silicon-lab/bin/python ~/miniconda3/envs/mlx/bin/python ~/miniconda3/envs/cwk-asr/bin/python ~/miniconda3/bin/python /opt/homebrew/bin/python3; do "
"[ -x $p ] && $p -c 'import mlx.core as mx; i=(mx.device_info() if hasattr(mx,\"device_info\") else mx.metal.device_info()); "
"print(i[\"memory_size\"], i[\"max_recommended_working_set_size\"])' 2>/dev/null && break; done")
print(f"{'alias':8} {'GB':>4} {'spec':>5} {'achieved':>9} {'GB/s/GB':>8} {'working set GiB':>16} {'9B ceiling':>11} {'27B ceiling':>12}")
for alias, spec in SPEC.items():
out = subprocess.run(["ssh", "-o", "ConnectTimeout=8", alias, READ], capture_output=True, text=True).stdout.split()
phys, rec = (int(out[0]), int(out[1])) if len(out) == 2 else (None, None)
bw = ACHIEVED.get(alias)
basis = bw or spec
tag = "" if bw else " (spec)"
ws = f"{rec/2**30:6.1f} ({rec/phys:.0%})" if rec else " n/a"
print(f"{alias:8} {phys//2**30 if phys else '?':>4} {spec:5d} {str(bw or '—'):>9} {spec/(phys/2**30) if phys else 0:8.1f} {ws:>16} "
f"{basis*1e9/BYTES_PER_TOKEN['9B']:8.0f}{tag:>7} {basis*1e9/BYTES_PER_TOKEN['27B']:8.0f}{tag}")
Add your Mac as a complete row — all nine columns, achieved from your own stream.py run. Then pick a Mac in the table with a higher GB/s per GB and a smaller working set than yours, and describe one workload that is better on it and one that is impossible on it. Finally, mark on your row which two cells the lab track is about to test.
Hint
The two cells are the ceilings. The lab writes them down, runs the model, and explains the gap. A workload better on the smaller machine is a small model at high tokens per second; the impossible one is anything whose peak at your context exceeds its working set.
Progress
Progress is local-only — sign in to sync across devices.