What Limits Context Windows: Attention Complexity, Memory, and Cost
~13 min read
Self-attention costs grow QUADRATICALLY with sequence length, not linearly — doubling context length roughly quadruples the compute and memory needed for attention alone.
It's tempting to assume a '1 million token context window' costs roughly 8x what a 128k window costs, since 1M is about 8x bigger than 128k. The real cost is far worse than that, and understanding why requires looking at what self-attention (the mechanism inside every Transformer, covered at a high level in this curriculum's neural-networks material) actually computes.
Self-attention lets every token 'look at' every other token to decide how much to weigh it when building its own representation. For a sequence of n tokens, this means computing an attention score between EVERY pair of tokens — that's n multiplied by n, or n-squared, pairs. Double the sequence length, and you don't double the work — you quadruple it: 2n tokens means (2n)^2 = 4n^2 pairs, four times as many as before. This O(n^2) (order n-squared) scaling is the single biggest structural reason context windows can't just be made arbitrarily large by throwing more compute at the problem — the cost curve gets steeper and steeper as n grows, not just proportionally bigger.
Memory is the second constraint, and it's closely related to the KV cache from this curriculum's llm-optimization topic: every token's attention keys and values need to be stored so future tokens can attend to them, and that storage also grows with sequence length. A model processing a 1-million-token context needs to hold a correspondingly enormous KV cache in GPU memory for the ENTIRE generation — this is why extremely long contexts are often memory-bound (limited by how much fits in VRAM) well before they're compute-bound.
Inference cost combines both problems into what you actually pay: processing a long prompt (the 'prefill' phase, computing attention across the whole input at once) takes meaningfully longer and costs meaningfully more as the input grows, due to the O(n^2) attention cost above, and providers typically price API calls partly by token count specifically because longer inputs are genuinely more expensive to serve, not just as a convenient billing unit.
This is exactly why 'just increase the context window' isn't a free upgrade a lab can ship overnight — every genuine long-context capability increase requires engineering work to manage this quadratic cost curve, which is precisely what the next two subtopics' techniques (better positional encodings, sparse/sliding-window attention) are built to address.
💻 Code example
# Demonstrating the O(n^2) attention cost directly: doubling sequence
# length QUADRUPLES the number of attention score pairs computed.
def attention_pair_count(seq_len: int) -> int:
"""Every token attends to every other token: n * n pairs."""
return seq_len * seq_len
def kv_cache_size_mb(seq_len: int, num_layers: int = 32, num_kv_heads: int = 8,
head_dim: int = 128, bytes_per_val: int = 2) -> float:
"""KV cache memory (from llm-optimization) also grows with seq_len."""
total_bytes = 2 * num_layers * num_kv_heads * head_dim * seq_len * bytes_per_val
return total_bytes / 1e6
print(f"{'seq_len':>10} {'attn_pairs':>15} {'pairs_vs_prev':>15} {'kv_cache_mb':>12}")
prev_pairs = None
for seq_len in [1_000, 2_000, 4_000, 8_000, 128_000, 1_000_000]:
pairs = attention_pair_count(seq_len)
ratio = f"{pairs / prev_pairs:.1f}x" if prev_pairs else "--"
kv_mb = kv_cache_size_mb(seq_len)
print(f"{seq_len:>10,} {pairs:>15,} {ratio:>15} {kv_mb:>10.1f} MB")
prev_pairs = pairs
# Notice: each 2x increase in seq_len produces roughly a 4x increase
# in attention pairs -- the quadratic cost the subtopic describes
💬 Deep Dive with AI
Key points
- •Self-attention computes a score between every pair of tokens, so cost scales with sequence length SQUARED (O(n^2)), not linearly
- •Doubling context length roughly quadruples attention compute — this is the core structural reason context windows can't scale for free
- •The KV cache (from llm-optimization) must store every token's keys/values for the whole context, making very long contexts memory-bound in GPU VRAM
- •Longer prompts take meaningfully longer to process (the 'prefill' phase) and cost more, which is part of why API pricing scales with token count
- •Real long-context capability requires specific engineering work (covered in the next two subtopics) to manage this quadratic cost, not just more raw compute