Skip to content

KVCacheAware Plugin Scoring Latency Too High — Optimize with Caching #1100

Description

@YaoZengzeng

Problem

The KVCacheAware.Score plugin in the kthena-router introduces significant latency per request, typically ranging from 30ms to 100ms per scoring call. Under concurrent workloads (e.g., multi-turn conversations), this latency adds up and becomes a bottleneck for request routing.

Observed Latency (from production logs)

KVCacheAware.Score: completed in 57.139784ms
KVCacheAware.Score: completed in 31.290123ms
KVCacheAware.Score: completed in 85.288769ms
KVCacheAware.Score: completed in 100.34733ms
KVCacheAware.Score: completed in 76.064469ms
KVCacheAware.Score: completed in 72.113914ms
...

Average latency is approximately 50-60ms, with spikes exceeding 100ms. Under high concurrency scenarios, this significantly impacts overall request throughput and tail latency.

Test Script

The issue was reproduced using the following multi-turn conversation benchmark script:
https://github.com/YaoZengzeng/scripts/blob/master/aiperf/multi-turn-conversation.sh

Environment

  • Model: Qwen (0.6B) with 3-4 replicas
  • Backend: vLLM
  • KV cache metadata stored in Redis

Root Cause Analysis

The Score function (pkg/kthena-router/scheduler/plugins/kvcache_aware.go) performs two expensive operations on every single request:

  1. Tokenization (normalizeAndTokenizePrompt): Each incoming prompt must be tokenized to compute block hashes. This involves loading and invoking the tokenizer for the target model on every request, even for multi-turn conversations where prior turns have already been tokenized.

  2. Redis Query (queryRedisForBlocks): After tokenization, the plugin queries Redis via a pipeline to check which pods have cached the corresponding KV blocks. Even though pipelining is used, the network round-trip and per-block hash lookup add consistent overhead.

Both operations are performed from scratch on every scoring call, with no reuse of previously computed results.

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions