In this article
Modern digital businesses generate millions of telemetry events every hour—ranging from user click-streams and payment transactions to IoT sensor telemetry and AI inference logs. Traditional relational databases (such as standard MySQL or PostgreSQL instances) choke when subjected to continuous ingestion rates exceeding 50,000 writes per second while simultaneously serving complex analytical aggregation queries. In 2026, the gold-standard architecture for sub-second real-time analytics combines Apache Kafka as the distributed event log with ClickHouse as the columnar analytical database.
ClickHouse’s vectorized query execution engine and columnar storage format deliver 100x to 1,000x faster aggregation speeds than row-oriented databases, while Kafka provides fault-tolerant, horizontally scalable message buffering. This production engineering guide walks you through building an end-to-end data pipeline capable of ingesting 100,000+ events per second with sub-50ms analytical query response times.
Architectural Overview: The Ingestion Flow
The streaming analytical pipeline consists of three coordinated tiers:
- Event Producers (APIs & Microservices): Applications dispatch lightweight JSON or Protocol Buffer messages to Kafka topics over TLS.
- Kafka Cluster (Buffer Layer): Partitions events across distributed broker nodes, guaranteeing message durability and replayability during downstream maintenance.
- ClickHouse Kafka Engine + Materialized View (Storage & Ingestion): ClickHouse consumes messages directly from Kafka via background consumer threads and streams transformed records into compressed, partitioned tables.
| Architecture Dimension | Traditional ETL (Postgres / MySQL) | Streaming Pipeline (Kafka + ClickHouse) |
|---|---|---|
| Write Throughput | 2,000 – 10,000 rows/sec before lock contention | 100,000 – 1,000,000+ rows/sec via batch blocks |
| Storage Compression | 1.2x – 1.8x typical compression | 5x – 10x LZ4 / ZSTD columnar compression |
| Aggregation Query Latency | 15 – 90 seconds across 100M rows | 12ms – 85ms via SIMD vectorized scanning |
| Operational Scalability | Requires complex sharding or costly cloud instances | Horizontal scale-out across lightweight commodity servers |
Step-by-Step Implementation
1. Designing the Target ClickHouse Analytical Table
In ClickHouse, create the persistent storage table utilizing the MergeTree or ReplacingMergeTree engine, partitioned by month and ordered by timestamp and event type:
-- 1. Create target analytical storage table
CREATE TABLE telemetry_events (
event_id UUID,
event_timestamp DateTime64(3, 'UTC'),
tenant_id UInt32,
event_name LowCardinality(String),
payload_json String,
duration_ms Float32,
status_code UInt16
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_timestamp)
ORDER BY (tenant_id, event_name, event_timestamp);
2. Setting Up the ClickHouse Kafka Engine Consumer
ClickHouse includes a native Kafka integration engine that operates as a consumer group, reading messages without requiring external middleware like Logstash or custom Python workers:
-- 2. Define Kafka consumer engine table
CREATE TABLE kafka_telemetry_queue (
event_id UUID,
event_timestamp DateTime64(3, 'UTC'),
tenant_id UInt32,
event_name String,
payload_json String,
duration_ms Float32,
status_code UInt16
) ENGINE = Kafka
SETTINGS
kafka_broker_list = 'kafka:9092',
kafka_topic_list = 'telemetry-stream',
kafka_group_name = 'clickhouse-ingest-group',
kafka_format = 'JSONEachRow',
kafka_num_consumers = 2;
3. Wiring the Stream with a Materialized View
Because the Kafka engine table is an ephemeral stream, you bind it to your storage table using a ClickHouse Materialized View that triggers automatically on incoming message batches:
-- 3. Create real-time pipe from Kafka queue to storage table
CREATE MATERIALIZED VIEW mv_telemetry_consumer TO telemetry_events AS
SELECT
event_id,
event_timestamp,
tenant_id,
CAST(event_name AS LowCardinality(String)) AS event_name,
payload_json,
duration_ms,
status_code
FROM kafka_telemetry_queue;
Executing Sub-Second Real-Time Analytics
With data flowing into ClickHouse, you can query rolling averages, P95 latencies, and conversion funnels across tens of millions of records in milliseconds:
-- Real-time P95 latency and error rate calculation over the last 15 minutes
SELECT
event_name,
count() AS total_requests,
quantile(0.95)(duration_ms) AS p95_latency_ms,
countIf(status_code >= 500) AS server_errors,
round(countIf(status_code >= 500) / count() * 100, 2) AS error_percentage
FROM telemetry_events
WHERE event_timestamp >= now() - INTERVAL 15 MINUTE
GROUP BY event_name
ORDER BY total_requests DESC
LIMIT 10;
Production Performance Tuning Guidelines
- Batch Size Tuning: Adjust
kafka_max_block_size = 65536inside ClickHouse to balance write throughput with insertion latency. - Data Types: Always use
LowCardinality(String)for repetitive category fields (e.g., HTTP methods, event types) to achieve massive memory savings. - Retention Policies (TTL): Implement automated lifecycle cleanup using table-level TTL rules:
ALTER TABLE telemetry_events MODIFY TTL event_timestamp + INTERVAL 90 DAY;.
Conclusion
Combining Apache Kafka’s bulletproof message queuing with ClickHouse’s raw columnar analytical speed provides a world-class foundation for real-time observability, telemetry analytics, and customer intelligence platforms capable of effortless enterprise scaling.