Skip to content

ClickStack vs Loki+Prom Comparison

Evaluation runbook for the vector + ClickStack migration.

Evaluation window: 1 month minimum, 3 months maximum from PR1 merge.

Decision date: TBD (set when PR1 merges)

These differences are expected and do not count toward dimension 3’s “zero data-loss incidents”:

  • Log serialization: Loki LogQL line vs OTel LogRecord body/attributes
  • Log transport: Loki HTTP push vs OTLP gRPC
  • Metric semantics: Prom remote_write preserves data model exactly; OTLP path converts to OTel model (histogram re-bucketing, summary lossy mapping, staleness markers absent)
  • Timestamp precision: Prom ms vs OTel ns
  • Counter resets: Prom transmits resets; OTel cumulative conversion can mask or amplify reset artifacts

Dimension 1: Query Parity (target: all 10 queries expressible)

Section titled “Dimension 1: Query Parity (target: all 10 queries expressible)”
#QueryLoki/Prom expressionHyperDX expressionEquivalence
1Last 1h pod crash countcount_over_time({namespace="X"} |= "CrashLoopBackOff"[1h])kubernetes.namespace_name:X AND message:CrashLoopBackOffTBD
2Cert expiring in 7d(probe_ssl_earliest_cert_expiry - time()) / 86400 < 7SQL on otel_metrics_gaugeTBD
3(to be filled pre-evaluation)TBD
4(to be filled pre-evaluation)TBD
5(to be filled pre-evaluation)TBD
6(to be filled pre-evaluation)TBD
7(to be filled pre-evaluation)TBD
8(to be filled pre-evaluation)TBD
9(to be filled pre-evaluation)TBD
10(to be filled pre-evaluation)TBD

Dimension 2: Investigation Speed (target: HyperDX first-reach >50% weeks 3+, n>=10)

Section titled “Dimension 2: Investigation Speed (target: HyperDX first-reach >50% weeks 3+, n>=10)”
DateQuestionStack opened firstStack that resolvedNotes
(filled in during eval)

Resource consumption snapshots (weekly):

WeekClickStack CPU/mem/diskLoki+Prom CPU/mem/diskRatioNotes
1baseline

Mongo-down incidents: count and timestamps (per “Mongo-down incident” definition in spec).

Disruption baseline (Loki LogQL):

count_over_time({job="kubernetes-events"} |~ "(?i)node draining|Cordoned|Drained" [<BASELINE_WINDOW>])

Result captured in audit doc; eval-window incidents rate-normalized against this baseline.

Attempted: (describe HyperDX dashboard-as-code attempt here)

Outcome: (pass/fail with rationale)

Auto-clustering value:

  • (date, observation, did it surface something Grafana would not?)

NL-to-query value:

  • (date, observation)

Anomaly detection:

  • (date, observation)

Hard dimensions won (out of 4 or 3 depending on dim-2 sample size):

  • Dim 1: WIN / LOSS / UNCLEAR
  • Dim 2 (hard if n>=10): WIN / LOSS / INFORMATIONAL
  • Dim 3: WIN / LOSS / UNCLEAR
  • Dim 4: WIN / LOSS / UNCLEAR

Path selected: A / B / C

Rationale: …

Next-step PR: …