Define the Toolkit and Its Users
A streaming-statistics toolkit is like a dashboard at a busy railway station: it cannot store every passenger forever, but it must continuously answer useful questions—how many arrived, how many were distinct, whether a name has probably appeared, which destinations are busiest, and where the wait-time distribution lies. Producers send events, applications ask questions, and operators need to know whether an answer is exact, approximate, stale, or degraded.
Start with the stream A, B, A, C, A. An exact counter reports 5 events; a distinct set reports 3 keys; a frequency map reports A → 3; a membership structure answers that B was seen. An approximate toolkit may replace those structures with a Morris counter, HyperLogLog (HLL), Count-Min Sketch, and Bloom filter to use bounded memory. The output A ≈ 3 is only useful if it also states the configured error and confidence.
The common contract is update(event), query(request), merge(other), snapshot(), and restore(bytes). A parameter calculator turns an error budget into memory settings. An exact oracle processes the same replay with dictionaries, sets, or sorted arrays. Confidence metadata describes a probabilistic statement; it is not a promise that every answer is within the bound. Mergeability requires identical algorithm families, seed identities, schema versions, and compatible parameters—not merely two objects with the same method names.
The users are application engineers choosing a statistic, data-platform engineers deploying partitioned state, reliability engineers diagnosing lag or corruption, security reviewers limiting sensitive output, and analysts interpreting estimates. Acceptance means stable interfaces, deterministic seeded tests, bounded memory, merge-equivalent results where promised, versioned serialization, visible degradation, and exact-oracle evidence for every approximate backend.
Think of the toolkit as a set of small, mergeable measuring instruments behind one labeled control panel. “One API” does not mean identical semantics: each result must expose whether it is exact or approximate and which guarantee applies.
| Term | Intuitive meaning | Exact example | Non-example | Assumption | Question answered |
|---|---|---|---|---|---|
| Event count | Items processed | Integer incremented per accepted event | Queue length | Defined deduplication policy | How many events arrived? |
| Reservoir sample | Uniform sample of fixed size | Seeded Algorithm R with k=100 | First 100 events | Stable RNG and one pass | What does a typical event look like? |
| Bloom filter | Compact membership screen | Bits set by k hashes | A key-value store | False positives allowed; no false negatives before deletion/corruption | Has this key possibly appeared? |
| HLL | Distinct-cardinality estimate | Registers from leading-zero ranks | Sum of event counts | Uniform hash; compatible precision | Roughly how many unique keys? |
| Count-Min Sketch | One-sided frequency estimate | Minimum across hashed counters | Exact top-k list | Nonnegative updates for the standard bound | How frequent is this key, at most how overestimated? |
| Count Sketch | Signed frequency estimator | Median of signed bucket values | Membership filter | Pairwise-independent hash/sign functions | What is a frequency under signed updates? |
| Quantile summary | Rank-oriented distribution synopsis | GK summary with rank error εN | Arithmetic mean | Ordered values and stated rank-error model | What value lies near p95? |
| Merge contract | Rule for combining partitions | Add aligned CMS matrices | Concatenating arbitrary serialized bytes | Matching version, seeds, dimensions, semantics | Can these states be combined safely? |
Define the Toolkit and Its Users
Process [(A,4), (B,9), (A,7), (C,2), (A,8)] on paper. Maintain an exact event count, exact distinct set, exact frequency map, and a size-2 reservoir using replacement draws —, —, 2, 4, 1 for arrivals 1–5 (replace only when the draw is at most 2, at position draw−1). Checkpoints: after three arrivals the count is 3, distinct keys are {A,B}, frequencies are {A:2,B:1}, and the reservoir becomes [A,B] because draw 2 replaces the second entry with the third event (A,7). After five arrivals expect count 5, three distinct keys, A:3, and reservoir [(A,8),(A,7)]. Reflection: which answers remain exact, and why must a sample never be presented as a frequency table?
Choose Interfaces, Guarantees and Backends
The primary workload is keyed events on many partitions, with millions of updates per second, point queries below 20 ms at p99, snapshots every five minutes, and bounded per-tenant memory. Producers submit {tenant, stream, event_id, event_time, key, value, schema_version}. The service validates size and type, applies an explicit duplicate policy, routes by tenant and stream, and returns a Result containing value, algorithm, exactness, error model, confidence, parameters, watermark, and state version.
Functional requirements include counts, uniform samples, membership, distinct counts, point frequencies, heavy-hitter candidates, and quantiles. SLOs include 99.9% query availability, no silent restore across incompatible versions, deterministic replay under fixed seeds, and resource enforcement before allocation. Privacy limits prohibit raw sampled payloads unless the tenant policy permits them; access control, retention, redaction, and query auditing are part of the contract. The threat model covers malformed events, hash-flooding, cross-tenant reads, snapshot tampering, replay duplication, and a compromised operator credential, but not a fully compromised process host.
Parameter calculators translate targets into configuration: Bloom uses m = ceil(-n ln p/(ln 2)^2) bits and k ≈ (m/n)ln 2; CMS uses width ceil(e/ε) and depth ceil(ln(1/δ)); HLL precision selects m=2^p registers with relative standard error near 1.04/sqrt(m). Values outside safe ranges are rejected. Exact backends remain available for small streams, audits, and automatic fallback when an approximation is unsupported—not when memory would become unsafe.
flowchart TD
P[Producers] --> V[Validate and route]
V --> L[Partition log]
L --> E[State engine]
E --> X[Exact backends]
E --> A[Approximate backends]
X --> S[Versioned snapshots]
A --> S
Q[Query API] --> E
E --> R[Result plus guarantee metadata]
O[Operators] --> C[Config and rollout control]
C --> V
E --> M[Metrics traces audit]
classDef navy fill:#17365D,color:#fff,stroke:#102844;
classDef teal fill:#147D84,color:#fff,stroke:#0c5c61;
classDef crimson fill:#C6284D,color:#fff,stroke:#8e1935;
classDef purple fill:#6C3BAA,color:#fff,stroke:#482675;
class P,Q,O navy;
class V,L,E,C teal;
class X,A,S purple;
class R,M crimson;
| Candidate | Guarantee | Scale / latency | Memory | Operational burden | Privacy | Recovery | Decision |
|---|---|---|---|---|---|---|---|
| Exact map/set | Exact under accepted-event semantics | Best for small cardinality; tail latency grows with state | O(distinct keys) | Simple until compaction/sharding | Stores identifiers; highest exposure | Straightforward snapshot/replay | Keep as oracle and small-stream backend |
| Morris counter | Probabilistic total count | O(1) update | O(log log N) bits conceptually | Low, but surprising variance | No keys retained | Merge is nontrivial and must be specified | Offer only when extreme count compression is required |
| Reservoir sampling | Uniform k-sample | O(1) expected update | O(k) payloads | Requires deterministic merge strategy | May retain raw sensitive events | Snapshot RNG state and seen count | Select with redaction and access controls |
| Bloom filter | No false negatives; configured false-positive rate | Constant hash work | Fixed m bits | Capacity must be watched | Membership inference risk | Bitwise OR only for compatible filters | Select for membership screening |
| HLL | Relative-error distinct estimate | Constant update/query over registers | Fixed 2^p registers | Bias/version compatibility | Hashed identifiers still sensitive | Register-wise max when compatible | Select for distinct counts |
| Count-Min Sketch | Additive overestimate for nonnegative frequencies | O(depth) update/query | O(width×depth) | Saturation and candidate discovery need care | Frequency leakage | Cell-wise addition when compatible | Select for point frequency; pair with candidate heap |
| Count Sketch | Unbiased signed estimator with variance bound | O(depth) | O(width×depth) | More seed/sign management | Frequency leakage | Cell-wise addition when compatible | Select where negative updates are required |
| GK / KLL summary | Rank-error quantiles | Logarithmic or amortized update | Bounded by accuracy | Merge/version rules vary | Distribution leakage | Only documented compatible merge | Select KLL for merge-heavy analytics; GK for deterministic rank bounds |
The central invariant is that accepted events and compatible merges have one unambiguous semantic effect, while every query returns the evidence needed to interpret it. Launch is blocked by cross-tenant leakage, unbounded allocation, silent version coercion, or any estimate lacking algorithm and guarantee metadata.
Build Exact and Approximate Statistics Vertically
Build one statistic end to end before adding the next. Slice 1 implements the envelope, validation, exact count, snapshot checksum, and replay. Slice 2 adds Bloom membership with a calculator and exact-set oracle. Slice 3 adds reservoir sampling, then HLL, CMS/Count Sketch, and a quantile summary. Each backend conforms to a narrow protocol but may expose statistic-specific queries; forcing membership and quantiles into the same scalar method would hide semantics.
Configuration is immutable within a state generation. A snapshot records {format_version, algorithm, parameters, seed_id, schema_version, watermark, payload, checksum}. Restore first validates size, checksum, version, and parameter compatibility. Migrators are explicit functions between adjacent formats; otherwise the service replays the retained log or returns UNSUPPORTED_STATE. Memory guards check calculated dimensions before allocation. Counter saturation, late-event policy, and serialization limits are observable. A circuit breaker can route a small stream to an exact backend, reject optional statistics, or serve a stale labeled snapshot; it never silently changes guarantees.
flowchart TD
C[Contract and envelope] --> E[Exact baseline]
E --> B[Bloom and reservoir]
B --> H[HLL and frequency sketches]
H --> Q[Quantile summary]
Q --> I[Integrated canary]
I --> D[Progressive deployment]
D -->|SLOs pass| P[Promote]
D -->|Mismatch or saturation| R[Rollback generation]
R --> E
classDef navy fill:#17365D,color:#fff,stroke:#102844;
classDef teal fill:#147D84,color:#fff,stroke:#0c5c61;
classDef crimson fill:#C6284D,color:#fff,stroke:#8e1935;
classDef purple fill:#6C3BAA,color:#fff,stroke:#482675;
class C,E navy;
class B,H,Q teal;
class I,D purple;
class P,R crimson;
Build Exact and Approximate Statistics Vertically: Streaming Statistics Toolkit
Create contracts.py, exact.py, cms.py, snapshot.py, and test_replay.py. First replay A,B,A,C,A; checkpoint 1 passes when exact count is 5 and frequencies are {A:3,B:1,C:1}. Add CMS with width=64, depth=4, seed=11; checkpoint 2 passes when every point estimate is at least its exact nonnegative frequency and two identical replays produce identical matrices. Split the stream after three events, merge aligned CMS states, and compare with the single-pass matrix; they must be byte-for-byte equal. Attempt a merge with seed 12 and an allocation above max_cells; both must fail before mutation. Serialize, corrupt one byte, and verify checksum rejection. Definition of done: normal replay, compatible merge, deterministic snapshot, corruption rejection, and resource/compatibility guards all run in one command with zero unexplained warnings.
Verify Every Contract and Failure Mode
Verification layers reinforce one another. Unit tests cover parameter formulas and serialization. Property tests generate streams and assert exact identities, Bloom no-false-negative behavior, CMS non-underestimation for nonnegative updates, merge equivalence, and bounded state. Differential replay compares approximate answers with exact oracles across seeds and skew levels. Load tests measure update throughput, query p99, memory per stream, snapshot duration, and recovery time. Adversarial tests target hot keys, empty streams, Unicode, maximum counters, late events, duplicate IDs, incompatible seeds, corrupt snapshots, storage stalls, and partition loss.
An approachable end-to-end case replays 10,000 café orders and checks count, distinct menu items, frequent products, a uniform audit sample, and p95 preparation time. The professional case is a multi-tenant telemetry service at 500,000 events/s, 5,000 active streams, a 4 GiB state budget per worker, query p99 under 20 ms, and recovery under 10 minutes. Canary traffic shadows exact results for small tenants. Dashboards separate algorithm error from systems error: lag, rejected events, saturation, incompatible merges, checksum failures, and estimate/oracle deltas. An incident commander owns rollback; the correctness lead signs the dossier; security reviews sampled data and membership-inference exposure.
| Requirement / guarantee | Oracle | Workload | Metric and threshold | Failure injection | Evidence | Owner |
|---|---|---|---|---|---|---|
| Accepted-event count is exact | Integer replay counter | Café trace + duplicate IDs | Equality after dedup policy; zero mismatch | Duplicate and out-of-order replay | Seeded replay report | Correctness lead |
| Bloom has no false negatives | Exact set | Capacity and 2× capacity streams | 0 false negatives; measured FP ≤ configured p plus statistical tolerance | Bit-flip snapshot | Property-test log, checksum alert | Backend owner |
| HLL distinct estimate is calibrated | Exact set cardinality | Uniform and Zipf keys over 30 seeds | RMSE within documented envelope; no systematic regression >10% | Incompatible precision merge | Accuracy notebook and seed manifest | Algorithms reviewer |
| CMS respects one-sided bound | Exact frequency map | Uniform, Zipf, adversarial collisions | No underestimates; violation rate of additive bound ≤ δ envelope | Counter saturation | Differential report and saturation metric | Backend owner |
| Reservoir is uniform | Exact inclusion probabilities | Repeated seeded runs, N=100, k=10 | Chi-square test not persistently rejected across seed suite | RNG-state loss on restore | Statistical test report | Correctness lead |
| Quantile rank error is bounded | Sorted exact array | Bimodal, repeated values, heavy tails | Observed rank error ≤ configured contract | Truncated snapshot | Rank-error plots and restore logs | Backend owner |
| Query and update SLOs | Load generator and trace clock | 500k updates/s, 5k streams | Query p99 <20 ms; availability ≥99.9% | 200 ms storage stall | Dashboard export and trace exemplars | SRE |
| Memory is bounded | Allocator telemetry | Cardinality ramp to limit | Worker state ≤4 GiB; rejection before unsafe allocation | Malicious dimensions | Heap profile and rejection audit | Platform lead |
| Recovery is safe | Snapshot + retained log | Worker loss during snapshot | RTO <10 min; checksum/version errors never bypassed | Kill worker, corrupt byte | Incident timeline and replay hash | Incident commander |
| Tenant/privacy isolation | Authorization oracle | Cross-tenant queries and samples | 0 unauthorized reads; all sensitive queries audited | Forged tenant token | Security test and audit export | Security owner |
Verify Every Contract and Failure Mode: Streaming Statistics Toolkit
Run a 30-minute readiness trial: 10 minutes at 250k events/s, 10 at 500k, and 10 at 650k with Zipf-skewed keys across 5,000 streams. Require p99 query latency below 20 ms at target load, update acceptance above 99.99%, memory below 4 GiB, zero cross-tenant results, and estimate/oracle metrics inside each backend's documented envelope. At minute 12 kill one worker; expect reassignment, snapshot restore, replay, and recovery under 10 minutes. At minute 20 corrupt a snapshot and change one CMS seed; expect checksum and compatibility alerts, quarantine, and no merge. Roll back if p99 exceeds 30 ms for five minutes, memory exceeds 90% of budget, an invariant fails once, or recovery breaches 10 minutes. The written decision must be GO, CONDITIONAL GO with dated owners, or NO-GO, citing dashboard captures, replay hashes, alert timelines, cost per million events, and unresolved risks.
Package, Demonstrate and Extend the Toolkit
The release bundle contains an API reference with semantic examples, configuration calculators, a pinned reproducible environment, seeded datasets, benchmark commands, raw results, a correctness dossier, schema and migration notes, an operational runbook, security/privacy review, limitations, and a roadmap. The runbook covers saturation, lag, snapshot corruption, incompatible state, elevated false positives, unexpected oracle drift, tenant isolation, rollback, and evidence preservation. Every artifact names its version, owner, generation command, and review date.
The demonstration starts with the five-event example, shows exact and approximate result envelopes, partitions and merges a replay, rejects an incompatible seed, restores a valid snapshot, rejects a corrupt one, and finishes with the professional workload dashboard. Peer reviewers should ask: Can a caller distinguish every guarantee? Are calculators tested at boundary values? Is merge equivalence proved or explicitly unsupported? Can operators see degradation before users do? Are samples and membership queries appropriately protected? Could a new backend be added without weakening old contracts?
Handoff requires tagged source, checksums, a clean one-command test run, benchmark provenance, reviewed dashboards and alerts, rehearsed rollback, ownership rotation, and no undocumented exceptions. The roadmap prioritizes risk reduction before feature breadth: priority-reservoir merge correctness, production HLL bias tables, KLL quantiles, differential-privacy wrappers with explicit budgets, hardware-aware vectorization, and cross-language conformance fixtures.
Package, Demonstrate and Extend the Toolkit: Streaming Statistics Toolkit
Final checklist: (1) build from a clean checkout; (2) run unit, property, replay, load, security, and fault suites; (3) publish API docs and result-envelope examples; (4) attach parameter-calculator proofs and boundary tests; (5) archive benchmark data, environment lock, seeds, and commands; (6) sign the correctness dossier; (7) rehearse restore and rollback; (8) record privacy review and on-call ownership. Demo script: ingest the five-event stream, inspect labeled results, replay two partitions, show compatible CMS merge equality, trigger incompatible-seed rejection, corrupt a snapshot, then open the SLO dashboard from the production trial. Score 0–2 each for correctness, contract clarity, reproducibility, bounded resources, observability, recovery, security/privacy, and documentation; require at least 14/16 and no zero. Stretch goals are HLL, KLL, signed Count Sketch, and language-neutral fixtures. Milestones: merge-safe reservoir, calibrated HLL, then privacy-budgeted release. Reviewers sign only when every acceptance criterion links to evidence and an owner.
Launch only with passing contract tests, bounded resources, calibrated error evidence, rehearsed recovery, privacy controls, and explicit owners. Known risks include hash assumptions, distribution shift, membership and sample leakage, and operators misreading probabilistic bounds; ask which failure would remain invisible, then make the next milestone a merge-safe reservoir with statistical and recovery evidence.