Back to blog

2026.09.14

Three case fans at full blast, still 92°C. A zip-tie and a scrap of paper got it to 64°C. What's the number in between?

A passively-cooled datacenter GPU in a desktop case. Piling on more airflow does nothing. Here's how one subtraction and one division give you thermal resistance, why adding a third fan bought zero performance and only quieter operation, and the six times I fooled myself — including the ambient temperature I used across four chapters that turned out to be a hardcoded constant.

hardwarecoolingGPUmeasurement

A passively-cooled datacenter card goes into a desktop case. Three front fans at full speed. Three minutes and twenty seconds into a full load: core climbs from 74°C to 92°C, memory at 90°C. The card reports its own Max Operating temp as 85°C, hardware throttle at 95°C, shutdown at 98°C. Three minutes twenty — it hadn't even reached thermal equilibrium yet and was already past the line.

Then I zip-tied a single 120mm fan onto a 3D-printed shroud and stuffed the gaps with a scrap of paper. Same full load, 64°C at 107W.

Cost: a few zip ties and a piece of paper.

No more airflow. Same card, same case. What changed is where that air actually goes. This post is about turning that into a single number, and about the six times I got it wrong while measuring it — the most embarrassing being a value I used across four chapters and four rounds of experiments before discovering it was a constant baked into the motherboard's ACPI tables. It didn't budge when I moved the machine to a different room.

Want the criterion? Chapter 2 — it's one subtraction and one division. Want to see how I contaminated all my own data? Chapter 6.

1. Why case fans do nothing for these cards

Consumer GPUs bring their own fans. Datacenter cards don't. They assume they're sitting in a rack where a wall of screaming fans shoves air from the front of the chassis straight through to the back — the card is just one segment of that duct. Its fin stack is packed tight as a deck of cards, designed exactly for the case where something behind it is pushing hard.

A desktop case has no such thing. Air leaving a case fan spreads the moment it clears the frame. It flows past the card, not through it. Cranking RPM just spreads it faster.

One term worth defining before we go further: static pressure. A fan has two abilities — how much air it moves in open space (airflow, CFM), and how much it can still push against resistance (static pressure, usually in mmH₂O). A dense fin stack is an extremely high-resistance object, so for these cards the airflow number on the box is nearly worthless. Static pressure is the one that decides everything.

I later measured the system impedance coefficient of a duct feeding one of these cards at roughly 0.015. Your machine's number will differ, but its role is the same: it determines where a fan's rated specs actually land as an operating point.

2. The criterion: thermal resistance, one subtraction over one number

You can't judge cooling by temperature. Temperature is a function of power and ambient — change the power and it changes. What you compare is this:

Thermal resistance Rth = (steady-state temp − intake temp) ÷ power    in °C/W

It means "for every watt I put into this card, how many degrees above ambient does it sit." This isn't an empirical rule of thumb. It's a division.

Its real use is running it backwards:

Watts you can feed before hitting the wall = (temp wall − intake temp) ÷ Rth

Plug in my measurements. With three fans in series and the shroud sealed, steady state is 82.0°C at 200.1W, intake taken as 27.8°C:

Rth = (82.0 − 27.8) ÷ 200.1 = 0.2709
85°C capacity = (85 − 27.8) ÷ 0.2709 = 211 W

Drop to two fans, same day, same everything: Rth 0.2981, 85°C capacity 192W. One extra fan bought 19 watts.

Go back further — the original paper-scrap build was 0.371. The stock case-fans-blowing-randomly build was 0.626. From 0.626 to 0.2709 is 2.3× the cooling capability, without ever buying a heatsink. The money went to fans and a roll of filament.

The words "steady state" are the hard gate on this entire method. The day I swapped shrouds, my first comparison used "199W at 79°C before the swap" and concluded the new shroud was worse. That 79°C was an instantaneous reading I grabbed over a remote session while the load had barely started. The new shroud's first minute only hit 55.7°C — if I'd sampled that moment, Rth would have computed to 0.15 and looked miraculous.

Compare an instantaneous value against a steady-state one and your conclusion inverts. That was the first thing I got wrong here.

3. The third fan made it quieter, not cooler

Later I wanted to squeeze harder, and the question became: would adding an exhaust fan at the outlet help?

Intuitively yes. In practice the performance gain was exactly zero.

Because the power limit on this machine was set to 200W, and in testing the card never throttled on temperature even once:

Time throttled by temperature   0 s / 181 s   = 0%
Time capped by power limit      3 s / 181 s   = 1%

The constraint was a power wall I set myself, not cooling. Temperature wasn't the bottleneck, so shaving another 5°C off buys not one additional MHz. That is mathematically zero, and calling it "a small gain" would be wrong.

The second layer is more interesting. The shroud fans run on a temperature-closed loop — cooler means they spin down automatically. So what actually happens if it really does drop 4°C?

Currently 82-83°C → 97% duty → 1982 rpm
If it dropped to 78°C → 82% duty → about 1630 rpm

The fans slow themselves down, thermal resistance climbs back up, and steady state settles somewhere in the middle. The cooling headroom gets converted by the control loop into acoustic gain, not thermal gain.

There's a handy law on the noise side: sound power scales roughly with the fifth power of RPM, so

ΔdB ≈ 50 × log₁₀(rpm ratio)
50 × log₁₀(1982 ÷ 1630) = 4.2 dB

About 4 dB quieter, roughly a quarter reduction in perceived loudness. That's the only real benefit that fan buys.

My first answer to this question was "installing it won't change a single number," and I got called on it immediately — of course the temperature drops. I'd stated "zero performance gain" as if it meant "zero effect." The transferable lesson: before saying something is useless, split the benefit by dimension (performance / temperature / noise / longevity) and put a number on each. One dimension being zero doesn't make them all zero. And the dimension the other person cares about is often exactly the one where the gain is real.

4. "Small fans naturally have higher static pressure" — the direction is backwards

I've said this too, and I've handed out recommendations based on it. When it got dug up and challenged, I pulled the actual specs. It's backwards.

Static pressure scales roughly with the square of blade tip speed, and tip speed is:

u = π × diameter × rpm ÷ 60

120mm @ 2000rpm → 12.57 m/s
 92mm @ 2000rpm →  9.63 m/s

At the same RPM, the smaller fan's tip moves slower, so its static pressure is lower. Official data agrees: at 2000 rpm, one 120mm model rates 2.34 and one 92mm model rates 2.28 — the 92mm is slightly lower, and moves over 20% less air.

So why is the saying everywhere? It carries an unstated premise: small fans usually spin much faster. 92mm units commonly run 3000-6000 rpm; 120mm rarely do. Those 40mm screamers in rack servers get terrifying static pressure from 15,000 rpm, not from being small.

The correct statement: static pressure is set by RPM and blade design. Diameter only matters in the sense that at a fixed noise budget, bigger wins. You pick 92mm only when 120mm physically won't fit.

4.1 The real value of stacking: letting each fan spin slower

This is the most counterintuitive part. Put two fans in series and static pressure doubles while noise goes up 3 dB — sounds like trading noise for performance. But flip how you use it:

static pressure ∝ rpm²        airflow ∝ rpm
single-fan noise change = 50 × log₁₀(rpm ratio)
N stacked                = single-fan noise + 10 × log₁₀(N)

That +10·log₁₀(N) grows painfully slowly — three fans is only +4.8 dB. The 50·log₁₀(r) term falls off a cliff. So adding a fan and then slowing them all down nets out quieter.

Plugged into my duct's target flow:

Setup RPM each Estimated total noise
2000-rpm model ×2 (what I had) 2000 rpm 32.7 dBA
2000-rpm model ×3 1670 rpm 30.6 dBA
3000-rpm model ×1 2964 rpm 43.2 dBA

Going from two to three of the same fan is 2.1 dB for free. And a single fast fan delivers about the same static pressure as two slow ones in series (7.63 vs 7.88) while costing nearly 11 dB.

The only cost is thickness and money. So when someone asks "is one fan enough," the right answer is usually "more is better," not "one will do."

4.2 But stacking cannot raise the airflow ceiling

This is the hard boundary on the previous point, and where it most often gets misused.

On a fan's pressure-flow curve, series stacking multiplies the pressure axis by N — but the right-hand endpoint, maximum airflow, does not move at all. It's set by swept area and blade design. So the operating-point flow has an asymptotic ceiling that's completely independent of how many fans you stack.

Run it for a 92mm model (max airflow 46.44 CFM, target 21.83):

×1  →  11.92 CFM
×3  →  19.40        target is 21.83 — still short
×10 →  29.86        ten fans barely clears it, which is absurd

Check max airflow first — that's the ceiling, and stacking can't raise it. Then check static pressure — that one you can stack your way to. A fan whose max airflow falls short is money burned no matter how many you buy.

5. Two numbers both called "thermal resistance," 2.6× apart

Here's a weapon for you.

There are two ways to compute thermal resistance. Same name, different quantities:

Method Formula What it contains
Single-point (temp − intake) ÷ power includes the constant term
Slope Δtemp ÷ Δpower increment only

The single-point method divides the card's idle baseline temperature into the result. The slope method doesn't. I once ran a regression across several power levels and fit T = 54.0 + 0.143·P — that 0.143 is a slope. The single-point number for the same card in the same duct is 0.2443.

Compare 0.143 against 0.2379 and you get "cooling improved 2.6×." I genuinely reached that conclusion once.

Reading any cooling data, first ask how it was computed and whether there's an intercept term. There's a related trap that's more common in the fan world: marketing copy says "high airflow" while withholding all three key numbers. High airflow and high static pressure are opposing design choices — shallow blades with fewer of them push far in open air and collapse against resistance; steep blades with more of them hold up against a fin stack. A product advertising high airflow without publishing static pressure is unusable in a high-resistance duct by default, no matter how good the rest of the spec sheet looks.

A subtler one: I once ruled out a blower fan because "the label says 12V 1.80A = 21.6W and the motherboard header is rated 1A / 12W — that's 1.8× over spec, don't plug it in." The pushback was "I've seen people plug this exact fan into a board and it's fine." They were right. Those two numbers aren't the same quantity. A fan's nameplate rating is maximum/locked-rotor; a motherboard header's rating is continuous. Compare a peak against a continuous rating and "over spec" is guaranteed. A napkin calculation exposes it: that blower's aerodynamic power at a typical operating point is about 1.11 W, and at 15-25% efficiency that back-solves to 4.4-7.4 W electrical. To continuously draw 21.6 W it would have to move 78 CFM, which a blower that size physically cannot do.

Any conclusion of the form "A exceeds B therefore no" needs A and B confirmed as the same kind of measurement first. Same family of traps: peak power vs TDP, burst bandwidth vs sustained bandwidth, PSU peak output vs rated output.

6. The ambient temperature I used for four chapters was a hardcoded constant

This is the part worth remembering.

Every Rth above used "intake temperature 27.8°C," read from a system temperature sensor. I built four chapters of data on it.

Later the machine moved from the study to the living room and I re-measured out of habit. Rth landed on the same point three times (1.3% spread) — the shroud hadn't shifted, the blanking plate hadn't fallen off. Good. But one detail was off: I changed rooms and the number was still 27.8.

for i in 1 2 3 4 5; do cat /sys/class/thermal/thermal_zone0/temp; sleep 1; done
# 27800 27800 27800 27800 27800

Different room, a reboot, CPU temp moving from 34 to 38 — it didn't twitch. That value is a constant in the motherboard's ACPI tables, never a sensor reading at all. This machine has no real intake sensor.

Blast radius: every (T − 27.8) / P in four chapters used a fake value.

But the shape of the damage is interesting enough to unpack:

  • Historical comparisons still hold. A constant denominator is a uniform bias, so every internal comparison survives — conclusions like "the third fan improved things 9.1%" are still valid.
  • Absolute values were about 12% too high. Ambient was underestimated, so resistance was overestimated.

Switching to a real proxy — an idle display GPU in the same case at 33.8°C, same duct, same environment, the closest thing to what the shroud fans actually inhale — corrects Rth from 0.2680 to 0.2379.

And the 85°C capacity? 213 W vs 215 W. A 1% difference. Because temp wall − intake and Rth move in the same direction, the errors cancel. Every capacity conclusion in the archive is unaffected.

The transferable criterion: any quantity serving as a baseline, a reference, or a normalizing denominator must be independently verified to actually respond to the conditions you're varying. An unchanging reference frame is broken — don't read it as stable. I only caught this because I changed rooms and it stayed 27.8. Had I always measured in the same room, that fake value could have survived any number of experiments — its error is a constant offset, it cancels in every internal comparison, and it would never surface.

Relatives of this: a control group fixed at a constant, a cached baseline, a hardcoded threshold, a health check that always returns the same value.

7. The rest of the wrecks, briefly

Analytical extrapolation is systematically optimistic. Before installing the third fan I solved the pressure-flow intersection and predicted "flow up 19.7% → Rth 0.2628 → 218 W." Measured: 0.2709 / 211 W. Right direction, optimistic by about a third. Same day, something worse: a duty-cycle sweep predicted 111°C, measured 84°C. Any number that feeds a decision gets measured, not extrapolated.

Swallowing a subprocess's stderr disguises failure as silent success. The first version of my load script invoked the system Python while the compute library only existed inside a virtualenv. Module not found, instant exit. Because stderr went to /dev/null, the script noticed nothing and dutifully measured five minutes of an idle card (48 W, SM at 210 MHz), nearly producing a fabricated Rth. The fixed version added two guards: use the virtualenv interpreter and assert the path exists first; during warmup, verify power ≥120 W and utilization >80%, abort otherwise. Better to fail than to hand back a fake number.

R² dropping from 0.99 to 0.92 means a data point never reached equilibrium. Don't reach for a physical explanation yet. Running a before/after dust-cleaning comparison, the first power level showed a 7°C difference and I nearly booked it as the cleaning effect. In reality that card started cold at 32°C and the probe's 100-second warmup wasn't enough for the first level — all six samples were still climbing monotonically (55→57→58→60→61→62). Drop the first level and the fit goes from 0.9241 to 0.9958. In any before/after comparison, both groups must start from the same thermal state. This kind of contamination is visible in R² and invisible in the mean.

A control group's "untreated" status is a claim requiring evidence, not a default assumption. Same dust experiment: I compared two different cards and computed a 1.0% improvement from cleaning — below the 1.3% measurement noise, so the conclusion is "cleaning isn't worth doing for performance." I stand by that, but its boundary has to be stated: the one confound I never eliminated is card-to-card variation (silicon leakage, thermal pad compression, heatsink mounting tolerance). Two different cards means individual variation could easily be the same magnitude as the dust effect, or could cancel it out. What I have is an upper bound of 1.0%. It is not a point estimate saying dust does nothing. Properly eliminating it requires one card measured before and after cleaning, without removing the shroud in between.

Pull specs from the manufacturer, never from memory. In a single conversation I misreported four times: two fans' static pressure overstated by 22% and 8.6%, the "92mm has naturally higher static pressure" claim stated backwards, and I omitted the exact row that should have been the baseline. The person I was talking to remembered what I'd said earlier and caught it on the spot.

8. What isn't finished

For honesty's sake, these gaps exist and I won't state the conclusions harder until they're closed:

  • The tip-speed model in chapter 4 predicts 92mm static pressure should be 0.588× that of 120mm by the square relationship, while the actual ratio between two real products is 0.974. Direction correct, magnitude way off — blade design, blade count, and frame structure contribute on the same order as diameter. That proportionality is only good for telling you which way something goes, never for computing a value. I only used it directionally here; no decision in this post rests on it numerically.
  • Every absolute Rth depends on the substitute intake baseline (the idle display GPU). Same case, zero load, same airflow — the best proxy I have, but it isn't a sensor mounted at the intake.
  • Ambient is a seasonal variable. Every degree of room warming adds a degree to steady state, so every power-wall conclusion above has to be re-measured once the weather turns.
  • The dust result is an upper bound of 1.0% with no point estimate, for the reason above.

9. The order to do this in

Next time you're cooling a passive card, follow this order. Don't start from a product catalog.

  1. Measure your current thermal resistance first. Run full load to steady state — keep going until temperature is jittering within ±1°C, and never settle for a quick instantaneous grab — then (temp − intake) ÷ power.
  2. Confirm your "intake temperature" actually moves. Change something about the environment (different room, open a window, add a fan) and read it again. A number that doesn't budge is unusable.
  3. Back-solve the required Rth from your target power, (temp wall − intake) ÷ target watts, then back-solve the flow and static pressure that implies.
  4. Only now open the catalog. Check max airflow first (the ceiling, unstackable), then static pressure (stackable).
  5. Your candidate pool must include industrial manufacturers. Searching only consumer brands systematically produces a false "can't be done" — consumer 120mm static pressure tops out around 7.6 mmH₂O, while industrial 92mm units comfortably hit 20-28. But confirm 4-pin PWM before ordering; a 2-wire unit has no speed control, so you've bought permanent full-speed noise.
  6. At a fixed noise budget, stack another slow fan rather than swapping in a fast one.
  7. Re-measure after every change. Don't trust extrapolation. Mine was optimistic by a third, and optimistic in the flattering direction.

One last thing: that scrap of paper sealing the gap — I've been meaning to replace it with foil tape. It's still paper.