Back-of-the-Envelope Estimation for LLM Systems
The 9-step framework ends with scaling, and every real design discussion reaches the same questions there: how many GPUs, how fast will it feel, and what will it cost? You can answer them to within a factor of two in a few minutes, before writing any code, from four numbers: how many tokens the system handles, how big the model is, how much memory a GPU has, and how fast that memory is. This page builds the estimate one piece at a time and ends with a calculator you can run.
Think of a GPU as a kitchen with a small counter and a fast cook. The model's weights are the recipe book, and they take up most of the counter. Every customer's half-finished order (the conversation so far) also needs counter space. The cook can't start the next step of any order until they've read the whole recipe book again, so how fast the cook can read, not how fast they chop, sets the pace.
Estimating an LLM system is working out how many orders fit on the counter, how long each step takes, and how many kitchens you need for the dinner rush.
1. Start from tokens
Everything in an LLM system is priced and limited in tokens, so the first step is turning the product's traffic into tokens per second.
Take a support assistant with 200,000 requests a day. Each request sends a 2,000-token prompt (instructions, retrieved documents and the conversation) and gets back a 300-token answer. Traffic isn't flat, so plan for a peak hour about three times busier than the daily average:
Input and output tokens are kept separate because they cost different amounts of work, for reasons that come up in sections 4 and 5. Here the system reads about 14,000 prompt tokens and writes about 2,000 output tokens per second at peak.
Limit: the averages hide the tail. A few users with 30,000-token documents can need more memory than hundreds of ordinary requests, so check the largest request you'll accept as well as the typical one.
2. Memory, part one: the weights
A model's weights must sit in GPU memory. Their size is the parameter count times the bytes per parameter:
| Precision | Bytes per parameter | Qwen2.5-72B (72.7B parameters) | Qwen2.5-7B (7.6B) |
|---|---|---|---|
| BF16 | 2 | 145 GB | 15 GB |
| FP8 | 1 | 73 GB | 8 GB |
| 4-bit | 0.5 | 36 GB | 4 GB |
An H100 GPU has 80 GB of memory. After the serving framework's own overhead, plan on using about 90% of it, so 72 GB per GPU. The 72B model in BF16 needs 145 GB, which is more than two GPUs' usable 144 GB, so in BF16 it needs four GPUs. In FP8 it fits on two, with room to spare. That is why quantization is usually the first thing a serving team reaches for: halving the bytes halves the hardware for the weights.
Limit: fitting the weights is not enough. Whatever memory is left decides how many users the GPUs can serve at once, which is the next step.
3. Memory, part two: the KV cache
While generating, a transformer keeps the keys and values of every earlier token, in every layer, so it doesn't recompute them. That store is the KV cache, and it grows with every token of every active conversation. Per token it takes:
The 2 is one key and one value. From the published model configurations, in BF16:
- Qwen2.5-72B: bytes, which is 320 KiB per token.
- Qwen2.5-7B: bytes, which is 56 KiB per token.
A single 2,300-token conversation on the 72B model therefore holds about 0.75 GB of KV cache. Whatever memory the weights leave free, divided by that, is how many conversations can be in progress at once: the batch size.
Both models use grouped-query attention, which shares each key-value head among several query heads. The 72B model has 64 query heads but only 8 KV heads, so its cache is 8 times smaller than it would otherwise be. Attention and Transformers explains the mechanism.
Limit: this assumes every slot is used for a full-length conversation. Serving engines such as vLLM allocate the cache in small pages as conversations grow, so real batches are often larger than this worst case.
4. Speed: decoding is limited by memory bandwidth
A model writes its answer one token at a time. For each new token, the GPU has to read all of the weights from memory once, plus the KV cache of every conversation in the batch, and do comparatively little arithmetic with each byte. So the time per step is set by memory bandwidth, not by compute:
An H100 reads 3.35 TB/s. For the 72B model in FP8 on two GPUs (6.7 TB/s together), a batch of one gives
That's the fastest a single user can get. Batching is where the throughput comes from: one pass over the weights produces a token for every conversation in the batch, so a batch of 94 produces 94 tokens for not much more than the cost of one. Each user then gets fewer tokens per second, because the step also reads all 94 KV caches, but the system as a whole produces far more.
There is a neat consequence. When the batch fills all the free memory, each step reads essentially the GPU's whole usable memory, about 72 GB per GPU, so the step takes about ms whatever the model is. A fully loaded H100 serving one stream per conversation gives each user roughly 47 tokens per second, for a 7B model and a 72B model alike. The model size decides how many users fit, not how fast each one goes at full load.
Limit: this is a ceiling. Real kernels reach perhaps 60 to 80% of peak bandwidth, and the serving engine rarely runs exactly full, so expect measured numbers somewhat below these.
5. Prefill: reading the prompt is limited by compute
Before the first output token, the model processes the whole prompt in one pass, the prefill. All 2,000 prompt tokens go through the weights together, so the weights are read once for many tokens, and arithmetic becomes the limit instead of memory. A forward pass costs about 2 FLOPs per parameter per token:
An H100 does 989 TFLOP/s in dense BF16 at peak. Assuming a realistic 50% of that, two GPUs take about 0.29 seconds. That time is most of the time to first token, which is what users feel as "it's thinking".
This difference between the two phases is why serving systems treat them differently. Chunked prefill splits long prompts so they don't stall everyone's decoding, and some deployments run prefill and decode on separate GPUs. LLM Inference Optimization covers both.
Limit: long prompts change the picture. Attention costs grow with the square of the prompt length, so at tens of thousands of tokens the 2-FLOPs-per-parameter rule underestimates prefill time.
6. Putting it together
Here is the whole estimate as code. It uses the H100 figures above, the model shapes from the published Qwen2.5 configurations, and the support-assistant traffic from section 1.
Running it prints:
Reading the result:
- The 72B model fits the peak on two GPUs in FP8, since 4,387 tokens/s is about twice the 2,083 needed. In production you'd still run at least two replicas, four GPUs, so that one failure or deployment doesn't take the service down.
- At ten times the traffic, 20,833 output tokens/s, the same setup needs , so 5 replicas and 10 GPUs. Capacity scales linearly with traffic, which is what makes this kind of estimate useful.
- The 7B model is about ten times cheaper per token. If evaluation shows it answers well enough, switching to it saves more than any serving trick. That's the case for model routing: send easy requests to the small model.
- The cost line assumes full load. GPUs bill by the hour whether busy or idle. At 30% average utilisation, a common figure for traffic with daily peaks, divide by 0.3: about $1.05 per million output tokens for the 72B setup.
7. Where estimates go wrong
- Long-tail prompts. A few very long requests take a large share of memory. Estimate with the 95th-percentile prompt, not the average, and cap the maximum.
- Output length is a guess. Reasoning models can write thousands of hidden reasoning tokens before the visible answer. Measure output tokens on real traffic; they drive decode cost directly.
- Utilisation, not peak. Hardware peaks are never reached in practice. Using 60 to 80% of bandwidth and 40 to 60% of compute keeps the estimate honest.
- Prompt caching changes the input side. When requests share a long system prompt, the serving engine can reuse its cached keys and values, and much of the prefill disappears. Count it only once you've confirmed the prefix is stable.
- Latency targets cap the batch. If the product needs 80 tokens per second per user, you can't fill the GPU to the 47-tokens-per-second batch. Pick the batch size from the latency target first, then compute the throughput.
8. When not to rely on this
| Situation | Do this instead |
|---|---|
| Choosing between two serving engines or GPU types | Benchmark both on your own prompts. Engines differ in kernels, batching and caching by more than these formulas capture |
| Mixture-of-experts models | Use the active parameters for decode speed but the total parameters for memory; the simple formulas assume a dense model |
| Very long contexts (32K+ tokens) | Add attention cost to prefill, and check KV-cache memory per conversation first: it can exceed the weights |
| Committing to a hardware purchase | Treat this as the first pass, then load-test a pilot at realistic traffic before buying |
Remember
| Quantity | Rule of thumb |
|---|---|
| Weights | parameters × bytes per parameter (2 for BF16, 1 for FP8) |
| KV cache per token | 2 × layers × KV heads × head dim × bytes |
| Batch size | free memory ÷ KV cache per conversation |
| Decode step time | bytes read per step ÷ memory bandwidth |
| Speed per user at full load | about usable memory ÷ bandwidth per step, roughly 47 tokens/s on an H100 |
| Prefill time | 2 × parameters × prompt tokens ÷ (FLOP/s × utilisation) |
| Cost per token | GPU-hours ÷ tokens produced, at your real utilisation |
Next: LLM Inference Optimization for the techniques that move these numbers, and AI Cost Engineering for routing and caching decisions built on them.
Sources
- Qwen, model configurations for Qwen2.5-72B-Instruct and Qwen2.5-7B-Instruct
- NVIDIA, H100 Tensor Core GPU specifications (80 GB HBM3, 3.35 TB/s, 989 dense BF16 TFLOP/s for the SXM version)
- Kwon et al., Efficient Memory Management for Large Language Model Serving with PagedAttention (vLLM, 2023)
- Amit Shekhar, AI System Design (Apache-2.0), whose topic list this page's coverage was checked against