Real-time Analytics#
Problem statement (interviewer prompt)
Design a real-time analytics platform for clickstream events: ingest 1M+ events/s, sessionise per user, compute funnel + retention + cohort metrics with sub-minute freshness, and let analysts query both live and historical data with sub-second latency for dashboards.
flowchart LR
E[Events]
K[[Kafka]]
ST[[Stream Processor<br/>Flink / Kinesis]]
AGG[(Aggregates)]
OLAP[(OLAP store<br/>Druid / ClickHouse)]
DASH[Dashboards]
E --> K --> ST --> AGG --> OLAP --> DASH
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class E service;
class AGG,OLAP datastore;
class K,ST queue;
class DASH obs;
flowchart TB
subgraph Source
WEB([Web pixels])
SDK([Mobile SDK])
SVC[Server events]
end
subgraph Ingest
LB
COL([Collector / Edge ingester])
KAFKA[[Kafka]]
SCHEMA[Schema registry]
end
subgraph Sess[Sessionization & enrich]
SES[Session windowing]
JOIN[[Stream-stream / stream-table joins]]
ENRICH([Geo / device / UTM])
end
subgraph Stream
FLINK[[Flink / Kinesis Analytics]]
HLL[HLL unique counts]
TUMBLE[Tumbling windows]
SLIDE[Sliding windows]
end
subgraph Storage
HOT[(KV / Redis hot counters)]
OLAP[(Druid / ClickHouse / Pinot)]
LAKE[(S3 / Iceberg)]
end
subgraph Serve
API[Query API]
DASH[Dashboards]
ALERT[Real-time alerts]
EXPORT[Export to warehouse]
end
Source --> LB --> COL --> KAFKA --> SCHEMA
KAFKA --> Sess --> Stream --> Storage --> Serve
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class WEB,SDK,ENRICH client;
class SVC,SCHEMA,SES,HLL,TUMBLE,SLIDE,API service;
class OLAP,EXPORT datastore;
class HOT cache;
class KAFKA,JOIN,FLINK queue;
class COL compute;
class LAKE storage;
class DASH,ALERT obs;
Glossary & fundamentals#
Concepts referenced in this design. Each row links to its canonical page; the tag column shows whether it is a high-level (HLD) or low-level (LLD) concept.
| Tag | Concept | What it is | Page |
|---|---|---|---|
HLD |
Pub/Sub & message brokers | topics, consumer groups, delivery semantics | pub-sub-pattern |
HLD |
Probabilistic data structures | Bloom, HLL, Count-Min, MinHash, t-digest | probabilistic-data-structures |
HLD |
Batch & stream processing | Lambda vs Kappa, watermarks, windows | batch-stream-processing |
Quick reference#
Functional#
- Sessionization, funnels, retention.
- Per-event dashboards & ad-hoc queries.
- Real-time alerts.
- Export to warehouse for SQL.
Non-functional#
- Pipeline lag < 5 s.
- Sub-second dashboard for last 24h.
- Petabytes long-term in lake.
Trade-offs#
- Druid/Pinot for high-QPS dashboards; ClickHouse for ad-hoc SQL.
- Lambda vs Kappa: kappa simpler if stream-first.
- Exactly-once is expensive; design idempotent counters.
Refs#
- Druid, Pinot, ClickHouse docs.
- "Streaming Systems" Tyler Akidau.
- Snowplow / Heap engineering posts.
FAQ#
How does a real-time analytics platform work?#
Events stream into Kafka, a stream processor like Flink sessionizes and aggregates them, and results land in an OLAP store such as Druid or ClickHouse for sub-second dashboard queries.
What is the difference between Lambda and Kappa architecture?#
Lambda runs parallel batch and streaming pipelines, then reconciles. Kappa uses only a streaming pipeline that can replay history, simplifying ops but demanding robust state.
How is sessionization done at scale?#
Stream processors keyed by user ID maintain session state with an inactivity timeout. When the user goes idle, the session is closed and emitted with computed metrics.
Why use Druid, Pinot, or ClickHouse?#
These OLAP engines store data in columnar segments, pre-aggregate where possible, and use bitmap indexes to answer slice-and-dice queries on billions of rows in sub-second.
How do funnel and cohort analyses work?#
Funnel queries match ordered event sequences per user. Cohort queries group users by an acquisition event and measure retention or revenue over time relative to that anchor.
How is exactly-once guaranteed in streaming analytics?#
Flink and similar engines use distributed snapshots and transactional sinks so a job restart resumes from a consistent state without reprocessing or losing events.