Real-time Kafka pipeline, routed by device platform

Every login event, routed to the right stream, in real time.

A Kafka pipeline that ingests user login events, validates each one, normalizes its timestamp, and routes it by device platform to iOS, Android, or missing-data topics.

stackApache KafkaConfluentPythonDocker
LIVE0/speak 0/s
waiting…
iOS0
Android0
Missing0
Dropped0
throughput
now

Live routed stream, running now. Scroll for the full control room.

/ live control room

Watch every login event route itself.

A live simulation of the pipeline at scale. Tune the producer rate, partition count, and consumer parallelism, then fire chaos at it. The real router.py on the right highlights the line executing for each event.

controls
Produce rate120 ev/s
Partitions6
Consumers3
chaos
capacity = 4200 ev/s. push rate above it to grow consumer lag.
Producermy-python-produceruser-loginsource topicRouterconsumers/router.pyios-user-loginiOS eventsandroid-user-loginAndroid eventsmissing-data-loginincomplete / nullConsumersplatform_consumer.py
router stdout
waiting for events…
login originssimulated geo
live
1from confluent_kafka import Consumer, Producer
2import json
3from datetime import datetime
4
5TOPICS = {"iOS":"ios-user-login", "android":"android-user-login",
6 "missing":"missing-data-login"}
7EXPECTED_FIELDS = 7
8
9consumer.subscribe(["user-login"])
10while True:
11 msg = consumer.poll(1.0)
12 raw = json.loads(msg.value())
13
14 if len(raw) != EXPECTED_FIELDS:
15 producer.produce(TOPICS["missing"],
16 value=json.dumps(raw))
17 continue
18 if raw.get("user_id") is None:
19 continue
20
21 raw["timestamp"] = str(
22 datetime.fromtimestamp(raw["timestamp"]))
23
24 topic = TOPICS.get(raw.get("device_type",""),
25 TOPICS["missing"])
26 producer.produce(topic,
27 value=json.dumps(raw))
executing: poll
live metricsconsumers 3
Throughput
0/s
of 10,000/s
Consumer lag
0
messages
End-to-end
14 ms
p50 latency
Rate trend
iOS0
Android0
Missing0
Dropped0

Click any node in the topology to inspect its code and live counters. Slide produce rate past consumer capacity to grow lag.

/ engineering calls

Decisions, with reasons.

The same tradeoffs the repo documents, surfaced as architecture decisions.

ADR

One generic consumer, not three?

platform_consumer.py replaces ios / android / missing scripts. Same logic, takes the topic as a CLI arg. Less duplication.

ADR

Route in a consumer, not Kafka Streams?

Routing is a 10-line if/else on one field. A plain consumer and producer have far fewer dependencies than a Streams app for logic this simple.

ADR

Docker for infra, local for consumers?

The broker and producer need consistent networking, so Docker fits. Consumers are lightweight Python you want to watch and iterate on locally.

What I would add at scale

Schema Registry
Enforce Avro/Protobuf to catch schema drift before consumers.
Dead-letter queue
Route unparseable messages to a DLQ instead of dropping them.
Lag monitoring
Prometheus + Grafana on consumer group offsets.
Key partitioning
Partition by user_id hash for per-user ordering.
Sink connector
Kafka Connect into a warehouse for historical analytics.

/ fan-out in 3d

One stream becomes three.

The router inspects each event and fans it to the matching topic. Drag to orbit. At scale, partitioning by user_idhash keeps every user's events ordered within a topic, so downstream consumers see each user in sequence.

drag to orbit

/ stack

A small, deliberate stack.

Each tool does one job. The broker and producer are containerized for consistent networking, while the router and consumers stay as lightweight Python you can watch and iterate on locally.

Apache Kafka
Apache Kafka
message broker
Confluent
Confluent Python
producer / consumer
Python
Python 3.8+
routing logic
Docker
Docker Compose
broker + producer
terminal
$ docker-compose up -d
  zookeeper  kafka  my-python-producer  started
$ python consumers/router.py
  Router listening on 'user-login'

[    IOS]  user=abc123  dev=iOS  v2.3.0
[ANDROID]  user=def456  dev=android
[MISSING]  {user_id:ghi789, ..incomplete}

Session analytics

opt-in, local to your browser, nothing leaves the page

Toggle tracking to measure your session: total events routed, peak throughput you pushed the pipeline to, route distribution, and how many chaos interactions you triggered. Useful for the same reason real pipelines need telemetry: you cannot improve what you do not measure.

Run the pipeline locally.

Bring up Kafka, Zookeeper, and the producer in containers, then start the router and watch events classify and route in real time.

$ docker-compose up -d
$ python consumers/router.py