Most LLM latency problems come down to a handful of well-understood causes: reprocessing work that didn't need reprocessing, generating tokens one at a time when more could be produced per step, or running at a precision that costs more memory bandwidth than necessary. This guide covers seven proven techniques for inference optimization and llm performance, what each one actually fixes, and when it doesn't help. Where you reduce latency and where you just reduce cost are related but different questions, and this post is precise about which is which for each technique.
Key takeaways
⚡ First, identify what "slow" actually means
If users are waiting for the first word to appear, that's time to first token (TTFT), and it's dominated by prompt processing and queueing. If the first token arrives quickly but the rest of the answer trickles out, that's per-token generation speed, sometimes called inter-token latency (ITL) or measured as tokens per second (TPS). If everything slows down as traffic increases, the bottleneck is likely queueing or overall throughput rather than either of the above. Different techniques target different ones of these, so it's worth knowing which is actually the problem before picking a fix. See the packet.ai What Is TTFT guide for the full breakdown of this distinction.
KV caching is the foundational optimization nearly every serving engine relies on, and it's not optional so much as assumed. Without it, generating each new token would mean reprocessing the entire conversation from scratch through every layer of the model. With it, the model reuses the key and value tensors it already computed for earlier tokens and only computes the new ones, turning each step after the first into an incremental operation rather than a full recomputation.
This is the one technique on this list with essentially no downside; every production serving engine has it enabled by default. What it doesn't fix is memory growth: KV cache size scales with context length and concurrent requests, and at long context or high concurrency it can become the dominant memory cost on the GPU. For the full mechanism and why it matters at scale, see the packet.ai What Is KV Cache guide.
Prefix caching extends KV caching across requests rather than just within one. Worth being precise about the distinction, since the two are easy to conflate: KV caching avoids recomputing previously processed tokens within a single, ongoing request. Prefix caching reuses already-computed KV state across different requests that happen to share the same starting sequence, a system prompt, a few-shot example set, or a shared document. The first is about not repeating work inside one generation; the second is about not repeating work between separate generations.
This directly reduces time to first token for any workload with repeated context, which describes most production chatbots and agentic tools running behind a consistent system prompt. It doesn't help unique, one-off prompts with no shared prefix, and the benefit depends on how much of a typical request is actually shared versus unique. The packet.ai vLLM prefix caching guide covers exactly how it's implemented and what it saves in practice.
Continuous batching is fundamentally a throughput and concurrency optimization, one path to faster inference at the system level: it keeps a GPU serving new requests as they arrive rather than waiting for an entire batch of requests to finish together before starting the next one. Older batching approaches processed a fixed group of requests as a unit, so a batch full of short and long responses meant the whole batch waited on the slowest one. Continuous batching lets new requests join execution mid-stream as earlier ones complete, keeping the GPU's compute genuinely busy and inference throughput high.
Its effect on any single request's latency is more nuanced and depends heavily on workload and scheduling: it can help latency under concurrent load by avoiding the static-batch wait, but it isn't primarily a single-request latency technique the way prefix caching or speculative decoding are. For most production workloads serving multiple concurrent users, the throughput gain is worth it regardless. It's less relevant for a system serving one request at a time.
Quantization reduces the precision used to store a model's weights, most commonly from 16-bit formats like BF16 or FP16 down to 8-bit FP8. The mechanism is straightforward: fewer bits per parameter means less data the GPU needs to move through memory for every forward pass. Whether that translates into an actual speedup is conditional, not automatic, and depends on the hardware, the specific quantization format, kernel support, and whether the workload is genuinely memory-bound in the first place. On hardware with dedicated FP8 support, H100 and H200 deliver roughly double the TFLOPS at FP8 compared to BF16, but a workload that isn't memory-bound to begin with, or a quantization path lacking optimized fused kernels, may see far smaller gains or none at all.
The tradeoff is real, even if usually small for standard generation tasks: quantization can introduce a measurable accuracy cost, and it requires hardware support to pay off, FP8 specifically only accelerates on Hopper and Blackwell-generation GPUs, not older architectures like A100. It's also workload-dependent in ways worth checking rather than assuming: FP8 KV cache quantization, for instance, tends to help decode-heavy, memory-bound serving at long context, but has shown smaller or even negative throughput effects in prefill-heavy scenarios or without fused dequantization kernels. It's not something you bolt on casually; getting the calibration right and verifying the gain on your actual workload matters. For the full breakdown of formats, memory footprint, and which GPUs actually support which precision, see the packet.ai FP8 vs FP16 vs BF16 guide.
Speculative decoding restructures how tokens get generated rather than changing precision or caching behavior. A small, fast draft mechanism proposes several tokens ahead, and the full model verifies all of them in a single forward pass instead of generating one token per pass. When the draft's guesses are accepted, which happens often on predictable text like code or structured output, one expensive verification step produces several tokens of real progress instead of one.
The genuinely important detail: this doesn't change output quality. The verification step mathematically guarantees the same output distribution as standard generation would produce; it's a speed technique, not an approximation. The catch is that it depends heavily on how predictable your traffic actually is. High-acceptance workloads like code completion see large gains; open-ended creative generation at high temperature sees much less, and past a certain point the overhead of drafting can make things slower rather than faster. The packet.ai speculative decoding guide covers the mechanism, current approaches, and where the gains actually show up.
The most straightforward llm speed lever is often skipped: use a smaller model when the task doesn't need a larger one. A smaller model has fewer parameters to move through memory per token, which directly means faster generation, independent of any of the other techniques on this list. Every optimize llm technique above still applies to a smaller model and often has more headroom to work with, since a smaller model's memory footprint leaves more room for KV cache and batching.
This isn't a universal answer since task quality genuinely does depend on model capability for some workloads, but it's worth actually testing rather than reflexively reaching for the largest available model. A well-chosen smaller model, optimized with the other six techniques here, frequently outperforms a larger model running unoptimized, on both latency and cost.
The seventh technique is really a meta-technique: most of the six above aren't things you implement from scratch, they're features of the serving software you choose. vLLM ships PagedAttention-based KV cache management, prefix caching, continuous batching, and quantization support as built-in features, configured through flags rather than custom implementation. Picking a serving engine that already implements these well is frequently a bigger latency win than manually tuning any single technique on a weaker foundation.
This is also where time to first token and tokens per second, the two metrics that actually define perceived speed, come from mechanically. Understanding which of the two your workload cares about more, per the distinction at the top of this post, shapes which of the six techniques above matters most for your specific case.
Worth being clear about a related but distinct question: some of these techniques are primarily latency techniques, and some are primarily llm cost optimization techniques, and they're not the same problem even though they overlap. For how these choices translate into actual inference spend, see the packet.ai LLM inference cost guide.
All seven techniques above are things you'd otherwise configure yourself in a self-hosted vLLM deployment. packet.ai's Token Factory is being built to apply these at the serving layer by default, so requests benefit from them without configuration on your side. Token Factory is currently in private preview, with the specific model catalog and pricing still being finalized.
Join the waitlist for early access once it opens.
Last reviewed: August 25, 2026. For the individual mechanisms in depth, see the KV cache, prefix caching, and speculative decoding guides. For precision formats, see FP8 vs FP16 vs BF16. For serving engine fundamentals, see What Is vLLM. For how these choices affect cost specifically, see the LLM inference cost guide.
Same models. Same API. Fraction of the cost. Start free — no credit card required.
Start Building →