Troubleshooting · Streaming observability
Streamwake reliability agents

Tie QoE metrics to the CDN edge
spot the gap and fix it.

A working guide to the QoE metrics that actually move live and on-demand delivery — rebuffer ratio, video-startup time, manifest-fetch failures, segment-fetch failures by CDN, CDN hit ratio, origin-shield health, and per-(CDN, geo) error rate. Covers the instrumentation blind spots that sit between the transcoding pipeline and the CDN edge, and how Streamwake's agentic ops layer bridges them: ranked root cause plus a recommended fix on every refresh.

Protocol: OBSERVABILITY
Format: metrics + edge telemetry
Streamwake probes: rebuffer · startup · manifest · segment · hit ratio · origin shield · edge error rate.

Book a technical demo for Streaming observability

Lead magnet
Streaming observability

Read the postmortem — then bring your own incident to Streamwake.

Two ways to engage on this exact failure pattern: book a 30-minute technical demo where we walk through the probe cascade on your source, or hand us an archived incident and watch the agent diagnose it end-to-end.

Both routes land on the scoping intake form — no SDR gate.

Probes

What Streamwake checks

Five families of probes, each with a small, deterministic pass/fail verdict that reads both player-side and edge-side telemetry. Every check has a name — that's the name you'll see on the agents feed.

Player QoE
qoe.rebuffer_ratio + qoe.video_startup_time
player · events
  • rebuffer_ratio across session windows (0.5%/5%/24h) — warn above 0.5%, fail above 2%.
  • video-startup time from manifest fetch to first frame; budget ≤ 2.5s p75.
  • Join time across cohort — p50/p75/p95 read alongside the per-session rebuffer ratio.
Manifest fetches
manifest.fetch_failures + manifest.fetch_latency
m3u8 · mpd
  • Failure rate under 0.1% over 5 min; p95 fetch latency ≤ 250ms.
  • Detect partial-consistent failures across regions — aggregate green, geo red.
  • Stale-while-revalidate serving masked as a successful manifest fetch is flagged via Warning: 110 + age > max-age.
Segment fetches
segment.fetch_failures_by_cdn + segment.fetch_latency_by_cdn
per-(cdn · pop)
  • Per-CDN, per-POP segment-fetch success rate — outlier cells must surface, not dilute.
  • 5xx share tracked separately from connection-time / first-byte timeouts.
  • Outlier-POP detection vs the same CDN's healthy POPs — the partial-consistent cell mix names the failing POP exactly.
CDN cache state
cdn.hit_ratio + origin.shield_health
cache · shield
  • hit_ratio on the manifest path ≥ 95% within the probe window — fail below.
  • Shield bypass rate without a shield fault → reroute-rule regression flagged.
  • Shield saturation flagged when shield latency > capacity under load, even when no x-cache: ERROR is emitted.
Edge error rate
edge.error_rate_per_pop + edge.egress_health
per-(pop · geo)
  • Per-(provider, POP, geo) 5xx count — scoped, not aggregate.
  • 4xx vs 5xx isolated — 4xx is application, 5xx is edge. Don't discount 4xx either.
  • Egress saturation: bandwidth ratio approaching ceiling, queue depth growing.
Anatomy

Anatomy of an observability packet

The five things the agents actually probe at observability cadence — a player event timeline, an edge access log, a manifest metrics push, a ranked root-cause verdict, and the agent timeline that ties them together with a recommended fix and rebalance hints.

Player event timeline (rebuffer + startup + segment fetch)
{
  "session_id": "cksliveobs-sess-7421",
  "player": "streamwake/2.4.1",
  "events": [
    { "ts": "2026-08-06T10:42:11.002Z", "type": "MANIFEST_FETCH",  "cdn": "cdn-A/fra02", "dur_ms": 182 },
    { "ts": "2026-08-06T10:42:11.547Z", "type": "FIRST_FRAME",     "elapsed_ms": 545 },
    { "ts": "2026-08-06T10:42:14.114Z", "type": "SEGMENT_FETCH",   "cdn": "cdn-A/fra02", "dur_ms": 88 },
    { "ts": "2026-08-06T10:42:15.031Z", "type": "SEGMENT_FETCH",   "cdn": "cdn-A/fra02", "dur_ms": 94 },
    { "ts": "2026-08-06T10:42:16.230Z", "type": "REBUFFER_START",  "reason": "segment_404", "cdn": "cdn-A/fra02" },
    { "ts": "2026-08-06T10:42:18.974Z", "type": "REBUFFER_END",    "rebuffer_ms": 2744 },
    { "ts": "2026-08-06T10:42:19.012Z", "type": "SEGMENT_FETCH",   "cdn": "cdn-A/fra02", "dur_ms": 79 }
  ],
  "summary": {
    "video_startup_time_ms": 545,
    "rebuffer_ratio_session": 0.018,
    "segment_fetch_p95_ms": 94
  }
}
Edge access log (per-segment)
cdn-A/fra02 - - [06/Aug/2026:10:42:14 +0000] "GET /live/event/seg1237.m4s HTTP/2" 200 871244 "-" "-" 94 "x-cache=MISS" "x-served-by=cache-fra6123"
cdn-A/fra02 - - [06/Aug/2026:10:42:15 +0000] "GET /live/event/seg1238.m4s HTTP/2" 404    312 "-" "-" 21 "x-cache=MISS" "x-served-by=cache-fra6123"
cdn-A/fra02 - - [06/Aug/2026:10:42:15 +0000] "GET /live/event/seg1238.m4s HTTP/2" 200 871312 "-" "-" 78 "x-cache=MISS" "x-served-by=cache-fra6123"
cdn-A/fra02 - - [06/Aug/2026:10:42:16 +0000] "GET /live/event/seg1239.m4s HTTP/2" 200 871408 "-" "-" 92 "x-cache=MISS" "x-served-by=cache-fra6123"
# session cksliveobs-sess-7421 read X-Cache: MISS on every segment in the burst;
# cdn-A/fra02 served 1x404 (seg1238) -> rebuffer on the player.
Manifest metrics (CDN-provider push)
{
  "window": "2026-08-06T10:42:10/10:42:20",
  "cdn": "cdn-A",
  "manifest_fetch_count": 43821,
  "manifest_fetch_failures": 19,
  "manifest_fetch_latency_p95_ms": 287,
  "per_geo_breakdown": [
    { "geo": "EMEA", "count": 18201, "failures": 18, "latency_p95_ms": 298, "fail_ratio": 0.00099 },
    { "geo": "AMER", "count": 14751, "failures":  1, "latency_p95_ms": 214, "fail_ratio": 0.00007 },
    { "geo": "APAC", "count": 10869, "failures":  0, "latency_p95_ms": 232, "fail_ratio": 0.0 }
  ],
  "note": "vendor aggregate is staged per-cdn, geo, but the per-POP cells are not; per-cell greens can hide a red POP inside a green geo."
}
Ranked root-cause + recommended fix verdict
{
  "session_id": "cksliveobs-sess-7421",
  "relapse_score": 0.86,
  "ranked_root_cause": [
    { "rank": 1, "hypothesis": "cdn-A/fra02 segment-404 burst",            "evidence": ["edge_access_log.404", "player.rebuffer_start"], "probability": 0.62 },
    { "rank": 2, "hypothesis": "manifest cache-control ttl widened",      "evidence": ["manifest.fetch_latency_p95=287ms"],              "probability": 0.27 },
    { "rank": 3, "hypothesis": "encoder/packager handoff drift",           "evidence": ["packager->cdn.handoff_wait=412ms"],              "probability": 0.11 }
  ],
  "recommended_fix": {
    "title": "Pin next probe to cdn-B for EMEA, tighten manifest cache-control to 1s",
    "actions": [
      { "kind": "rebalance_hint", "value": "pin_segment_to_cdn_B_for_geo_EMEA" },
      { "kind": "config_change",  "value": "manifest.cache-control: max-age=1, must-revalidate" }
    ],
    "verification": "rebuffer_ratio < 0.005 and segment_fetch_p95_ms < 120 over next 5 cycles"
  }
}
Probes → observability packet fields
Quick map from probe verdict to the field you should grep in player or edge telemetry.
  • qoe.rebuffer_ratio → session rebuffer events / playtime
  • qoe.video_startup_time → first-frame epoch − manifest-fetch epoch
  • manifest.fetch_failures → 5xx on *.m3u8/ *.mpd per-(CDN, geo) cell
  • manifest.fetch_latency Server-Timing: manifest;dur=… + edge access log
  • segment.fetch_failures_by_cdn → per-CDN x-cache, via, status
  • segment.fetch_latency_by_cdn Server-Timing: segment-fetch;dur=…
  • cdn.hit_ratio x-cache: HIT vs x-cache: MISS ratio on manifest path
  • origin.shield_health → shield latency p95 + shield bypass rate
  • edge.error_rate_per_pop → 5xx / total per x-served-by POP
  • edge.egress_health → per-POP bandwidth ratio + queue depth

The player event timeline is the QoE substrate: the rebuffer, startup, and segmentFetch events carry the per-segment CDN POP identity. That's where the rebuffer + startup signal originates; the agent reads the timeline once per session and feeds it into qoe.rebuffer_ratio and qoe.video_startup_time.

The edge access log is the CDN-side ground truth that joins player events back to POP identity. Per-segment status + x-cache + x-served-by form the population that segment,cdn.hit_ratio, and edge.error_rate_per_pop read from. The seg1238 404 chain in the sample is exactly the partial-consistent failure pattern those probes fail on.

Manifest metrics from the CDN provider's push are partial on multi-CDN because they aggregate across POPs. Per-(CDN, geo) is exposed by the vendor; per-(CDN, POP, geo) is not. Aggregate-greens can hide a red POP inside a green geo — which is why manifest.fetch_failures needs the per-cell clause to flip to fail when any cell moves past threshold.

The agent's ranked root cause + recommended fix is the bridge. The verdict ranks hypotheses by probability, picks a recommended fix, and emits a rebalance hint to keep streaming green while the fix is shipped. Without the bridge, the page renders numbers but on-call has to do the ranking manually — and on-call has to do it on the same partial-consistent telemetry that hid the failing cell to begin with.

Why rebalance beats alert-only
The agent emits rebalance hints, not just pages.

The QoE-observability surfacing has too much volume for alert-only — too many POPs, too many geo cohorts, too many concurrent metrics. Streamwake ranks hypotheses + emits a rebalance + a recommended fix, so streaming stays green while engineering works the issue. Most failures are remediated before the on-call engineer finishes reading the timeline.

Failure modes

Ten ways observability leaves gaps

Each row: the symptom the player reports → the underlying cause → a fix that holds under the next probe cycle → the rebalance hint the Streamwake agent emits. The rebalance hint is the part the agent does on its own — it routes traffic around the failing cell while engineering works the actual fix.

01Rebuffer ratio flatlines near zero despite obvious stalls
failure mode
Symptom

Dashboards read rebuffer_ratio 0.0% over the rolling-7-day window, but users report clear stalls in session cohorts that the dashboard rolls up. Vendor QoE looks green; users disagree.

Root cause

QoE reporting is feature-flagged off for that session cohort — A/B partition has a fallback to no-emit, so the rebuffer events never reach the analytics pipeline. The cohort missed the QoE source flag.

Recommended fix

Surface the rebuffer signal from player.events.rebuffer directly into the QoE probe pipeline and stop trusting the vendor's aggregate. The qoe.rebuffer_ratio probe reads 0.018 on the player-side cohort that the vendor reports 0.0% on; cross-check both on every cycle until they converge.

Streamwake rebalance

Agent detects missing rebuffer via cross-check vs segment_fetch_latency outliers and emits rebalance_hints=[pin_qoe_source_to_event_pipeline]. The next probe stitches player.events to qoe.rebuffer_ratio on the same window — rebuffer_ratio flips to 1.8% and the failing cell is named.

02Video-startup time creeps upward silently while the SLA dashboard reads green
failure mode
Symptom

p75 video-startup time climbs +18% over the last 7 days. The SLA board stays green throughout because its alerting window is rolling-24h, which dilutes the cohort trend.

Root cause

A CDN cache-control change deployed 7 days ago widened manifest fetch latency from p95=214ms to p95=287ms, dragging startup time with it. The rolling-24h aggregate washes the change out; the rolling-7-day trend is the one that surfaces it.

Recommended fix

Re-time the SLA alert on the p75 of the rolling-7-day cohort, not the rolling-24h aggregate. qoe.video_startup_time should be probed at agent cadence (30s) and the SLA alert should fire when p75 over the cohort hops more than ~10% week on week.

Streamwake rebalance

Agent surfaces the cohort trend, runs manifest.fetch_latency upstream to find the delta, and emits rebalance_hints=[tighten_manifest_cache_ttl_until_rev_checked]. Streaming stays green while engineering re-times the SLA window and rolls back the cache-control change.

03Manifest-fetch failures concentrate on a subset of geo POPs but the aggregate stays flat
failure mode
Symptom

Global manifest_fetch_failures reads 0.04% (green) but a single geo cohort reads 1.8% (red). Viewers in that cohort see consistent manifest timeouts; aggregate-vendor dashboards stay silent.

Root cause

CDN telemetry rollup aggregates per-provider, not per-(CDN, geo). The per-geo breakdown Stage is exposed by the vendor, but the per-POP cells are not; per-cell greens can hide a red POP inside a green geo.

Recommended fix

Scope the manifest.fetch_failures probe per-(CDN, geo) cell and fail the probe when any cell reads >0.5% over the probe window. The qoe→manifest-fetch ladder must read the per-cell value, not the per-provider rollup.

Streamwake rebalance

Agent sees the partial-consistent cell mix on EMEA and emits rebalance_hints=[pin_manifest_to_healthy_geo_pop]. Pin next probes to cdn-B/eu-west for EMEA; the manifest path on cdn-A/fra02 gets capacity headroom while the failing POP is repaired.

04Segment-fetch failures concentrate on one CDN POP cohort with no alert firing
failure mode
Symptom

Viewers in one (CDN, geo) cohort see partial stalls; aggregate CDN-segment-fetch-failure is 0.07% — under the global alerting threshold. The cohort barely moves the global rollup, but the cohort is fully degraded.

Root cause

Outlier cells are diluted by healthy cells in the rolling-1-min aggregate. The aggregate reads green because nine healthy (CDN, geo) cells average out one failing cell; the failing cell never crosses the global threshold.

Recommended fix

Floor the per-cell failure threshold above the cohort-average floor — segment.fetch_failures_by_cdn must read the per-(CDN, geo) cell, not the rolled-up CDN aggregate. The threshold should be in absolute terms (>= 0.5% per cell) not aggregate (>= 0.1% per CDN).

Streamwake rebalance

Agent scopes the failing (CDN, geo) cell and emits rebalance_hints=[route_segment_to_alternate_pop_for_failing_geo]. Pin segment fetches to cdn-B for the failing geo cohort; cdn-A gets isolated while on-call narrows the causal cell.

05CDN hit ratio drops below optimize threshold but the alert fires after user impact
failure mode
Symptom

Dashboard surfaces cdn.hit_ratio below the 95% optimize threshold 4-5 minutes after user-visible rebuffer lifted. The dashboard sample window is wider than the user-impact window; the alert-by-dashboard is too late.

Root cause

The hit-ratio dashboard aggregates over a 5-minute window while the live edge path is computed at a smaller cadence. The optimize-threshold alert kicks in only after the dashboard window closes.

Recommended fix

Emit the cdn.hit_ratio probe at agent cadence (≤30s) and fail the probe below the optimize threshold (95%) within the probe window. The dashboard can stay coarse — the probe is the source of truth.

Streamwake rebalance

Agent pre-warms the edge cache on the next probe cycle and emits rebalance_hints=[prewarm_warm_window_for_manifest_path]. The next probe reads hit_ratio=96% — user-visible rebuffer recovered within a single probe interval, before the dashboard window closed.

06Origin-shield saturation event goes unflagged because shield error rate is gated on a specific status class
failure mode
Symptom

Shield saturation burn but no shield fault log. The shield latency p95 climbed to 612ms and bypass rate is 11%, but the dashboard reads green because the gating metric watches only x-cache: ERROR.

Root cause

The shield-error-rate metric gates on x-cache: ERROR responses — the reroute rule emits x-cache: BYPASS when it bypasses the shield (without an error). Saturation re-routes traffic but the metric never flips to fail because the status reads BYPASS, not ERROR.

Recommended fix

Count bypass-without-fault as a shield-fail class in the probe. The origin.shield_health probe should read shield_latency_p95 + bypass_rate together — bypass-without-fault is a fail even when no ERROR has been emitted.

Streamwake rebalance

Agent detects the bypass-without-fault spike and emits rebalance_hints=[pin_edge_to_origin_direct_until_shield_recovers]. The next probe witnesses origin-direct serving green; shield backpressure releases; bypass rate drops back under 1% within two cycles.

07Edge error rate is monitored only at the aggregate CDN level — per-(POP, geo) error rates stay invisible
failure mode
Symptom

A CDN provider's aggregate error rate reads 0.4% (green), but a single geo cohort reads 6.1% (red). Vendor dashboards aggregate over CDN provider, not per (provider, POP, geo) — the failing cell never reaches the dashboard.

Root cause

Vendor reports aggregate CDN health, not per-cell. The aggregate-greens hide a red POP inside a green geo, and on-call never sees the failing cell because the alerting window rolls up to the CDN provider level.

Recommended fix

Scope the edge.error_rate_per_pop probe to per-(provider, POP, geo) cell and tag the failing cell by its POP identity. Aggregate thresholds should be derived from the per-cell view, not the other way around.

Streamwake rebalance

Agent scopes the failing cell (cdn-A/fra02, EMEA) and emits rebalance_hints=[route_egress_to_alternate_pop_for_failing_geo]. Pin egress to cdn-B/eu-west for EMEA; the failing cell on cdn-A/fra02 gets capacity headroom and on-call is paged for the single cell, not the whole provider.

08Encoder/packager handoff: packager segment emits before init.mp4 lands at the edge
failure mode
Symptom

A burst of client errors reads 'MSE SourceBuffer init failure on first segment'. Init.mp4 hasn't been pre-warmed at the edge when the first segment lands; the player fetch races the CDN ingest.

Root cause

Packager emits segment asynchronously from CDN ingest. The instrumentation on each side ends at the silo boundary — packager telemetry and CDN ingest telemetry lack a shared join, so the handoff wait is never timed.

Recommended fix

Bridge the gap by registering a packager->cdn.handoff_wait probe that times segment-emit to edge-readable on the first cycle. The probe should fire when handoff wait exceeds 500ms — the budget the player's startup path assumes.

Streamwake rebalance

Agent bridges the packager/CDN telemetries and emits rebalance_hints=[prewarm_init_for_new_session]. Pin the next init probe to cdn-B for EMEA cohort; pre-warm the edge cache on init.mp4 so the player read races the CDN ingest correctly.

09License/DRM handoff: license latency is logged by the license proxy but not joined to the playback-session regression banner
failure mode
Symptom

4% of sessions show +3s on video-startup time. License-first-byte latency correlates — but the regression banner reads video-startup time without naming the license-fetch path.

Root cause

License proxy is a separate observability silo. Either-side metric alone misses the join — qoe.video_startup_time looks green except in the 4% cohort, and license.first_byte looks green except on assets with high keyserver latency.

Recommended fix

Emit a probe that joins qoe.video_startup_time with license.first_byte per session and flags the correlation. The probe should fire when both metrics move in tandem above their per-session thresholds.

Streamwake rebalance

Agent surfaces the license-fetch path in the timeline and emits rebalance_hints=[pin_license_to_alternate_keyserver_pop]. Pin the next license probe to a keyserver POP with a healthy first-byte profile; video-startup time drops below budget within the next three cycles.

10Per-CDN egress: a CDN provider shows healthy aggregate but error rate on a geo POP cohort explodes
failure mode
Symptom

Aggregate egress healthy across CDN. One geo cohort shows egress queue depth climbing and 5xx climbing within the same cohort. Aggregate vendor dashboards read green; the cohort is fully degraded.

Root cause

Vendor reports aggregate CDN health, not per-cell. The aggregate reads green because nine healthy (CDN, geo) cells average out one failing cell; the failing cell never reaches the alerting threshold at aggregate.

Recommended fix

Surface edge.egress_health as a per-cell (CDN, geo) probe and tag the failing cell by its POP identity. The bw_ratio and queue_depth metrics must be per-cell, not aggregate; the threshold should fire when per-cell bw_ratio >= 0.85 or queue_depth grows 3x in 5 minutes.

Streamwake rebalance

Agent scopes the failing cell (cdn-A/fra02) and emits rebalance_hints=[route_egress_to_alternate_pop_until_egress_recovers]. Pin egress to cdn-B/eu-west for EMEA; cdn-A/fra02 gets capacity headroom while on-call narrows the causal cell.

Diagnose

Diagnose with Streamwake

Register the OBSERVABILITY probe against POST /api/v1/streams, then read the agent timeline back through GET /api/v1/agents. The probe verdicts in the timeline are exactly the rows above — rebuffer, startup, manifest, segment, hit ratio, origin shield, edge error rate. The agent.ranked_root_cause and agent.recommended_fix blocks name the decision the agent emitted on every refresh.

The curl below registers a live source URL with a 30-second probe cadence. The OBSERVABILITY protocol routing makes the agent run all five probe families on every refresh — and the agent timeline surfaces each verdict plus a ranked root cause plus a recommended fix plus the rebalance hints the agent emits when a probe fails.

The cookie is the same better-auth.session_token that gates every /api/v1/* call — see the auth guide for how to mint one.

POST /api/v1/streams
curl -X POST https://streamwake.polsia.io/api/v1/streams \
  -H "content-type: application/json" \
  -b "better-auth.session_token=<your-session-cookie>" \
  -d '{
    "sourceUrl": "https://cdn.example.com/live/event/manifest.m3u8",
    "protocol": "OBSERVABILITY",
    "probeIntervalSeconds": 30,
    "agents": [
      "qoe.rebuffer_ratio",
      "qoe.video_startup_time",
      "manifest.fetch_failures",
      "manifest.fetch_latency",
      "segment.fetch_failures_by_cdn",
      "segment.fetch_latency_by_cdn",
      "cdn.hit_ratio",
      "origin.shield_health",
      "edge.error_rate_per_pop",
      "edge.egress_health"
    ]
  }'
GET /api/v1/agents?stream_id=…
curl https://streamwake.polsia.io/api/v1/agents?stream_id=<id> \
  -b "better-auth.session_token=<your-session-cookie>"
Agent timeline response (trimmed)
{
  "stream_id": "ckobsstreaming-7421",
  "source": "https://cdn.example.com/live/event/manifest.m3u8",
  "protocol": "OBSERVABILITY",
  "checked_at": "2026-08-06T10:42:20.014Z",
  "checks": [
    { "probe": "qoe.rebuffer_ratio",              "result": "fail", "value":     0.018,  "threshold":     0.005, "detail": "session rebuffer_ratio=1.8% > 0.5% warn — burst of rebuffer events tied to cdn-A/fra02 segment 404 chain" },
    { "probe": "qoe.video_startup_time",          "result": "pass", "value_ms":  545,    "threshold_ms":  2500,  "detail": "first-frame under 2500ms budget — manifest-to-first-frame reads 545ms p75" },
    { "probe": "manifest.fetch_failures",         "result": "pass", "value":     0.00043, "threshold":    0.001, "detail": "global manifest_fetch_failures 0.043% under 0.1% threshold even though EMEA cell reads 1.8%" },
    { "probe": "manifest.fetch_latency",          "result": "warn", "value_ms":  287,    "threshold_ms":  250,   "detail": "p95 fetch latency 287ms > 250ms budget on cdn-A/fra02 — manifest cache-control widened 7 days ago" },
    { "probe": "segment.fetch_failures_by_cdn",   "result": "fail", "per_cdn": { "cdn-A": { "fail_ratio": 0.0049, "outlier_pop": "cdn-A/fra02" }, "cdn-B": { "fail_ratio": 0.0003 } }, "detail": "cdn-A/fra02 segment-fetch fail_ratio 0.49% vs healthy 0.03% on cdn-B — partial-consistent cell mix" },
    { "probe": "segment.fetch_latency_by_cdn",    "result": "warn", "per_cdn": { "cdn-A/fra02":   { "p95_ms": 412 }, "cdn-B/eu-west": { "p95_ms":  79 } }, "detail": "cdn-A/fra02 segment p95 latency 412ms — cdn-B/eu-west reads 79ms healthy" },
    { "probe": "cdn.hit_ratio",                   "result": "warn", "value":     0.91,    "threshold":     0.95,  "detail": "hit_ratio 91% under 95% optimize threshold — cdn-A/fra02 served MISS on every probe" },
    { "probe": "origin.shield_health",            "result": "fail", "shield_latency_p95_ms": 612, "bypass_rate": 0.11, "bypass_without_fault": true, "detail": "shield bypass rate 11% — bypass-without-fault spike means reroute rule mis-configured" },
    { "probe": "edge.error_rate_per_pop",         "result": "fail", "per_cell": { "cdn-A/fra02": 0.061, "cdn-A/eu-west": 0.004, "cdn-B/eu-west": 0.001 }, "detail": "cdn-A/fra02 error rate 6.1% vs healthy < 0.5% — cell mix partial-consistent" },
    { "probe": "edge.egress_health",              "result": "warn", "per_cell": { "cdn-A/fra02": { "bw_ratio": 0.92, "queue_depth": 412 } }, "detail": "cdn-A/fra02 egress bandwidth 92% ceiling; queue depth climbing" }
  ],
  "ranked_root_cause": [
    { "rank": 1, "hypothesis": "cdn-A/fra02 segment-fetch failures cluster",            "probability": 0.62 },
    { "rank": 2, "hypothesis": "manifest cache-control widened 2026-07-30 deploy",      "probability": 0.27 },
    { "rank": 3, "hypothesis": "encoder/packager handoff drift on packager->cdn edge",  "probability": 0.11 }
  ],
  "recommended_fix": {
    "title": "Pin segment fetches to cdn-B for EMEA; tighten manifest cache-control to max-age=1",
    "verification": "rebuffer_ratio < 0.005 and segment_fetch_p95_ms < 120 over the next 5 probe cycles"
  },
  "agent_rebalance_hints": [
    "pin_segment_to_cdn_B_for_geo_EMEA",
    "tighten_manifest_cache_control_to_1s",
    "reroute_shield_bypass_to_origin_direct"
  ],
  "summary": {
    "first_failing_probe": "qoe.rebuffer_ratio",
    "ranked_root_cause_top": "cdn-A/fra02 segment-fetch failures cluster",
    "estimated_viewer_impact_pct": 14.2,
    "fix_window_minutes": 8
  }
}
Next step

Want Streamwake to catch this on its own?

Sign up, register an OBSERVABILITY probe, and the same rebuffer / startup / manifest / segment / hit-ratio / shield / edge-error-rate probes that produced the timeline above run on every refresh — and surface in a Slack channel, a webhook, or the streams dashboard.

Need Streamwake on one of your incidents?
Would you like Streamwake to analyze one of your historical incidents and show where AI could reduce investigation time? (Filed under: Streaming observability.)
Incident analysis
  • Pick a recent on-call incident — manifest stall, edge miss, player-side stall, or peer congestion.
  • We replay it through the same reliability-agent probe cascade used on the postmortem above.
  • You walk away with a written what-could-have-been-Automated readout, not a sales deck.
Back to library

Read the next protocol guide

The other live entries cover the canonical protocol-by-protocol failure patterns.