Prefill Heats the House, Decode Doesn't

Cartoon: a cutaway of a house. Upstairs, a woman reads comfortably at 72°F. Downstairs in the basement, a sweating man sits at 85°F beside an RTX 5090 rig whose two panels read "570W PREFILL" with a flame icon and "277W DECODE" with a snowflake, while heat rises through the floor. Caption: "It turns out the real winter breakthrough wasn't the AI inference, but the 570-watt construction takeoff prefill heating system."

Part of the space heater series — Friday Morning Space Heaters, the breakeven posts, Does AI Agree With Itself? — and a follow-on to Qwen3.8-27B on Three Boxes.

Back in January I ended a post about quantization with a throwaway line: “These NVIDIA space heaters have been great this winter, but I’m beginning to wonder how they’re going to work out in the spring. Oh well, a problem for a few months from now.”

It is now the middle of August. It is a few months from now.

The answer, which I could have gotten any time since May by walking down the stairs with a thermometer, is that the basement has been sitting at 80°F and touching 85°F on heavy LLM days. Not dangerous. But it’s the room the whole lab lives in, and I spent four months not measuring it, because in January the heat was the feature.

TL;DR

The basement has no HVAC zone of its own. The thermostat that governs it reads a sensor one floor up, so GPU heat is never counted where it’s made — it’s 80°F down there right now.

Measuring that turned up something better. On an idle RTX 5090, sustained prefill pulls 570W, pinned against the card’s 575W limit. Decode on the same card and model pulls 277W — under half, though both report 99% “utilization.” Batching decode four ways only reached 315W.

The wrinkle is architectural: a sparse MoE with 3B active parameters is the weakest heat load in the building, while prefill lights up the whole card regardless.

So prefill-heavy work is winter work, and TeraContext spec takeoff — 100k-token windows, thousands of calls, short answers — is the best furnace we own. It’s also why the rack isn’t in Ashburn: at 109 W/U my density is low enough that colo bills me for floor space, not power — $900 to $1,100 a month against ~$50 metered at 15% duty.

The room has no vote

Here’s the actual defect, and it isn’t the GPUs.

The basement doesn’t have its own HVAC zone. It’s conditioned as an afterthought off the first-floor zone, and that zone’s thermostat reads a sensor in a hallway one floor up. I can put 2,400W of Blackwell into that room and the thermostat’s opinion of the house does not change by a tenth of a degree. It’s a furnace with no feedback path.

In winter that’s tolerable, and it’s most of why the January posts worked. Heat leaks up through the floor into the family room, which is where the breakeven post described the rack as “positioned strategically under the family room.” That was not strategy. That’s where the electrical panel is. But it worked: my wife got a warm family room, I got benchmark data, and the oil company got nothing.

In summer the same physics runs backward. The heat still leaks upstairs, where the first-floor zone fights it with air conditioning using a sensor that can’t see the source, while the basement climbs because nothing in the control system is accountable for it. Two seasons, one missing sensor, opposite outcomes.

What the card actually draws

One card was quiet this afternoon, so I sampled power and temperature while driving it through different load shapes. I’ve been benchmarking this rack for eight months and had somehow never once written down watts.

There are two 5090s in the basement and they aren’t the same card. One is a 600W board inside the Ryzen box. The other — the one I measured — is a 575W card in its own enclosure, attached to a host rather than installed in it, with its limit fixed at 575W floor and ceiling both. Everything else in the room was parked at 0%, so nothing is contaminating the numbers.

Load GPU power % of 575W limit GPU temp
Idle (model resident) 9W 2% 32°C
Decode, 1 stream 277W 48% 43°C
Decode, 4 streams 315W 55% 47°C
Unique 100k prefill 570W 99% 68°C

That last row is the one to sit with. Prefill didn’t come near the card’s rating, it came within five watts of it, peaking at 572W against a 575W wall. During a long prefill this card isn’t choosing how much power to draw — it’s being held back by the limiter. Decode never got past half.

That’s 2.06× the power of decode on the same card running the same weights: a 293W spread, about a slow cooker on high, hiding behind two rows that both report 99% utilization. That utilization figure is close to useless here. It reports whether a kernel is resident, not whether the transistors are doing anything expensive.

The mechanism is the same one that made the three-boxes post end up being about prefill. Decode emits one token at a time and spends its life waiting on memory — stream the weights, do a trivial amount of arithmetic, repeat. It’s bandwidth-bound, and a bandwidth-bound kernel leaves the tensor cores standing around drawing almost nothing. Prefill eats the entire prompt as one enormous matrix multiply. That’s FLOPS, that’s the tensor cores lit up, and that’s the only workload I’ve measured that makes a 575W card actually ask for 575W.

The corollary I hadn’t considered until I had both rows side by side: you cannot heat a house with chat. Every evening I’ve described as “firing up the space heaters” while asking a model who caught the Immaculate Reception, I was running the card at 48% of nameplate and calling it heating.

Sparse models make bad furnaces

The model on that card is a 35B mixture-of-experts with roughly 3B active parameters, and that detail turns out to matter more than I expected.

MoE decode is the least thermally productive thing a GPU can do. The router picks a couple of experts, so a given token touches only a small slice of the weights — less memory traffic than a dense model of the same nominal size, and still no meaningful math. That’s exactly why it decodes so fast at 254 tok/s, which is wonderful for chat and useless for heating. Sparse activation is a computational bargain, and heating is the one application where you don’t want a bargain.

Prefill doesn’t get that discount. Push 100,000 tokens through at once and the batch is large enough that essentially every expert gets work. The sparsity that saves you on decode buys you nothing on ingest.

Which sets up a rule I like:

Dense models are better space heaters than sparse ones. Prefill is a better space heater than decode. And the two effects stack.

The dense 27B on the other box lands where that predicts: its decode sits meaningfully higher, because a dense model streams every weight for every token, while its prefill ends up in the same near-nameplate territory. That box was serving other traffic while I sampled it, so I’m treating those figures as directional and re-running them when it’s quiet. The ordering is solid; I don’t yet trust the third digit.

Batching is the other lever, and it’s a weak one. Four decode streams instead of one added just 38W. It should help, and it does — not enough to matter. You cannot batch your way to a warm house.

Watts are watts

A GPU is a resistive heater with a side effect. Essentially all the electrical energy going in comes out as heat in that room; the tokens are free. The conversion is arithmetic at 3.412 BTU/hr per watt.

Adding up the enforced limits, the two Blackwell boxes carry 1,775W of GPU nameplate — a 600W 5090, the 575W external 5090, a 300W PRO 6000 Max-Q, and a 300W 5070 Ti. Add CPUs, drives, and power supply losses and the room’s ceiling lands right around the 2,400W I’ve been quoting since January, which is a nicer coincidence than I deserve:

Load Electrical Heat output Cost at $0.15/kWh
One 5090, decode 277W ~945 BTU/hr $1.00/day
One 5090, prefill 570W ~1,945 BTU/hr $2.05/day
Whole rack, working ~2,400W ~8,200 BTU/hr $8.64/day
Hardware store space heater 1,500W ~5,120 BTU/hr $5.40/day

The rack at full tilt is about a 1.6× space heater, which retroactively justifies eight months of calling it one. That same rack on decode-only work is more like 0.8×.

I want to be careful about the efficiency claim, because it’s the part people get wrong in both directions — including me, on the first draft of this post.

A GPU is electric resistance heat, and at $0.15/kWh that’s about $44 per million BTU. Against the heat pumps this is a rout: they deliver the same BTU for roughly $15 when they’re behaving, and around $22 when it’s cold enough that the coefficient of performance falls off. No argument there.

Oil is where I was wrong. I’d been carrying $3.50 a gallon around in my head, which lands oil in the high $20s and makes the GPUs look like three times the cost of running the furnace. Oil is not $3.50 anymore. It’s been $4.30–$4.50 a gallon in Virginia this year. A gallon of No. 2 holds 138,500 BTU, and a boiler at 86% AFUE delivers about 119,000 of them:

Heat source Cost per million BTU
Heat pump, COP 3 ~$15
Heat pump in the cold, COP 2 ~$22
Oil, $4.40/gal at 86% AFUE ~$37
GPUs (electric resistance) ~$44
Oil at its March 2026 peak, $5.54/gal ~$47

So the GPUs are about 15–20% worse than the oil burner, not three times worse. And during the March spike, oil crossed $46 per million BTU and the space heaters were briefly the cheaper heat in the house, which is not a sentence I expected to write when I started this post. Strictly as a heater the GPUs still lose — but only to the heat pumps by much, and to oil by a margin thin enough to disappear on a bad week for crude.

That comparison is a trap, though, and it’s the same trap as January. I’m not buying heat. I’m buying compute I was going to buy anyway, and the heat falls out for free — marginal cost zero, because the electricity was already committed to the thing I actually wanted. The only real decision is when to spend it, which is where a 293W gap turns into a plan.

Prefill is winter work

If prefill converts twice as much electricity into heat as decode, then the workload mix isn’t only a throughput question. It’s a seasonal one.

And the most prefill-heavy thing in the building is the thing we’re actually trying to ship. TeraContext takes a commercial RFP — a 500 to 2,000 page specification book plus the drawing set — classifies pages against a work breakdown structure, and bundles them into trade packages with a citation back to the paragraph it used. That means 100,000+ token windows, thousands of calls per job, and short outputs. As the three-boxes post worked out, roughly 95% of one of those turns is prefill: the model spends its time reading Division 03 and almost no time talking.

So construction spec takeoff is, thermally, the best workload we have. It’s the one job that holds a card at the power limit for hours instead of dropping to 277W between tokens, and it produces something a client is paying for.

The scheduling rule for this winter, which is the actual conclusion here:

  • Batch prefill-heavy work into the cold months and the cold hours. Spec takeoff, corpus ingest, embedding and reranking backfills, long-context evals. Anything where the prompt is the work. Queue it overnight in January and the family room is warm by morning.
  • Push decode-heavy work to summer. Chat, coding assistance, the debate platform, short-answer benchmarks. Same tokens either way, half the heat, in a room that’s already at 80°F.
  • Prefer the dense model in winter and the sparse one in summer, when quality permits. I did not expect the model zoo to acquire a seasonal dimension.
  • Long-context sweeps are a December luxury. A 176k-token window is the hottest thing I can run. That’s not an August experiment.

None of this changes a benchmark number. It just means the calendar gets a say in queue order, which it never had before.

Thirty minutes from the data center capital of the world

Which raises the obvious question. I live near Ashburn, Virginia. There is more data center capacity within a half-hour drive of my house than in most countries. Why is any of this in my basement?

Because of how colocation is priced, and because my deployment is precisely the shape colo prices badly.

Start with power. GPU rack rental varies, but all in you’re looking at roughly $300 per kW per month billed on peak demand. My rack peaks at 2.4 kW, so that’s $720 a month whether I use it or not.

Except $720 is the floor, not the bill. Providers charge on space or power, whichever is greater, and 2.4 kW simply isn’t much power. My gear needs about 22U — and consumer tower cases don’t rack, so each one eats four or five U sitting on a shelf. Spread 2.4 kW across 22U and the density is 109 watts per U, in a market where cabinets are routinely provisioned at 5 to 10 kW and up. I’d be renting rack space I have no way to fill with power, which means the space charge binds, not the power charge. Half-cabinet space in Ashburn runs about $861 to $1,100 a month right now, and a full 48U cabinet is $1,500 to $1,875. Cross-connects, bandwidth, and remote hands stack on top.

So the honest colo number for my footprint is $900 to $1,100 a month, not $720. Low density is the trap: below roughly 3 kW a cabinet you stop buying electricity and start buying floor.

Meanwhile my workload isn’t steady. It’s bursty and irregular, maybe 15% duty cycle across a month — a weekend of benchmarks, a takeoff run, then days where the cards idle at 9W. Metered at $0.15/kWh that’s about $50 a month. Colo prices power like a subscription on the peak; the utility prices it like a meter on the consumption.

  Monthly Basis
Colocation, ~22U at 2.4 kW $900–$1,100 greater of space or power
— if billed on power alone $720 2.4 kW × $300/kW
My basement, ~15% duty ~$50 metered consumption

That’s roughly $11,000 a year, which is a couple of GPUs. And none of it includes the reset button: when something wedges I either pay a tech for remote hands or drive thirty minutes each way. Downstairs is thirty seconds. The rest of what colo sells, I already have — redundant internet, redundant power with UPS, and Cloudflare in front as the CDN.

Then there’s the part this whole post is about. Four months of the year the waste heat is worth something. No colocation contract will ever credit me for that. In Ashburn I’d be paying a premium to have someone else’s chillers throw away the exact BTUs I want in my family room in January.

None of which survives scale, and the reason isn’t money. Run it flat out at 100% duty cycle and the basement is still cheaper — about $259 a month against $900-plus. Home electricity wins on the meter at every duty cycle I can model. Colo doesn’t beat my basement on price and it never will.

What beats my basement is the ability to get rid of heat, and that’s the wall I’m actually up against. The room is out of thermal headroom. Put the current rack in cooling terms: 2.4 kW is 8,200 BTU/hr, which is 0.68 tons of heat rejection. The dedicated cooling capacity currently serving that room is zero tons. That gap is the entire reason it sat at 85°F all summer, and it’s why the honest answer to “can you add another card” is no.

And to be clear about which constraint is actually binding, it isn’t the panel. That 2.4 kW is 20 amps spread across three 15-amp circuits. Derated to the 80% you’re allowed to hold continuously, those three circuits carry 4,320W, so I’m running at about 56% of my electrical capacity with roughly 1,900W of headroom — call it another big card and its host. I could plug more hardware in tomorrow and the breakers would be perfectly happy. The room would cook. The wiring has room and the air does not, and that’s the whole problem in one sentence.

The arithmetic past that is unforgiving. A 5 kW rack wants about 1.4 tons of dedicated cooling; 10 kW wants nearly 3 tons — a real mechanical system, ducted and drained and condensate-pumped. At that point the panel does become an issue too, since 10 kW is 83 amps and a subpanel. That is not a shopping trip. It’s a major construction project on a house that was never meant to be a data hall, and I’d pay for it twice: once to build it, then again every July to run it.

And once the answer to “how do we get more compute” is “renovate the house,” the answer is really lease commercial space. Not a colocation rack — paying for floor space I can’t fill with power is still terrible value for a bursty load, and I already own the redundant power, redundant internet, and CDN that colo is mostly selling. Commercial space is different: I’d be buying square footage with cooling engineered for the load and power still on a meter, and a loading dock instead of a basement stairwell. On which point — try getting a full 42U cabinet, call it seven feet on casters, down a straight run of basement stairs. There’s no corner to snag on. It’s just that tilting seven feet of steel back onto a staircase runs the top of it into the ceiling, and once it’s leaning it very much wants to get to the bottom faster than you do. The workaround is building the rack in place from parts, which is its own kind of penance. That’s a different blog post.

So the honest version: the basement wins right now precisely because the load is irregular and the heat has somewhere useful to go. Both of those stop being true the moment this is production. The thing that makes it a good furnace is the same thing that caps its size — and the space heater era has an expiration date measured in tons of cooling, not dollars per month.

What has to happen before November

1. Put a sensor in the basement. This is the whole problem. I already run dcgm-exporter, Prometheus, and Grafana. I checked what’s actually in there: GPU die temperature, GPU memory temperature, motherboard hwmon, thermal zones. There is no metric for the room. I can tell you a 5090 hit 68°C during a 100k-token prefill at two-second resolution, and the best I have for the space that card is heating is “80, I think.”

2. Get the heat where the vote is. A real zone for the basement, or a transfer path — a return near the rack, a boosted duct into the first-floor return. In winter I want that air upstairs and in summer I want it gone, which is the same duct with opposite intent. The external 5090 is the interesting case: a standalone enclosure putting 570W into one concentrated spot rather than burying it in a chassis, which makes it the easiest heat source in the room to duct on purpose.

3. Wire the furnace interlock. In January my wife asked me to set up the oil furnace to come on when the heat pumps can’t keep up. I said I’d look into it tomorrow. That was seven months ago. Once the room is instrumented, the interesting version becomes possible: let GPU heat count as the first stage. Heat pumps, then GPUs, then oil.

4. Set a summer ceiling. 85°F is fine for silicon and less fine for the drives, the power supplies, and the UPS batteries. Past a threshold, the long-context sweeps wait for October.

So

The joke for eight months has been that these are space heaters that happen to do inference. The measurement says something sharper: they’re space heaters with a high setting and a low setting, the high setting is the one that reads thousand-page specification books, and I have been running the low setting on purpose every time I sat down to chat with them.

Last night I told my wife the basement had been running 85 degrees all summer.

“I know,” she said. “That’s why I stopped putting the laundry down there in July.”

She had known since roughly the first week of June, and had not mentioned it, on the theory that I would eventually measure something and find out on my own. Which is exactly what happened.

“Good news is it should be great in January.”

“Did you ever set up the furnace?”

“…I’ll look into it tomorrow.”


Power and thermal figures sampled August 17, 2026 on the externally-enclosed RTX 5090 — 575W enforced limit, default and maximum both — running Qwen3.6-35B-A3B-NVFP4 under vLLM at 262k context, FP8 KV cache, vision enabled, with every other GPU in the room at 0%. nvidia-smi polled at 2-second intervals; the first quarter of each load window is discarded as ramp-up. Decode is streamed with ignore_eos; prefill uses fresh random-word prompts at ~98k tokens to defeat the prefix cache. Dense-model comparisons are directional only — that box was serving other traffic at 99% utilization while I sampled it, and will be re-run when it’s quiet. Heat conversion at 3.412 BTU/hr per watt; electricity at $0.15/kWh. Basement temperature is a handheld reading, which is the entire point of item 1.