Fill-in-the-Middle (FIM) and Inline Code Completion in Production: Architecture, Prefix-Suffix Context Windows, Speculative Decoding, and Sub-50ms Serving Latencies
Inline code completion is the most latency-sensitive deployment of large language models in production software engineering. Unlike conversational assistants or background agentic batch jobs, inline code completion operates directly inside an active editor typing loop. Developers type at speeds ranging from 40 to 120 words per minute (an inter-keystroke interval of 100ms to 250ms). If an inference system cannot deliver suggestions within 100ms to 150ms of a keystroke pause, the suggestion arrives after the developer has already typed past the insertion point, rendering the compute wasted and degrading user experience.
Standard left-to-right (L2R) autoregressive language models predict subsequent tokens given only preceding context. However, software engineering rarely proceeds linearly from the top of a file to the bottom. Developers routinely insert code within existing functions, modify arguments inside existing function calls, and implement class methods surrounded by existing type definitions and downstream call sites. Generating syntactically valid code in the middle of an existing document requires conditioning on both the preceding prefix and the succeeding suffix.
Production inline completion architectures solve this through Fill-in-the-Middle (FIM) data transformations, prefix-suffix context slicing, prefix-aligned KV cache reuse, and speculative decoding pipelines designed to achieve sub-50ms time-to-first-token (TTFT) latencies.

1. Fill-in-the-Middle (FIM) Transformations and Tokenization
Standard causal transformers enforce lower-triangular attention masks, preventing tokens from attending to subsequent sequence positions during pre-training. Modifying transformer architectures to incorporate bidirectional attention heads introduces serving overhead and complicates key-value (KV) caching.
In 2022, researchers at OpenAI formalized the Fill-in-the-Middle (FIM) training objective (Bavarian et al., 2022). FIM achieves bidirectional conditioning without modifying model architecture or attention masks. Instead, FIM applies an input data transformation during pre-training and fine-tuning:
- A document is partitioned into three contiguous segments: Prefix (), Middle (), and Suffix ().
- The segments are rearranged into an autoregressive sequence where the middle segment appears last.
- Special sentinel tokens delimit the boundaries between segments.
Original Document:
[Prefix (P)] [Middle (M)] [Suffix (S)]
Prefix-Suffix-Middle (PSM) Transformation:
<PRE> [Prefix (P)] <SUF> [Suffix (S)] <MID> [Middle (M)] <EOT>
Suffix-Prefix-Middle (SPM) Transformation:
<SUF> [Suffix (S)] <PRE> [Prefix (P)] <MID> [Middle (M)] <EOT>When predicting tokens in the Middle () segment, the causal attention mechanism naturally allows every token in to attend to all tokens in both and .
The FIM-for-Free Property and Hyperparameters
Bavarian et al. demonstrated that training models on a mixture of standard left-to-right data and FIM-transformed data confers infilling capabilities with zero penalty on conventional left-to-right code generation benchmarks (the "FIM-for-free" property). Modern foundation code models adhere to standard FIM pre-training configurations:
- FIM Rate: Typically set to 0.50 (50% of pre-training sequences undergo FIM splitting, while 50% retain standard L2R formatting).
- Format Splitting: A 50/50 split between PSM (Prefix-Suffix-Middle) and SPM (Suffix-Prefix-Middle) modes prevents positional bias.
- Span Selection: Span boundaries are selected via uniform random cuts or Abstract Syntax Tree (AST) node boundaries to train the model on diverse syntactic granularity (single tokens, line fragments, full statements, and multi-line blocks).
Sentinel Token Variations Across Model Families
Different model architectures implement custom sentinel tokens within their tokenizers:
| Model Family | Prefix Sentinel | Suffix Sentinel | Middle Sentinel | End of Sequence Sentinel | Source | | :--- | :--- | :--- | :--- | :--- | :--- | | StarCoder / StarCoder2 | <fim_prefix> | <fim_suffix> | <fim_middle> | <|endoftext|> | Li et al. (2023) | | CodeLlama | <PRE> | <SUF> | <MID> | <EOT> | Rozière et al. (2023) | | DeepSeek-Coder | <|fim begin|> | <|fim hole|> | <|fim end|> | <|end of sentence|> | Guo et al. (2024) | | Qwen2.5-Coder | <\|fim_prefix\|> | <\|fim_suffix\|> | <\|fim_middle\|> | <\|endoftext\|> | Hui et al. (2024) |
2. Context Window Assembly and Cross-File Retrieval
An editor context rarely consists of a single file in isolation. To generate completions that adhere to repository-specific APIs, types, and utility functions, the completion engine must assemble a hybrid prompt within strict token budgets (typically 2,048 to 8,192 tokens to maintain low prefill latency).
+-------------------------------------------------------------------+
| Top of Prompt: Cross-File & Workspace Context (Static Prefix) |
| - Relevant Type Definitions (LSP Symbol Lookup) |
| - Similar Chunks from Recent Tabs (Jaccard / BM25 / Vector) |
+-------------------------------------------------------------------+
| Active File Prefix: [PRE] <imports, preceding classes, functions> |
+-------------------------------------------------------------------+
| Active File Suffix: [SUF] <downstream code, closing delimiters> |
+-------------------------------------------------------------------+
| Target Generation Trigger: [MID] |
+-------------------------------------------------------------------+1. Active File Slicing
The completion engine extracts tokens surrounding the editor cursor:
- Prefix Window: Up to 70% of the active file token budget (e.g., 2,000 tokens preceding the cursor).
- Suffix Window: Up to 30% of the active file token budget (e.g., 800 tokens following the cursor). Suffix truncation typically prioritizes tokens immediately following the cursor, retaining the enclosing scope and closing delimiters.
2. Cross-File Context Harvesting
Production engines extract external context through two complementary paths:
- Lexical and Recent-Buffer Matching: Computing Jaccard similarity or BM25 retrieval over chunks from recently edited or viewed editor tabs.
- Language Server Protocol (LSP) Inferences: Querying LSP servers for type signatures, imported symbol declarations, and interface definitions referenced in the active file prefix.
3. Structure-Aware Prefix Tagging
Cross-file context is prefixed at the top of the prompt using comment tags (e.g., <reponame>/path/to/file.ts), ensuring the causal attention layers process background context prior to the active file sentinel tokens.
3. Serving Architecture: Prefix Caching and Speculative Decoding
Achieving interactive response times requires optimizing both the prefill phase (processing the context prompt) and the decode phase (generating token output).
Prefix KV Cache Optimization (PSM vs. SPM)
The selection between PSM and SPM formats has profound implications for serving efficiency in engines utilizing RadixAttention or PagedAttention (such as vLLM and SGLang):
- PSM Format (
[PRE] prefix [SUF] suffix [MID]): The prompt begins with static repository context followed by the active file prefix. As a developer types sequentially on a line, the prefix grows while previous prefix tokens remain invariant. Engines with tree-structured prefix caching match and reuse the entire cached KV state of the prompt prefix. Only the newly typed characters and the suffix require prefill computation, reducing TTFT from 120ms to under 15ms. - SPM Format (
[SUF] suffix [PRE] prefix [MID]): Placing the suffix at the beginning of the sequence causes any edits to the downstream buffer to invalidate the root of the KV cache tree, preventing prefix reuse across consecutive keystrokes. Consequently, production serving pipelines predominantly standardize on PSM formatting during inference.
Speculative Decoding for Repetitive Code Structures
Code generation exhibits high token predictability due to syntax structure, keywords, and boilerplate conventions. Speculative decoding exploits this by combining a small, high-throughput draft mechanism with a larger target verification model:
- Draft Generation: A lightweight draft mechanism (such as an EAGLE head, an n-gram prompt lookup, or a 1B-parameter draft model) generates candidate tokens (typically to ).
- Parallel Verification: The target foundation model (e.g., 7B or 14B code model) executes a single forward pass over all tokens simultaneously, verifying valid logits.
- Acceptance: Accepted tokens are committed in a single step; on rejection, generation rolls back to the first mismatch.
According to benchmarks from Snowflake Arctic Inference and vLLM engineering teams, speculative decoding with prompt lookup or suffix matching yields a 2.3x to 4.5x decoding speedup on repetitive code generation workloads (such as SWE-Bench and HumanEval), sustaining generation rates above 150 to 200 tokens per second on single GPU instances.
4. Client-Side Lifecycle: Debouncing, Streaming, and Cancellation
Serving infrastructure must be paired with client-side request management inside the editor extension to avoid overwhelming inference clusters with stale requests.
User Keystroke Event
|
v
+-----------------------------+
| Debounce Timer (50ms - 75ms)| ---> (Reset if next key pressed)
+-----------------------------+
| (Timer expires)
v
+-----------------------------+
| Extract Prefix / Suffix AST |
+-----------------------------+
|
v
+-----------------------------+
| Fire HTTP/2 Streaming Post |
+-----------------------------+
|
+---------------------------------------------+
| |
v v
[Streaming Token Arrival] [New Keystroke Detected]
| |
v v
[Syntax Stopping Check] [AbortController.abort()]
| |
v v
[Render Inline Ghost Text] [Terminate Server Stream]Debouncing and Heuristic Triggers
To avoid firing network requests on every keystroke during rapid typing bursts, client extensions implement adaptive debouncing:
- Baseline Debounce: 50ms to 75ms delay following the most recent keypress.
- Trigger Character Acceleration: Immediate dispatch (0ms debounce) when the cursor follows semantic boundary tokens (e.g.,
.,(,{,->, or newline characters). - Suppression Heuristics: Disabling requests when the cursor is positioned inside string literals, comments, or immediately after a rejection keystroke (e.g., pressing
EscapeorBackspace).
Early Stream Cancellation
When a user continues typing while an inference request is in-flight, the client immediately issues an AbortController.abort() signal over HTTP/2 or WebSocket. Production model gateways (such as LiteLLM or custom proxy layers) translate the connection termination into an engine-level request cancellation, halting GPU forward passes and freeing KV cache memory blocks.
5. Post-Processing and Syntax-Aware Stopping Criteria
Autoregressive models will continue generating tokens until reaching the maximum sequence length or generating an <EOT> sentinel. Unbounded generation wastes compute and produces unwanted multi-line completions.
Syntax-Aware Stopping Rules
Production completion servers enforce dynamic stopping criteria based on AST and delimiter tracking:
- Closing Delimiter Match: If the generated stream produces a closing bracket (
),],}) that already exists in the immediate suffix at the same indentation level, decoding terminates. - Indentation Boundary Exit: For indentation-scoped languages (such as Python or YAML), decoding stops when a new line returns to an indentation level less than or equal to the starting statement.
- Single-Line vs. Multi-Line Classification: If a completion is triggered mid-expression, generation is clamped to a single line; multi-line generation is permitted only on empty lines or block openings.
Suffix Deduplication and Ghost Text Alignment
Before presenting ghost text in the IDE, client-side post-processors align the generated text against the existing suffix:
- If the model generates
function calculateTotal(items) { return items.sum(); }and the existing document already contains}, the overlapping trailing tokens are trimmed. - Common prefix stripping ensures that if the user typed an additional character while the network request was in-flight, any matching leading characters in the returned completion are dropped to prevent character duplication.
Summary of Production Trade-Offs
| System Component | Recommended Production Choice | Primary Benefit | Trade-Off / Constraint | | :--- | :--- | :--- | :--- | | FIM Format | Prefix-Suffix-Middle (PSM) | Maximizes KV cache prefix hits across keystrokes. | Requires strict sentinel token alignment across training and serving. | | Draft Acceleration | Speculative Decoding (EAGLE / N-Gram) | 2x to 4x decode speedup, sub-30ms multi-token output. | Additional VRAM allocation for draft models or n-gram tables. | | Context Window | Asymmetric Slicing (70% Prefix / 30% Suffix) | Preserves local syntax scope and imports. | Suffix truncation requires AST-aware boundary detection. | | Client Transport | HTTP/2 Streaming with Abort Signals | Instant token rendering and GPU preemption on keystroke. | Requires proxy-to-engine cancellation propagation. | | Output Termination | AST Indentation & Delimiter Match | Prevents runaway hallucinations and duplicate brackets. | Requires lightweight language-specific parsing in post-processing. |
Sources
- Efficient Training of Language Models to Fill in the Middle (OpenAI): Bavarian et al. (2022)
- StarCoder: May the Source Be With You!: Li et al. (2023)
- Code Llama: Open Foundation Models for Code: Rozière et al. (2023)
- DeepSeek-Coder: When the Large Language Model Meets Programming: Guo et al. (2024)
- Qwen2.5-Coder Technical Report: Hui et al. (2024)
- vLLM Speculative Decoding Documentation: vLLM Team
- Fast Speculative Decoding in vLLM with Arctic Inference: Snowflake Engineering
- SGLang: Efficient Execution of Structured Language Model Programs: Zheng et al. (2023)



