Katkat

Design a Count-Metrics Monitoring Platform

StripeSoftware Engineer · Onsite

Last updated

Design a scalable count-metrics monitoring and alerting platform capable of tracking real-time event counts and rates, grouping by dimensional labels, handling duplicate/late events, and enforcing cardinality limits.

Scenario

Financial infrastructure platforms process millions of mission-critical operations per minute, such as payment authorizations, webhook deliveries, and API requests. Engineering and operations teams rely on a count-metrics platform to monitor traffic, compute rates (e.g., error rates, requests per second), slice counts across dimensional tags (e.g., merchant_id, http_status, currency), and fire alerts within seconds of an anomaly.

Design a distributed metrics ingestion, aggregation, and querying platform specialized for count metrics.

Requirements

Functional Requirements

  • Metric Ingestion: Accept count increment events with timestamps, metric names, and key-value labels.
  • Aggregation & Rates: Support real-time queries for rollups (e.g., 1-minute, 5-minute, 1-hour tumbling/sliding windows) and derived rates (e.g., count per second, error ratio).
  • Dimensional Grouping: Allow filtering and grouping by arbitrary labels (e.g., group by merchant_id, status_code).
  • Alerting Engine: Continuously evaluate user-configured alert rules (e.g., "alert if failed_charges / total_charges > 0.05 over a 5-minute window").
  • Late Data & Deduplication: Handle late-arriving events (up to 1 hour late) and deduplicate idempotency keys or message IDs.
  • Historical Replay & Retention: Allow replaying ingested logs to recompute metrics after logic changes or outages; maintain downsampled historical data.

Non-Functional Requirements

  • Scale: Ingest 1,000,000 events/second at peak. Support query latencies under 500 ms for dashboards and under 30 seconds for alert evaluations.
  • High Availability: 99.99% availability for ingestion; metric loss must be under 0.001%.
  • Cardinality Protection: Defend against label cardinality explosion (e.g., accidental inclusion of unique request_id as a label).

Deliverables

  1. High-Level Architecture: Ingestion pipeline, stream processing layer, storage engines, and alerting service.
  2. Data Model & Aggregation Strategy: Time-bucketed counter formats, rollup hierarchies, and handling late/duplicate events.
  3. Cardinality Control: Strategies for detecting, throttling, or dropping high-cardinality keys.
  4. Storage & Retention Tiering: Separation of real-time and historical cold storage, and how metric replay works without impacting live traffic.

Hints

Hint 1

Differentiate the ingestion path between immediate stream processing for near-real-time alerting and a persistent log (e.g., Kafka/WAL) that allows deterministic replay.

Hint 2

Consider sliding time buckets (e.g., 10-second sub-buckets) to compute arbitrary sliding window rates without re-reading raw individual events.

Hint 3

Address high-cardinality label attacks using token-bucket rate limiting per label set, HyperLogLog for distinct estimations, or an explicit allowlist/denylist mechanism.

Follow-up questions

  • How would you ensure exactly-once aggregation semantics when consumer nodes crash mid-window?
  • If a merchant sends 100,000 new distinct label values within 10 seconds, how does your ingestion pipeline degrade gracefully without crashing the storage cluster?
  • How would you architect historical replay so that reprocessing 7 days of raw events does not trigger false positive alerts or contaminate live real-time counters?