You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Measured: how the M4 Max display allocator actually behaves (3× 5K/165 panels + mixed configs)
This community — and discussion #4871 in particular — is where I found the only real prior art on macOS multi-display high-refresh limits, so I wanted to bring the data back here. I spent a week probing an M4 Max Mac Studio (macOS 27 Public Beta 2) with three LG 27GM950B panels (5120×2880 @ 165Hz native, DP 2.1/HDMI 2.1, DSC), plus a 4K/240 ASUS PG32UCDM3 and two QHD/144 ProArts for controls. Summary of what the allocator does, with the receipts condensed:
Findings
1. Per-display limits are soft. A single 27GM950B negotiates full native 5K @ 165 (2.43 Gpx/s) over both HDMI 2.1 and TB5 → USB-C-to-DP 2.1 cable — the monitor OSD confirms a genuine DP 2.1 link on the TB path. Apple documents 5K/120 as the single-display max; DSC makes the extra headroom real.
2. Two fast pipes, both claimable. Two GM9s run 5K/165 simultaneously (~4.87 Gpx/s) — one HDMI, one TB→DP. Apple's docs imply only one "fast class" display in 3+ display configs; in practice both fast pipes stay grantable.
3. Assignment is sticky and happens at enumeration. Once displays are connected, nothing re-deals the pipes. Concrete proof: in a triple config with the third display capped at 5K/60, manually dropping all three displays to 60Hz (2.65 Gpx/s total — headroom everywhere) still leaves the third display's mode list topping out at 60. Freeing bandwidth after the fact is invisible. Only physical replug re-enumerates.
4. Three distinct over-budget behaviors, never renegotiation:
Refusal: with dual-165 held, a third GM9 on any TB port refuses to enumerate — no signal, no fallback mode.
Basement demotion: hot-plugging into a marginally-over mix (2× GM9 + 2× QHD) drops the newcomer to a 3200×1800 @ 60 mode (~0.35 Gpx/s).
Tailored synthesis: with 165/165 held and a 4K/240 panel plugged last on HDMI, macOS offers a fixed, synthesized 4K @ 97Hz as the top of the mode list (97/60/50/30/25/24). No standard timing exists at 97; it's computed.
5. The 97Hz mode is a continuous probe of the budget. 4K@97 ≈ 0.805 Gpx/s; add 2× 2.433 and the machine total is ~5.67 Gpx/s. It also retro-explains the GM9's 5K/60 grant on the same seat: 0.885 fits, 5K/65 (0.96) wouldn't — 60 was the largest EDID mode fitting the remainder, same algorithm. Working model: two priority fast pipes drawing first from a ~5.7 Gpx/s machine budget, third seat sized to the remainder.
6. Pooling by output path. With both fast grants on Thunderbolt, a third display on any TB port gets nothing, while the same panel on HDMI comes up at the remainder mode. The HDMI output behaves like an independent pipe — in the triple config it's the reason a third display exists at all.
7. Workaround that works without EDID tools: pre-setting the connected displays' refresh before hot-plugging the next display changes what the allocator grants (120/120 pre-set → third display enumerates instead of refusing). This is how the first triple config came up.
8. No Adaptive-Sync anywhere. None of these panels (full G-Sync/FreeSync on Windows) ever show a variable option on macOS in these configs — presumably the usual DP-only / no-HDMI-VRR / scaled+DSC interference constraints.
Full pixel-rate ledger
Config
Aggregate (Gpx/s)
Outcome
1× 5K165
2.43
✅ either port
2× 5K165
4.87
✅
2× 5K165 + 2× QHD144
5.92 req.
❌ newcomer demoted to 0.35
3× 5K165
7.30
❌ third refuses to enumerate
2× 5K120 + 5K60
4.42
✅ (via pre-set workaround)
2× 5K165 + 5K60
5.75
✅ best all-5K result
2× 5K165 + 4K@97 (synthesized)
5.67
✅ best mixed result
3× on Thunderbolt, any refresh
—
❌ no signal; third stream requires HDMI
(For contrast: the same three panels on an RTX 5090 run 165/165/165 at 10-bit — the limits above are allocator behavior, not the panels or links.)
Questions for people who know the internals
Does anything in IOKit / the display pipeline corroborate the "two fast pipes + remainder seat + ~5.7 Gpx/s budget" model, or is there a better framing?
Is there a reason the HDMI path acts as an independent pipe while the TB side refuses a third stream outright?
The BetterDisplay-shaped question: since assignment is decided at enumeration, could a pre-connection EDID override (presenting a panel as, say, 6K/60-class) coax the TB side into granting a third TB stream? Sticky assignment means the override must exist before connect — is that feasible with BetterDisplay's EDID tooling today?
Remaining discriminating experiment I can run: whether 2× QHD/144 at plain native (no supersampling) coexist with 165/165/60 — pipe model says yes (~each fits a standard slot), pure aggregate budget says no (~6.8 total). Happy to test and report back, along with any other configs people want probed.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Measured: how the M4 Max display allocator actually behaves (3× 5K/165 panels + mixed configs)
This community — and discussion #4871 in particular — is where I found the only real prior art on macOS multi-display high-refresh limits, so I wanted to bring the data back here. I spent a week probing an M4 Max Mac Studio (macOS 27 Public Beta 2) with three LG 27GM950B panels (5120×2880 @ 165Hz native, DP 2.1/HDMI 2.1, DSC), plus a 4K/240 ASUS PG32UCDM3 and two QHD/144 ProArts for controls. Summary of what the allocator does, with the receipts condensed:
Findings
1. Per-display limits are soft. A single 27GM950B negotiates full native 5K @ 165 (2.43 Gpx/s) over both HDMI 2.1 and TB5 → USB-C-to-DP 2.1 cable — the monitor OSD confirms a genuine DP 2.1 link on the TB path. Apple documents 5K/120 as the single-display max; DSC makes the extra headroom real.
2. Two fast pipes, both claimable. Two GM9s run 5K/165 simultaneously (~4.87 Gpx/s) — one HDMI, one TB→DP. Apple's docs imply only one "fast class" display in 3+ display configs; in practice both fast pipes stay grantable.
3. Assignment is sticky and happens at enumeration. Once displays are connected, nothing re-deals the pipes. Concrete proof: in a triple config with the third display capped at 5K/60, manually dropping all three displays to 60Hz (2.65 Gpx/s total — headroom everywhere) still leaves the third display's mode list topping out at 60. Freeing bandwidth after the fact is invisible. Only physical replug re-enumerates.
4. Three distinct over-budget behaviors, never renegotiation:
5. The 97Hz mode is a continuous probe of the budget. 4K@97 ≈ 0.805 Gpx/s; add 2× 2.433 and the machine total is ~5.67 Gpx/s. It also retro-explains the GM9's 5K/60 grant on the same seat: 0.885 fits, 5K/65 (0.96) wouldn't — 60 was the largest EDID mode fitting the remainder, same algorithm. Working model: two priority fast pipes drawing first from a ~5.7 Gpx/s machine budget, third seat sized to the remainder.
6. Pooling by output path. With both fast grants on Thunderbolt, a third display on any TB port gets nothing, while the same panel on HDMI comes up at the remainder mode. The HDMI output behaves like an independent pipe — in the triple config it's the reason a third display exists at all.
7. Workaround that works without EDID tools: pre-setting the connected displays' refresh before hot-plugging the next display changes what the allocator grants (120/120 pre-set → third display enumerates instead of refusing). This is how the first triple config came up.
8. No Adaptive-Sync anywhere. None of these panels (full G-Sync/FreeSync on Windows) ever show a variable option on macOS in these configs — presumably the usual DP-only / no-HDMI-VRR / scaled+DSC interference constraints.
Full pixel-rate ledger
(For contrast: the same three panels on an RTX 5090 run 165/165/165 at 10-bit — the limits above are allocator behavior, not the panels or links.)
Questions for people who know the internals
Full writeup with the step-by-step receipts: https://gist.github.com/bnaert/14a4ad2e3ab5ece3a3520fe44a928fb9
All reactions