Back to home@shengbinxu

dsh-llm-latency

No description

Stars
0
Language
TypeScript
Created
Aug 29, 2026
Updated
Aug 29, 2026
GitHub repo

Introduction

dsh-llm-latency

English · 中文

Per-vendor / per-model / per-session LLM latency and cache-hit telemetry for DeepSeek Harness. It answers with numbers: "which vendor is actually faster, and whose cache hits better — for the same model, over the same period?"

  • Passive telemetry — every real model call is measured (first token, end-to-end, tokens/sec, cache-hit share) and classified by failure kind (429 / timeout / 5xx / abort).
  • Three comparisons:
    1. Overview — rank all vendor·model rows over any time window.
    2. Time-window — same model across vendors over an arbitrary window (e.g. today 10:00–10:30), with P50/P90/P95/P99, failure rates, cache-hit rate, sample counts, and median significance.
    3. Session — run the same prompt in two sessions, each pinned to one vendor's model, then compare the whole runs; valid only when a session never switched models.
  • Dashboard + tool — a self-contained HTML dashboard (overview / time-window / session / request-log views) plus the latency_report model tool and CSV export.
  • Request log — every model call is persisted as one record (time, vendor, model, session, request id, credential ref, TTFT, end-to-end, input/output tokens, cache-hit rate, status), searchable and filterable in the dashboard.

See DESIGN.md for the data model and comparison methodology.

Screenshots

Overview — rank every vendor·model row over a time window.

Overview

Time-window — the same model across vendors, with P50/P90/P95/P99, failure rates, cache-hit rate, and median significance.

Time-window comparison

Session — compare two single-model sessions side by side.

Session comparison

Request log — search and filter every model call.

Request log

Install

dsh plugin --profile web add github:shengbinxu/dsh-llm-latency

Then restart the profile. The plugin applies after dsh-base (it needs the llm service), intercepts llm/stream, and serves the dashboard at:

http://127.0.0.1:3080/llm-latency/

Usage

  • Dashboard — switch between 总览 / 时段对比 / 会话对比 / 请求日志:
    • 时段对比: pick a model, pick a window, compare vendors side by side.
    • 会话对比: pick two sessions that each used a single model, compare them.
    • 请求日志: search and filter every model call by request id, vendor, model, session, credential ref, or status.
  • Model tool — ask the agent "帮我看看各厂商延迟对比" (latency_report); it accepts model, vendors, from/to, and sessionIds.

Where data lives

Aggregates persist at $DSH_HOME/llm-latency/stats.json (default ~/.dsh/llm-latency/stats.json). Delete the file to reset. The request log is append-only at $DSH_HOME/llm-latency/requests.jsonl.

Metrics

  • TTFT (primary) — time to first content chunk; e2e — full stream; tok/s — decode throughput.
  • Cache-hit ratecacheRead / (input + cacheRead + cacheWrite); cache-write ratecacheWrite / (input + cacheRead + cacheWrite).
  • Failure breakdown — 429 (rate-limited), timeout, 5xx, abort, other, each as a share of attempts. Retries are separate llm/stream calls, so a 429 is recorded as an attempt-level failure.

Comparison methodology

Same-model cross-vendor comparisons always slice every vendor to the same time window. Percentiles come from merged histograms; the median's 95% bootstrap confidence interval comes from the recent sample ring when the window has enough samples (minSamplesForComparison). Two vendors differ significantly when their median CIs do not overlap. Insufficient samples and gross sample imbalance are flagged.

Configuration

Set in cordis.patch.yml (or override the row):

KeyDefaultMeaning
retentionDays30Data retention window in days
recentLimit2000Per-key exact-sample ring cap
sessionLimit500Sessions retained (most recent first)
spikeFloorMs10000TTFT above this counts as a spike
modelAliases{}Canonical model → provider model ids
minSamplesForComparison20Minimum ok samples before a median CI is reported
logLimit5000Request-log mirror cap (recent records kept)
logRetentionDays7Request-log retention window in days

How it works

The plugin registers a waterfall listener on llm/stream, wraps the returned AsyncIterable<StreamChunk>, and starts its clock on the first pull — the moment the adapter lazily issues the HTTP request. Failures carry the harness LlmFailure.code/.status, mapped to the five-class taxonomy above.

License

MIT