Push-based KV transfer to improve TTFT and TPOT for disaggregated inference in vLLM

TutoSartup excerpt from this article:
LLM inference has two distinct phases: prefill, which processes the input prompt and builds the key-value (KV) cache, and decode, which uses that cache to generate output one token at a time… Prefill-decode (P-D) disaggregation runs them on separate engine instances, allowing each phase to scale …

vLLM is an open-source inference and serving engine for large language models (LLMs). LLM inference has two distinct phases: prefill, which processes the input prompt and builds the key-value (KV) cache, and decode, which uses that cache to generate output one token at a time. These phases have different compute, memory, and scaling characteristics. Prefill-decode (P-D) disaggregation runs them on separate engine instances, allowing each phase to scale and be optimized independently. This can improve resource utilization, throughput, and latency under load. However, it also requires transferring the KV cache from the prefill instance to the decode instance before token generation can begin, making efficient KV transfer critical to time-to-first-token (TTFT).

One of the ways vLLM performs this transfer is through the NVIDIA Inference Xfer Library (NIXL) connector, which moves KV blocks over interconnects that support Remote Direct Memory Access (RDMA), such as AWS Elastic Fabric Adapter (AWS EFA, the low-latency RDMA network used across servers in AWS). On supported instance types, AWS EFA supports GPUDirect RDMA and Neuron Direct RDMA. NIXL can therefore transfer KV blocks directly between GPU or AWS Trainium device memory without staging through host memory. The default mode for NIXL connector is pull-based: After the prefill instance finishes computing the prompt KV cache, the router relays the source metadata, including the prefill block IDs, to the decode instance. The decode instance then allocates destination blocks, prepares the NIXL transfer, and initiates NIXL READ to pull the KV blocks from the prefill instance. Because these coordination and setup steps occur sequentially after prefill and before decoding can begin, they extend the TTFT critical path, as shown in the following timeline.

Pull-mode timeline: router relay, decode-side allocation, and NIXL READ run serially on the path to first token.

Figure 1: Pull-mode KV transfer timeline, where the router relay, decode-side allocation, and NIXL READ run serially on the path to the first token

This post introduces a push-based NIXL connector that moves post-prefill transfer coordination and setup off the critical path. If you run disaggregated prefill/decode inference with vLLM, push mode can improve application responsiveness by reducing TTFT and TPOT, particularly at high request rates.

In our benchmark on a 1P1D deployment using Amazon Elastic Compute Cloud (Amazon EC2) P5en instances connected with EFA, push mode delivered up to 3x better TTFT and up to 30 percent better time-per-output-token (TPOT) compared to pull mode (see the Performance data section) for the Qwen3-32B model. Results depend on workload and configuration.

We built and validated the feature on AWS Trainium instance clusters connected with EFA, and then we contributed it to vLLM as an accelerator-agnostic feature. The results here are from an Amazon EC2 P5en (GPU) cluster with EFA, showing the gains carry over to GPUs. This post explains the push-based architecture, transfer flow, threading model, performance results, and how to reproduce the benchmark.

Push-based KV transfer

This section explains the push-based design: its architecture, the transfer protocol, and the threading model that keeps KV transfer off the critical path.

Architecture overview

Push-based transfer improves TTFT and decode throughput for two reasons:

  1. It removes the serialization of the pull model by overlapping producer and consumer work. The decode instance registers its target blocks in advance while the producer is still computing KV. The transfer then begins as soon as the producer’s blocks are ready, rather than after a consumer-side ID-discovery round trip, removing that round trip from the path to first token.
  2. It moves the transfer-setup time off the decode instance. That setup runs on the prefill side and on a background thread. It prepares the NIXL descriptors and submits the transfer, so the decode instance does not spend those cycles during its latency-critical token-generation phase.

The net effect is lower TTFT and higher output-token throughput on the decode instance.

The push connector coordinates three actors: the decode instance registers its target blocks up front, the prefill instance matches each request and issues the transfer, and a dedicated background thread carries the KV write off the engine’s forward-pass loop. The following diagram shows how these pieces fit together.

Push-based KV transfer architecture overview

Figure 2: Push-based KV transfer architecture, showing how the decode instance, prefill instance, and background transfer thread coordinate

Implementation details

The protocol has three logical steps.

1. Registration (decode side). When the decode instance allocates local blocks for a request requiring remote prefilling, it prepares a registration describing where the prefill instance should write the KV: its own identity and the block locations it has just reserved. Within the same engine step, the worker transmits this registration to the prefill instance as a NIXL notification. Because registration happens at allocation time, the connector knows the destination blocks before the prefill instance completes prefill.

2. Rendezvous (prefill side). The registration from the decoder and the completion of prefill on the producer can arrive in either order, and the connector handles both. If the registration arrives first, the producer holds it until its own prefill finishes. If prefill finishes first, the producer holds the request’s blocks until the registration arrives. Whichever event happens second triggers the transfer. The connector pairs requests by ID, and the matching accounts for reissued requests, correctly associating preempted or retried requests.

3. Transfer (prefill side). Once a request is matched, the producer establishes a connection to the decode instance (if one does not already exist) and issues an NIXL WRITE that copies the KV blocks directly into the decoder’s registered memory, addressing each destination tensor-parallel rank. The producer and consumer may use different internal block layouts. Each side maps block locations to its own physical layout at transfer time, allowing different block sizes on each side. Each WRITE carries a completion notification that NIXL delivers to the decode instance once the data arrives. The decoder counts these notifications, one per producer rank that writes into it. It treats the KV as received only after all expected notifications have arrived, at which point the request proceeds to decode.

Threading model

The push connector separates model execution from KV-transfer preparation by using a dedicated background transfer thread on each prefill worker. At the start of a request, the decode main loop allocates its destination KV blocks and registers them with the prefill instance while the prefill main loop computes the prompt KV cache. After both the destination registration and prompt KV are ready, the prefill main loop hands the KV blocks to the background thread and quickly returns to model execution.

The background thread establishes or reuses the NIXL connection, maps the request’s KV block IDs to memory descriptors, merges contiguous blocks into larger transfer regions, and submits the NIXL WRITE to the decode instance. When NIXL completes the transfer, it sends a completion notification to the decode instance, which then begins token generation. Keeping descriptor preparation and transfer submission off the latency-critical main loops prevents this per-request work from delaying model execution. The following diagram shows these main-loop and background-thread handoffs for a single request.

Threading model showing the decode and prefill main loops handing KV blocks to a background thread that performs the NIXL transfer off the forward-pass loop

Figure 3: Main-loop and background-thread handoffs for a single request in the push-based threading model

Timing comparison of pull and push

The following diagram summarizes the pull and push transfer flows described in the preceding sections and highlights their effect on TTFT. Although both modes use the same NIXL and EFA/RDMA data path, pull performs the metadata relay and decode-side setup after prefill, while push overlaps decode-side setup with prefill. As a result, push removes these operations from the post-prefill critical path, allowing decoding to begin sooner.

Side-by-side timeline comparing pull and push KV transfer, showing push overlapping decode-side setup with prefill to shorten the path to the first token

Figure 4: Pull and push transfer flows compared, highlighting how push overlaps decode-side setup with prefill

The two modes also involve a routing tradeoff. Pull mode allows the router to select a decode instance after prefill completes, which provides greater flexibility for load-aware routing and quality-of-service management. Push mode selects the decode instance earlier so that destination setup can overlap with prefill. In return, under comparable load, the prefill instance can release its KV blocks sooner because the transfer starts as soon as both the prompt KV and destination registration are ready.

Performance data

For evaluation, we used Qwen3-32B model on a 1P1D deployment using Amazon EC2 P5en instances connected with EFA. To isolate P→D transfer performance, we configured the benchmark to disable prefix caching with --no-enable-prefix-caching. This configuration makes the decode node retrieve the full KV cache from the prefill node for every request. Otherwise, overlapping prompts could reuse the decode node’s local cache and bypass the transfer, which would produce misleading comparison results.

The following chart compares TTFT for push and pull KV transfer. We sweep input lengths 1k–16k and request rates of 1–8 queries per second (QPS). At low load and short prompts, the two modes perform almost identically. As QPS and input length grow, pull mode degrades sharply, reaching about 1,744 ms at 8 QPS and 16k. Push mode stays far lower at roughly 540 ms, around 3x reduction. The gap opens because pull mode posts NIXL descriptors inline on the decode worker, synchronously within its engine loop, so that work stalls token generation. Push mode moves it to a background thread, off the critical path.

Four-panel TTFT comparison of push and pull KV transfer for Qwen3-32B on Amazon EC2 P5en instances with EFA. Test configuration: 1P1D topology, 128 output tokens, and prefix caching disabled on the Decode node.

Figure 5: TTFT for push compared to pull KV transfer across input lengths and request rates (1P1D topology, 128 output tokens, prefix caching disabled on the decode node)

This chart shows TPOT under the same conditions. The pattern mirrors TTFT. At light load, push and pull are close, around 5.6–5.8 ms. As load and input length rise, pull climbs to about 10.4 ms at 4–8 QPS and 16k, while push holds near 7 ms. The reason is that push offloads descriptor preparation and transfer submission from the decode worker. Token generation is not starved, so per-token latency stays flat even at high concurrency and long contexts.

Four-panel TPOT comparison of push and pull KV transfer for Qwen3-32B on Amazon EC2 P5en instances with EFA. Test configuration: 1P1D topology, 128 output tokens, and prefix caching disabled on the Decode node.

Figure 6: TPOT for push compared to pull KV transfer across input lengths and request rates (1P1D topology, 128 output tokens, prefix caching disabled on the decode node)

How to run benchmark

To reproduce our 1P1D benchmark configuration, one prefill node and one decode node, using Amazon EC2 P5en instances connected with EFA, refer to the detailed instructions in the Reproducing our results guide. The guide covers environment setup, launching the vLLM prefill and decode servers, running the benchmark, and collecting results. The feature can run on other supported configurations, but performance results will vary depending on the hardware, model, workload, and network configuration.

Conclusion

In this post, we showed how the push-based KV connector overlaps prefill computation with decode-side block allocation and registration, removing the post-prefill router round trip and decode-side transfer setup from the critical path. This reduces TTFT and TPOT, particularly at high request rates. In our Qwen3-32B benchmark on a 1P1D deployment using Amazon EC2 P5en instances connected with EFA, push mode provided up to a 3x improvement in TTFT and 30 percent improvement in TPOT compared with pull mode. Results vary by workload and configuration. To use push mode, configure both the prefill and decode servers to use NixlPushConnector instead of NixlConnector.

Choose the push-based connector when early decode node selection is acceptable and lower TTFT is the priority. The pull-based connector remains the better fit for workloads that require bidirectional KV transfer or defer decode-instance selection until after prefill for load-aware routing. vLLM supports both push- and pull-based KV connectors, so you can select the approach that best fits your deployment.

As a future improvement, we are exploring bringing the background NIXL threading model to the pull-mode connector, moving NIXL setup off the critical path so that pull-mode workloads could benefit from the same optimizations. We have opened a pull request to explore this.

Acknowledgments

We thank the vLLM community for their support in maintaining this feature.

 


About the authors

Sunita Nadampalli

Sunita Nadampalli

Sunita is a Principal Engineer and AI/ML expert at AWS. She leads AWS Trainium and AWS Graviton software performance optimizations for AI/ML workloads. She is passionate about open-source software development and delivering high-performance and sustainable software solutions.

Nicolò Lucchesi

Nicolò Lucchesi

Nicolò is a Research Engineer at Mistral, where he leads the Inference Foundation team. He is a vLLM maintainer, with a background in fast inference for LLMs and Computer Vision.

Push-based KV transfer to improve TTFT and TPOT for disaggregated inference in vLLM
Author: Sunita Nadampalli