UnitStack because every unit in your stack matters

Decide your AI bill,
layer by layer

We connect every layer of your AI stack — so a change in one shows up in the cost of all the others, and you know which layer to change.

Start here

What are you trying to decide?

The trace

One prompt, seven units

A prompt does not stop at the model. It becomes tokens, and tokens become GPU-seconds, and GPU-seconds become electricity somebody is paying for and cooling somebody had to provision. Every layer on that path measures itself in a unit the layer above cannot read — so the path exists, but nobody can see along it.

The conversions — what nobody else publishesprompt → €, kgCO₂e
prompt layoutcache hit rate
cache hit rateprefill tokens
prefill tokensGPU-seconds
GPU-secondsGPU-hours ÷ utilisation ÷ (1 − goodput loss)
GPU-hourskWh × PUE
kWh€ and kgCO₂e
Prompt & applicationcompleted tasks, € / outcome
Agents & orchestrationtool calls, agent-steps, tracesLangChain · LlamaIndex · CrewAI · Orq.ai · Temporal · Langfuse
Model & servingtokens/sec, TTFT, cache hit ratevLLM · SGLang · TensorRT-LLM · Dynamo · LMCache · OpenAI · Anthropic · Meta · Mistral · DeepSeek · Qwen
Cluster & schedulingutilisation %, goodput %Slurm · Kubernetes · Run:ai · SkyPilot
Capacity & fabric$/GPU-hour, GB/s, µsAWS · Azure · Google Cloud · Oracle · CoreWeave · Nebius · Crusoe · NVIDIA · Arista · Broadcom · VAST · WEKA · DDN
Silicon & systemsGPU count, watts, HBM GBNVIDIA · AMD · Intel · HPE · Dell · Supermicro · Lenovo
Facility & powerMW, PUE, €/kWh, kgCO₂eEquinix · Digital Realty · Vantage · Vertiv · Schneider Electric · Eaton
The human problem

Why do two good engineers produce a bad system?

The agent engineer adds a reflection step because it measurably improves answer quality. The serving engineer raises the batch size because it measurably improves throughput. The facility engineer provisions for peak because that is the job.

Every one of those decisions is correct in its own units. The composition is wasteful, and no one is at fault, because no layer can see what its choice costs the layer below.

They do not need a meeting. They need a shared artefact. The agent engineer does not have to learn thermodynamics — they need to see that a prompt ordering added 40 MWh a year. The facility engineer does not have to learn about attention — they need to see that half their load is a software decision someone could undo in an afternoon.

No single layer holds the answer. It lives in the trail that runs through all of them — which is exactly why nobody has been looking at it.

Built · measured, reproducible

Should you host your AI agents yourself?

Multi-agent workloads reprocess the same context once per agent. Removing that duplication means reusing key-value state across agents, and that only works if you operate the inference server — no frontier API exposes it, at any price.

We measured what that is worth, where it stops working, and where renting stops beating owning. At one node with 24 shared calls the cache hit rate is 96%. Put the same workload on 150 nodes with ordinary load balancing and it falls to 7%, because a request only hits a warm cache if it lands on the node already holding the prefix.

derivation — balls in binscold(N, K)
cold(N, K) = N · (1 − (1 − 1/N)^K)
hit_rate   = 1 − cold(N, K) / K

N =   1, K = 24  →   1 cold prefill  →  96% hit rate
N = 150, K = 24  →  22 cold prefills →   7% hit rate

That result does not depend on your hardware, your model, or your framework. It follows from routing behaviour alone, which is why it is the one number here that survives extrapolation.

Building · open problem named

The join key, and the problem we haven't solved

Tracing a prompt downwards needs one thing that does not currently exist: a way to attribute a span to a watt. Above the process boundary there are traces. Below it there are throughput counters, per-GPU power draw, and rack-level kilowatts. Nothing joins them.

Some of that is engineering. Some of it is not.

Under continuous batching, forty requests share a single forward pass. There is no physical fact about how many joules belong to request seventeen. You have to choose an allocation rule — by tokens, by sequence length, by KV footprint, by marginal cost — and different rules give different answers, all of them defensible.

That is the interesting problem, not an inconvenience around the edge of one. It is the same question the cache work raised: who owns the cost of a resource whose whole value comes from being shared? We would rather publish the rule, the alternatives, and the disagreement than quietly pick one and print a number.

Directly measuredtokens, GPU-seconds, cache hit rate, per-GPU watts (DCGM, sub-second)
Attributable with workwhich request consumed which GPU-seconds
Modelled, never measuredPUE, cooling share, network and storage share, idle amortisation
Vision · where this goes

Where this goes

The end state is a report, not a dashboard. You are running 450 agents. Here is where the energy went, layer by layer. Three changes account for 60% of the waste, ranked by how hard they are to make.

Get that right and the two ends of the stack can finally negotiate. Capacity planning stops being a guess about growth and becomes arithmetic on an architecture. Efficiency stops being a sustainability report written after the fact and becomes a design constraint someone can act on while there is still time to act.

We are not there. We have traced one slice to the bottom and it already changed what we would recommend.

About

Who is behind this

Add a photo
(a face is worth more here than another paragraph)

«Your name». «One line on what you do and where — the shortest true version.»

«Two or three sentences on why you are the person to ask. Concrete credentials beat adjectives: what you have built, what you have measured, what you have access to.»

This section is deliberately left for you to complete — an invented anecdote on a page selling measured honesty is a very expensive lie. See the founder's note below, which you already wrote.

In my own words

Why I built this

UnitStack started as a question nobody could answer for me. If I architect my agentic system this way instead of that way, what does that do to the power supply and the costs in the data centre?

Not because the answer is unknowable. Because the question crosses too many boundaries. AI engineers and infrastructure engineers are working on the same problem from opposite ends of the building, and they do not share a language.

So I want to follow the whole trail — from the power supply in the data centre all the way up to one person sending one prompt. If you can see the entire path, you can make intelligent decisions about what each unit at each layer should be doing.

Take 450 agents running on a given cluster. Right now the engineer who designed those agents has no idea what they cost downstairs. With the trail in front of them it would be obvious: that is a lot of compute, that is a lot of memory, and if you restructure it like this you recover x in efficiency and y in performance.

That is what this is for. Not benchmarking for its own sake. Architecting across layers, and getting the people who own those layers into the same conversation.

Advisory

Deciding on sovereign AI infrastructure?

Most teams weighing whether to bring inference in-house are working from vendor TCO sheets and a spreadsheet of token prices. Neither accounts for duplicated prefill, routing behaviour at fleet scale, goodput loss on hardware you own, or the energy any of it draws.

I trace real workloads end to end and deliver the report: where the cost went, which changes recover the most, and what the decision looks like on your utilisation and your regulatory constraints. Sometimes the answer is that on-premise does not pay. That answer is worth having early.

No vendor pays to be measured, to be measured favourably, or to be left out. The benchmarks are funded by consulting, not by the companies they evaluate.

Model  /  KV Cache Sharing

KV cache sharing across a 150-GPU fleet

Deployment-tier model — every value is an assumption until you replace it with a measurement. Flip Role instructions first and watch cache, cost and energy per year move together: that is the trace, in one control.

01

What happens to cache hit rate at 150 GPUs?

Prefix-aware routing Random load balancing
02

Cost per 1,000 tasks vs fleet size

Frontier is token-priced; the rest are hardware-priced. Self-hosted tiers hold cost flat because routing is yours to control. Y-axis is logarithmic.

03

When does owning beat renting?

04

Summary

TierRouting controlHit rateCost / 1k tasks

Throughput, capex, rates and workload shape are placeholders. Replace each with a measured value before any of these curves is quotable. The hit-rate curve is the exception — it follows from routing behaviour rather than from hardware.

Benchmark · Open method

Why does multi-agent inference cost so much more than it should?

The coordination tax turns out to be a cache miss. And at 150 GPUs it comes back.

Register

The derivation in this piece is arithmetic and holds regardless of hardware. The throughput figures are third-party measurements from InferenceX. The routing validation is not done yet. Nothing here is a measurement from my own cluster.

The short answer

Ten agents reading the same case file prefill it ten times. On a metered API you pay for all ten and none of it looks like waste, because it is billed as input tokens, which is exactly what it is.

Removing that duplication means reusing key-value state across agents. That only works if you operate the inference server. No frontier API exposes it.

And here is the part I did not expect. The fix works beautifully on one node and returns almost nothing at 150, unless routing knows which node already holds your prefix. At one node the cache hit rate is 96%. At 150 nodes with ordinary load balancing it is 7%. Same code, same model, same hardware.

That number is not a measurement. It falls out of arithmetic, which is why I trust it more than most of the numbers in this piece.

Where does the duplication come from?

Model APIs have no memory. Every call carries the whole history, so a twenty-step agent sends its opening context twenty times. Put ten agents on one document and you have paid to read it a hundred times.

The provider caches help — when they can. Prefix caching only resumes if the new request is byte-identical up to the cached point. One changed character and everything after it is recomputed at full price.

Agents differ by construction. That is what makes them different agents. So their prefixes diverge, and how much they diverge depends entirely on where in the prompt the divergence starts.

Which deployment tiers can actually fix it?

The line that matters is not cloud versus on-premise. It is tenant versus operator.

Frontier APIManagedRented GPUOwned
Exact token sequenceNoUsually noYesYes
Cross-agent KV sharingNoNoYesYes
Cache offload to CPU/NVMeNoNoYesYes
Routing controlNoneNoneYoursYours
Idle capacityNoneProvisionedStoppableBackfillable

Rented GPU gives you every cache capability that owned hardware does. Renting a bare instance and running your own vLLM or SGLang puts you on the operator side of that line, in someone else's building.

On-premise adds three separate things: utilisation economics, fabric choice, and data residency. None of them is a caching argument. Keep them apart. An architect who hears "you need on-prem for KV caching" will correctly reject it, and you lose the room.

Does prompt order really matter more than hardware?

Sometimes, yes. This is the cheapest finding in the whole piece.

If role instructions sit at the top of the prompt, prefixes diverge at position zero and no cache hits anywhere — including on frontier APIs, where it would otherwise have worked. Move the shared corpus to the front and role instructions to the end, and a large fraction of the benefit comes back without changing a single thing about your infrastructure.

Most agent frameworks put role instructions first. It reads more naturally. It costs a fortune.

Flip the role instructions first switch in the model and watch every tier collapse at once. That cliff is free to fix and almost nobody has.

What happens to cache hit rate at 150 GPUs?

This is the section that changed how I think about the whole problem.

A request only hits a warm cache if it lands on the node that already holds the prefix. With random load balancing over N nodes and K calls sharing that prefix, the number of distinct nodes touched — and therefore the number of cold prefills — is a balls-in-bins expectation:

derivation — balls in binscold(N, K)
cold(N, K) = N · (1 − (1 − 1/N)^K)
hit_rate   = 1 − cold(N, K) / K

N =   1, K = 24  →   1 cold prefill   →  96% hit rate
N =  16, K = 24  →  ~13 cold prefills →  46% hit rate
N = 150, K = 24  →  ~22 cold prefills →   7% hit rate

No hardware term appears anywhere in that expression. It does not care which GPU you bought, which model you serve, or which framework you run. It is a property of routing.

Which means the mechanism everyone is optimising at single-node scale quietly stops paying somewhere between sixteen and forty nodes, and the fix is not a better kernel. It is prefix affinity — pinning a task's calls to the pipeline that already holds its state.

What does the hardware actually do?

You need real throughput numbers to turn any of this into money. I used InferenceX, which publishes its data under Apache 2.0 — rare, and the reason I could build a public calculator on top of it at all.

Peak prefill throughput per GPU, DeepSeek-V4-Pro at 8192 in / 1024 out, best disaggregated configuration per platform:

PlatformPrefill tok/s/GPUDecode tok/s/GPU
GB30015,3783,843
GB20011,3801,423
B30010,4862,621
B2008,6211,078
MI355X7,747968

But the number that actually surprised me is not in that table. Across the whole dataset, median prefill throughput is 1,287 tok/s/GPU colocated and 6,025 disaggregated — roughly 4.7×. Separating prefill from decode is a larger lever than most of what I set out to measure.

It also collapses two questions into one. Disaggregated serving means KV state has to move from the prefill GPUs to the decode GPUs. So "where does the cache live" and "how do you route for affinity" stop being separate problems at fleet scale. They become a bandwidth problem, and the fabric becomes a hardware conversation rather than a software one.

Where does the electricity come in?

This is why the whole thing sits under UnitStack rather than standing alone.

Follow the chain down. Duplicated prefill becomes prefill tokens. Prefill tokens become GPU-seconds. GPU-seconds become GPU-hours once you divide by utilisation. And then:

conversionkWh
kWh = GPU-hours × kW per GPU × PUE

Which means the prompt-order switch two sections up is not only a billing decision. Reorder a prompt, and the annual megawatt-hours move. A software choice made in a config file lands on somebody's cooling plant, and neither person can currently see the other.

That conversion is one line of arithmetic and I have not seen anyone publish it against a real agent workload. It is the next thing I am building.

What this doesn't tell you

Four things, and I would rather say them than have you find them.

The goodput correction cuts against my own conclusion. GPUs fail, jobs restart, and some of the hours you paid for produce nothing. SemiAnalysis put total goodput loss between roughly 13.5% and 28.4% depending on provider tier. That loss is asymmetric: on a frontier API you do not pay for the provider's failures, and on hardware you own you pay for every one. It is a real argument against the case I am making, and any TCO model that leaves it out is selling something.

Sharing needs architectural identity. Same base model across agents. Specialise by system prompt or LoRA adapters, not by running different models — different weights mean different cache formats and the whole mechanism evaporates.

Gains concentrate in prefill-heavy work. Long shared context, short outputs. A long-generation workload is decode-bound and will barely notice any of this.

Nobody knows whose joules those are. Under continuous batching, forty requests share one forward pass. There is no physical fact about how many joules belong to request seventeen. You have to pick an allocation rule — by tokens, by sequence length, by KV footprint, by marginal cost — and different defensible rules give different answers. I would rather publish the rule and the disagreement than quietly pick one and print a number.

Metrics

MetricWhy it is here
Concurrent agents per GPUConverts directly to node count in a quote
Coordination taxThe duplicated work, made visible
Cache hit rateValidates the routing model
Cost per completed taskPrices the waste, split by fresh / cache-write / cache-read
Energy per completed taskConnects the architecture to the facility
Scaling efficiencyWhere affinity routing starts paying

Coordination tax was the name before I understood the mechanism. It turns out to be, quite literally, a cache miss.

Reproduce it

Every figure here should regenerate from the published configuration on your own hardware. Where a number is an assumption, the calculator takes yours instead of mine.

Results that only hold on the author's cluster are marketing.

Methods note

Hardware throughput data from InferenceX (SemiAnalysis), Apache 2.0, attribution required. Goodput loss ranges cited from ClusterMAX (SemiAnalysis); their methodology is theirs and linked rather than reproduced. Model pricing via the CloudPrice API, fetched 20 July 2026, 12:58 AM UTC.

One caveat for anyone else using the InferenceX interactivity export: the TTFT, TPOT, ITL and E2E Latency columns are labelled in milliseconds but the values appear to be in seconds. 1/TPOT reproduces the interactivity column exactly, and TTFT + OSL × TPOT reconciles with end-to-end latency — both only hold if the unit is seconds. I lost an evening to it. Worth checking against the current release before you rely on it either way.

Try it on your own numbers. The interactive model turns every assumption above into a control — including energy per year.