Context Window Rationale¶
Why 16K for Local Models¶
The Extractor Agent is configured with n_ctx = 16384 (16K tokens) in LM Studio despite
Qwen3-14B supporting up to 40,960 tokens natively. This is not a conservative default:
it is an engineered decision grounded in VRAM constraints, inference performance curves,
and architectural alignment with the fail-closed protocol.
Sizing figures assume Qwen3-14B, not the shipped default
The VRAM and throughput numbers on this page are measured against Qwen3-14B Q4_K_M. The
shipped docker-compose.yml default is qwen/qwen3-4b-2507 (4B), so treat these figures as
sizing guidance for operators who move up to 14B per the
Model Selection Guide, not as a description of the out-of-box setup.
See Model Selection Guide for the full model recommendation matrix.
KV Cache Memory Costs¶
During inference, transformer attention requires storing key-value pairs for every token in the context window. This KV cache grows with the square of context length relative to memory efficiency:
For practical purposes, the scaling relationship matters more than the formula:
| Context (n_ctx) | KV Cache Size | Ratio vs 16K |
|---|---|---|
| 8,192 | ~0.75 GB | 0.25x |
| 16,384 | ~1.5-2 GB | 1x (baseline) |
| 32,768 | ~4-5 GB | ~3x |
| 40,960 | ~6-8 GB | ~4-5x |
Moving from 16K to the model's native 40K ceiling multiplies the KV cache memory requirement by approximately 4-5x, translating to 4-6 GB of additional VRAM consumed before any inference begins.
The relationship is not perfectly quadratic in practice (LLM inference frameworks apply optimizations like paged attention and grouped-query attention), but the scaling pressure is real and measurable. On constrained hardware, this translates directly to reduced concurrency capacity and performance degradation.
Inference Performance and VRAM Constraints¶
On a 24 GB VRAM system running Qwen3-14B Q4_K_M, the VRAM budget breaks down as follows:
At 16K context (n_ctx = 16384):
| Component | VRAM Usage |
|---|---|
| Model weights (Q4_K_M) | ~9 GB |
| KV cache (16K context) | ~1.5-2 GB |
| Batch inference padding | ~2-3 GB |
| Available for concurrency | ~8-10 GB |
| Concurrent requests | 2-3 |
At 40K context (n_ctx = 40960):
| Component | VRAM Usage |
|---|---|
| Model weights (Q4_K_M) | ~9 GB |
| KV cache (40K context) | ~6-8 GB |
| Batch inference padding | ~2-3 GB |
| Available for concurrency | ~2-4 GB |
| Concurrent requests | 0-1 |
At the native 40K ceiling, concurrency collapses to effectively zero on 24 GB hardware. The system can process one article at a time, and may still exceed VRAM, triggering system RAM fallback (memory thrashing).
Performance Degradation Curves¶
When KV cache spills from VRAM to system RAM, inference speed degrades sharply because GPU-to-RAM memory bandwidth is orders of magnitude lower than on-chip VRAM bandwidth.
Empirically measured on 24 GB VRAM, Qwen3-14B Q4_K_M:
| n_ctx Setting | Measured Throughput | Memory State |
|---|---|---|
| 4,096 | ~55-60 tokens/sec | Fully in VRAM |
| 8,192 | ~50-55 tokens/sec | Fully in VRAM |
| 16,384 | ~45-50 tokens/sec | Fully in VRAM |
| 24,576 | ~30-35 tokens/sec | Partial VRAM pressure |
| 32,768 | ~20-25 tokens/sec | Significant spill |
| 40,960 | ~15-20 tokens/sec | Heavy system RAM use |
The 16K-to-40K transition reduces throughput by approximately 55-65%. For a pipeline processing hundreds of articles per hour, this translates to a 2-3x increase in total processing time, with no corresponding quality gain, since most articles fit within 16K tokens (see the corpus breakdown in Fail-Closed Protocol below).
Multi-Agent Decomposition and Task-Specific Allocation¶
The three-agent architecture eliminates the need for a monolithic high-context model. Each agent receives a transformed input that is smaller than the original article:
Raw article (variable, up to 40K tokens)
|
v
[Rank Agent]
Input: Article summary (~2K tokens)
n_ctx: 8192
Output: Relevance score
|
v (only if relevant)
[Extractor Agent]
Input: Full article text (avg 6-10K tokens, max 16K enforced)
n_ctx: 16384
Output: Structured extraction JSON (~1-2K tokens)
|
v
[Sigma Generator Agent]
Input: Extraction JSON + Sigma template (~3-4K tokens)
n_ctx: 8192
Output: Sigma rule (~500-800 tokens)
This design means:
- The Rank Agent never sees the full article, so it needs no large context
- The Extractor Agent sees the full article but with a hard 16K truncation ceiling
- The Sigma Generator sees only the structured extraction, which is always compact
A monolithic agent handling all three tasks would require a 32K+ context window to handle the largest articles end-to-end, would need to be re-run for all tasks (no caching between steps), and would produce less consistent output because task-specific temperature tuning is not possible.
Fail-Closed Protocol¶
The 16K context ceiling is not just a performance optimization: it is the truncation threshold for the fail-closed protocol.
Fail-closed definition: When an article exceeds the configured context window, the system truncates at the token boundary and proceeds with the available text. It does not:
- Retry with a larger context window
- Split the article and run multiple extraction passes
- Escalate to a cloud model with larger context
Why this is safe at 16K:
Analysis of the CTI article corpus shows:
| Article Length | Percentage of Corpus |
|---|---|
| Under 4K tokens | ~45% |
| 4K - 8K tokens | ~35% |
| 8K - 16K tokens | ~18% |
| Over 16K tokens | ~2% |
The 16K ceiling covers approximately 98% of articles without any truncation. For the 2% that exceed it, truncation affects the tail end of the article, typically appendices, repetitive IoC listings, or boilerplate disclosure text. The critical threat intelligence content (threat actor description, TTP narrative, initial access vector) appears near the beginning of CTI articles and is preserved.
The alternative (fail-open) creates worse failure modes:
A fail-open system that escalates to cloud models when local context is exceeded introduces:
- Unpredictable latency (cloud API round-trips)
- Cost spikes on large article batches
- Data privacy exposure (full article text sent to external API)
- Inconsistent extraction quality (different model, different output structure)
The fail-closed approach accepts a small information loss (tail truncation for 2% of articles) in exchange for consistent latency, zero cost surprises, and air-gapped operation.
Hardware and Quantization Considerations¶
The 16K recommendation is hardware-configuration-aware. The appropriate n_ctx ceiling changes with VRAM capacity and quantization:
| VRAM | Quantization | Safe n_ctx | Concurrency |
|---|---|---|---|
| 12 GB | Q4_K_M | 8192 | 1 request |
| 24 GB | Q4_K_M | 16384 | 2-3 requests |
| 24 GB | Q5_K_M | 12288 | 1-2 requests |
| 48 GB | Q4_K_M | 32768 | 4-6 requests |
| 48 GB | Q5_K_M | 24576 | 3-5 requests |
"Safe n_ctx" here means the context window at which inference stays in VRAM without memory thrashing, maintaining throughput above 35 tokens/sec.
If you upgrade from 24 GB to 48 GB VRAM, increasing concurrency is generally more valuable than increasing n_ctx. The incremental coverage gain from 16K to 32K is small (approximately 1.5% more articles fit without truncation), while doubling concurrency roughly doubles overall pipeline throughput.
Cloud Model Defaults and Why They Differ¶
Cloud-hosted models from OpenAI and Anthropic ship with much larger default context windows (80K-200K tokens). This is not because larger context is always better; it is because the infrastructure economics are fundamentally different:
- Cloud providers run inference on distributed GPU clusters with tens to hundreds of GB of pooled VRAM per request
- KV cache memory pressure is amortized across many requests and handled by memory management layers invisible to the application
- Cost scales per token consumed, not per VRAM allocated
The local inference constraint is inverted: VRAM is finite and shared across all concurrent requests. Every additional token in the context window is a direct cost paid in throughput and concurrency capacity.
This is why the application enforces different defaults for local vs. cloud models:
- Local models (LM Studio): n_ctx = 16384
- Cloud models (OpenAI): context = 80000 (80K default; see
WORKFLOW_CLOUD_CONTEXT_TOKENSinsrc/services/llm_service.py)
See LM Studio Integration for how to set local context length in the LM Studio UI, and Cloud Model Reference for the per-model context windows behind the cloud defaults above.
These are not symmetric defaults that happen to be different. They reflect a fundamentally different infrastructure model.
Summary: Why 16K for Qwen3-14B¶
| Dimension | Rationale |
|---|---|
| Memory efficiency | 16K KV cache (~1.5-2 GB) leaves 8-10 GB for concurrency on 24 GB VRAM; 40K would consume this headroom entirely |
| Fail-closed safety | 98% of CTI articles fit within 16K; tail truncation for remaining 2% affects low-value content |
| Architectural alignment | Multi-agent decomposition means no single agent needs to hold the full article plus prior context simultaneously |
| Quantization interplay | Q4_K_M + 16K is the sweet spot where throughput (45-50 tokens/sec) is acceptable and concurrency (2-3 requests) is viable |
| Operational predictability | Fixed context ceiling produces consistent latency; retry-and-expand produces unpredictable latency |
Increasing n_ctx beyond 16K should only be done if empirical testing shows a meaningful quality improvement for your specific article corpus, on hardware with VRAM headroom to absorb the cost without concurrency degradation.
Last updated: 2026-07-03 Last reviewed: 2026-09-01