AI & Machine Learning

Context Window Limits: Managing Long Documents in LLMs

Learn how to work within LLM context window limits, process documents longer than the model supports, and choose the right long-context model for your needs.

By Inventive HQ Team

Before you wrestle a long document into a model, find out exactly how many tokens it actually is. Paste your text below to count its tokens and see at a glance whether it fits inside your model's context window.

Loading interactive tool...

You've crafted the perfect prompt and have a 50-page document to analyze. You hit send, and... error: "This model's maximum context length is 8192 tokens." Welcome to one of the most common challenges when working with LLMs: context window limits.

Understanding context windows—and how to work around their limitations—is essential for building practical AI applications. This guide explains what context windows are, compares limits across models, and provides strategies for processing documents that exceed those limits.

Context Windows in 60 Seconds

A context window is the total number of tokens an LLM can process in a single request - system prompt, conversation history, your input, document content, and the model's output all draw from the same budget.

Context Window = System + History + Input + Documents + Output

Anything past the limit is invisible to the model: the request either errors out or the content is silently truncated. This post is the applied companion to our canonical explainer, Context Windows Explained - start there for the full mental model, the "lost in the middle" research, and the size-versus-quality tradeoff. Here we focus on one practical problem: what to do when your document is bigger than the window.

Current Context Window Sizes (mid-2026)

The frontier has standardized on 1M-token windows. The numbers that mattered in 2024 - 128K here, 200K there - are now the floor, not the ceiling.

ModelContext windowMax outputApprox. capacity
Llama 4 Scout (open weight)10,000,000host-dependent~7.5M words
Gemini 3.5 Pro (expected late 2026)2,000,000~64K~1.5M words
GPT-5.51,000,000configurable~750K words
Claude Opus 4.8 / Sonnet 4.61,000,000 (200K standard)64K+~750K words
Gemini 3 Flash / 2.5 Pro1,048,57665,535~750K words
Llama 4 Maverick (open weight)1,000,000host-dependent~750K words
DeepSeek-V3131,0728K~98K words

Context Window vs. Output Limit

Don't confuse context window with maximum output. A 1M-token input window does not buy you 1M tokens of output - output is a separate, much smaller cap:

ModelContext windowMax output
Gemini 3 Flash1,048,57665,535 tokens
Gemini 3.5 Pro (expected)2,000,000~64K tokens
Claude Opus 4.81,000,00064K+ tokens
DeepSeek-V3131,0728K tokens

With a 950K-token input you might still only get tens of thousands of tokens back - plan input size with the output ceiling in mind.

The "Lost in the Middle" Tax - Briefly

Even when a document fits, models don't read all of it equally. Recall is highest for tokens at the very start and very end of the window and sags in the middle - roughly 90% recall at the edges versus 50-70% for facts buried in the center. Our canonical explainer covers the Stanford/Berkeley research and the U-shaped curve in detail.

The operational takeaway for long documents: fitting a document in the window is necessary but not sufficient. Placement and retrieval still decide whether the model actually uses the right passage. Put the most important material at the start or end, retrieve relevant sections instead of dumping everything, and use clear headers so the model can navigate. That's exactly why the strategies below exist.

Watch the memory bill if you self-host. Pushing a long document into a big window isn't only a token-pricing question. On local or self-hosted models, every context token consumes KV-cache VRAM that grows linearly with sequence length - a 128K-token context on a 70B model needs roughly 80 GB of KV cache (FP16) on top of the weights. Before assuming you can run million-token contexts locally, read The Real Cost of LLM Context: KV Cache, VRAM, and Memory and check the math with the LLM VRAM Calculator.

Strategy 1: Chunking

When documents exceed context limits, break them into processable pieces.

Fixed-Size Chunking

The simplest approach—split by token count:

def chunk_by_tokens(text: str, chunk_size: int = 4000, overlap: int = 200) -> list[str]:
    tokens = tokenizer.encode(text)
    chunks = []

    for i in range(0, len(tokens), chunk_size - overlap):
        chunk_tokens = tokens[i:i + chunk_size]
        chunks.append(tokenizer.decode(chunk_tokens))

    return chunks

Overlap ensures context continuity—information at chunk boundaries isn't lost.

Semantic Chunking

More sophisticated—split at natural boundaries:

def chunk_by_sections(text: str) -> list[str]:
    # Split by headers, paragraphs, or semantic boundaries
    sections = re.split(r'\n#{1,3}\s', text)  # Split on markdown headers
    return [s for s in sections if len(s.strip()) > 100]

Recursive Chunking

LangChain's approach—try larger boundaries first, fall back to smaller:

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=4000,
    chunk_overlap=200,
    separators=["\n\n", "\n", ". ", " ", ""]  # Try in order
)

chunks = splitter.split_text(document)

Strategy 2: Map-Reduce Processing

Process chunks independently, then synthesize results.

The Map Phase

Apply the same operation to each chunk:

def map_summarize(chunks: list[str]) -> list[str]:
    summaries = []
    for chunk in chunks:
        prompt = f"Summarize this section:\n\n{chunk}"
        summary = llm.complete(prompt)
        summaries.append(summary)
    return summaries

The Reduce Phase

Combine chunk results into a final answer:

def reduce_summaries(summaries: list[str], question: str) -> str:
    combined = "\n\n".join(summaries)
    prompt = f"""Based on these section summaries:

{combined}

Answer: {question}"""
    return llm.complete(prompt)

Full Map-Reduce Pipeline

def answer_from_long_document(document: str, question: str) -> str:
    # 1. Chunk the document
    chunks = chunk_by_tokens(document, chunk_size=4000)

    # 2. Map: Extract relevant info from each chunk
    extractions = []
    for chunk in chunks:
        prompt = f"Extract information relevant to: {question}\n\nText: {chunk}"
        extraction = llm.complete(prompt)
        extractions.append(extraction)

    # 3. Reduce: Synthesize final answer
    combined = "\n\n".join([e for e in extractions if e.strip()])
    final_prompt = f"Based on this information:\n{combined}\n\nAnswer: {question}"

    return llm.complete(final_prompt)

Strategy 3: Retrieval-Augmented Generation (RAG)

Instead of processing entire documents, retrieve only relevant sections.

Basic RAG Flow

Document → Chunk → Embed → Vector Store
                              ↓
Query → Embed → Retrieve Top-K → Generate Answer
Advertisement

Implementation Example

from sentence_transformers import SentenceTransformer
import chromadb

# Setup
embedder = SentenceTransformer('all-MiniLM-L6-v2')
db = chromadb.Client()
collection = db.create_collection("documents")

# Index documents
def index_document(doc_id: str, text: str):
    chunks = chunk_by_tokens(text, chunk_size=500)
    embeddings = embedder.encode(chunks)

    collection.add(
        ids=[f"{doc_id}_{i}" for i in range(len(chunks))],
        embeddings=embeddings.tolist(),
        documents=chunks
    )

# Query
def query_documents(question: str, top_k: int = 5) -> str:
    query_embedding = embedder.encode([question])[0]

    results = collection.query(
        query_embeddings=[query_embedding.tolist()],
        n_results=top_k
    )

    context = "\n\n".join(results['documents'][0])

    prompt = f"""Context: {context}

Question: {question}

Answer based on the context above:"""

    return llm.complete(prompt)

When to Use RAG vs. Full Context

Use RAG WhenUse Full Context When
Document is very large (100K+ tokens)Document fits in context
Only need specific informationNeed holistic understanding
Multiple documents to searchSingle focused document
Questions are specificQuestions require full context
Cost is a concernQuality is paramount

Strategy 4: Hierarchical Summarization

Create summaries at multiple levels for efficient navigation.

Building a Summary Hierarchy

def build_summary_tree(document: str) -> dict:
    # Level 3: Paragraph summaries
    paragraphs = document.split('\n\n')
    para_summaries = [summarize(p, max_tokens=50) for p in paragraphs]

    # Level 2: Section summaries (groups of paragraphs)
    sections = chunk_list(para_summaries, chunk_size=10)
    section_summaries = [summarize('\n'.join(s), max_tokens=100) for s in sections]

    # Level 1: Document summary
    doc_summary = summarize('\n'.join(section_summaries), max_tokens=200)

    return {
        "document_summary": doc_summary,
        "section_summaries": section_summaries,
        "paragraph_summaries": para_summaries,
        "full_text": document
    }

Querying the Hierarchy

def hierarchical_query(tree: dict, question: str) -> str:
    # Start with document summary to identify relevant sections
    relevant_sections = identify_relevant_sections(
        tree["document_summary"],
        tree["section_summaries"],
        question
    )

    # Get detailed content from relevant sections only
    detailed_context = get_section_content(tree, relevant_sections)

    # Answer from focused context
    return llm.complete(f"Context: {detailed_context}\n\nQuestion: {question}")

Strategy 5: Conversation Management

In chat applications, context accumulates with every turn.

The Problem

Turn 1: System (500) + User (100) + Assistant (200) = 800 tokens
Turn 2: System (500) + History (800) + User (150) + Assistant (250) = 1,700 tokens
Turn 3: System (500) + History (1,700) + User (200) + Assistant (300) = 2,700 tokens
...
Turn 20: Context overflow!

Solution 1: Sliding Window

Keep only the most recent N turns:

def sliding_window_context(messages: list, max_turns: int = 10) -> list:
    system_messages = [m for m in messages if m['role'] == 'system']
    conversation = [m for m in messages if m['role'] != 'system']

    # Keep only recent turns
    recent = conversation[-max_turns * 2:]  # *2 for user+assistant pairs

    return system_messages + recent

Solution 2: Summarize Old Context

def summarize_history(messages: list, threshold: int = 50000) -> list:
    current_tokens = count_tokens(messages)

    if current_tokens < threshold:
        return messages

    # Summarize older messages
    system = messages[0]  # Keep system prompt
    old_messages = messages[1:-4]  # All but last 2 turns
    recent_messages = messages[-4:]  # Keep last 2 turns

    summary = llm.complete(f"Summarize this conversation:\n{format_messages(old_messages)}")

    return [
        system,
        {"role": "system", "content": f"Previous conversation summary: {summary}"},
        *recent_messages
    ]

Solution 3: Hybrid Approach

def manage_context(messages: list, max_tokens: int = 100000) -> list:
    current = count_tokens(messages)

    if current <= max_tokens:
        return messages

    # Try sliding window first
    windowed = sliding_window_context(messages, max_turns=20)
    if count_tokens(windowed) <= max_tokens:
        return windowed

    # Fall back to summarization
    return summarize_history(messages, threshold=max_tokens * 0.8)

Choosing the Right Long-Context Model

Decision Framework

Document < 128K tokens?
├─► Yes → Any current frontier model (GPT-5.x, Claude, Gemini, DeepSeek-V3)
└─► No → Document < 1M tokens?
    ├─► Yes → GPT-5.5, Claude Opus 4.8 / Sonnet 4.6, or Gemini 3.x (all native 1M)
    └─► No → Document < 10M tokens?
        ├─► Yes → Llama 4 Scout (10M, open weight); Gemini 3.5 Pro targets 2M
        └─► No → Must use chunking / RAG

Remember: even when a document fits, chunking or RAG is often cheaper and more accurate than a full-context dump - the "lost in the middle" tax doesn't disappear just because you can afford the tokens.

Cost Considerations

Larger context doesn't mean you should use it all:

ScenarioModelContext usedInput cost (per request)
Short queryClaude Haiku 4.5 ($1/1M)5K tokens$0.005
Full documentClaude Haiku 4.5 ($1/1M)100K tokens$0.10
Full documentClaude Sonnet 4.6 ($3/1M)100K tokens$0.30
Full documentClaude Opus 4.8 ($5/1M)100K tokens$0.50

Using maximum context on the top model is roughly 20-100x more expensive than a minimal query on a small one - and output tokens (billed at 5x input on Claude) widen the gap further.

Best Practices Summary

Do:

  • Estimate token counts before sending requests
  • Use retrieval for targeted information extraction
  • Place critical information at start/end of context
  • Implement conversation management for chat apps
  • Monitor for "lost in the middle" issues

Don't:

  • Dump entire documents when only sections matter
  • Ignore output token limits when planning context
  • Trust that models process all context equally
  • Exceed context limits without error handling
  • Pay for 200K context when 5K would suffice

Conclusion

Context windows define what's possible with a single LLM call. Understanding these limits—and the strategies to work around them—is fundamental to building effective AI applications.

Key takeaways:

  1. Know your limits: Different models have vastly different capacities
  2. Less is often more: Focused context often outperforms full-document dumps
  3. Use the right strategy: Chunking, RAG, and summarization each have their place
  4. Mind the middle: Information placement affects recall accuracy
  5. Manage conversations: Chat histories grow fast; plan for it

Use our LLM Token Counter to check whether your documents fit within context limits and estimate costs before processing.

Frequently Asked Questions

What is a context window in LLMs?

A context window is the maximum number of tokens an LLM can process in a single request, including both the input (your prompt, documents, conversation history) and the output (the model's response). Think of it as the model's working memory—anything beyond this limit simply cannot be seen or processed by the model.

Which LLM has the largest context window?

Context windows have ballooned since 2024. Among open-weight models, Meta's Llama 4 Scout leads with a 10-million-token window. Among commercial APIs, 1 million tokens is now the frontier standard - GPT-5.5, Claude Opus 4.8 and Sonnet 4.6, and Google's Gemini 3.x all support it - and Google's expected Gemini 3.5 Pro targets 2 million. The old reference points (Claude at 200K, GPT-4 Turbo at 128K) are now the floor, not the ceiling.

What happens if my input exceeds the context window?

Most APIs will return an error if you exceed the context window. Some models truncate the input silently, which can cause unexpected behavior. Always check your token count before sending requests and implement strategies like chunking, summarization, or RAG to handle documents that exceed limits.

Is a larger context window always better?

Not necessarily. Larger context windows cost more (you pay per token), and models may struggle with "lost in the middle" problems where information in the center of long contexts is poorly recalled. For many tasks, shorter, more relevant context outperforms dumping entire documents into the prompt.

What is the 'lost in the middle' problem?

Research has shown that LLMs attend more strongly to information at the beginning and end of long contexts, while information in the middle may be poorly recalled. This means critical information placed in the middle of a 100K-token context might be missed or given less weight than information at the edges.

How do I process a document larger than the context window?

Several strategies work: (1) Chunk the document and process pieces independently, (2) Use RAG to retrieve only relevant sections, (3) Create a hierarchical summary first, then query the summary, (4) Use map-reduce where you process chunks, then synthesize results, (5) Use a model with a larger context window.

What's the difference between context window and max output tokens?

Context window is the total capacity for input plus output. Max output tokens is a separate, much smaller limit on how much the model can generate in response. For example, Gemini 3 Flash has a roughly 1M-token context window but caps output around 65K tokens—so a 950K-token input still yields at most ~65K tokens of response, not 950K. Always plan input size with the output ceiling in mind.

Does conversation history count toward the context window?

Yes, in chat applications, all previous messages in the conversation consume context window space. A 20-turn conversation might use 50K+ tokens before your current question is even asked. This is why long conversations eventually need summarization or truncation of older messages.

llmcontext-windowraglong-documentschunkingai