A billion a day is about 12,000 events a second on average and perhaps 50,000 at peak. That is a real but ordinary load; the design is about durability and replayability more than raw throughput.
Walk it stage by stage:
Producers write to a log, Kafka or a managed equivalent, partitioned by a key that spreads load (user id hashed) and with a schema registry so a producer cannot silently change the shape of an event. Retention of a few days on the log is the replay buffer.
A stream consumer lands raw events into object storage in small time-bucketed files, partitioned by event date and hour, in a columnar format. This is the immutable source of truth; nothing downstream is allowed to be the only copy of anything.
Batch or micro-batch jobs read the raw layer and produce cleaned, deduplicated, typed tables in the warehouse, partitioned by event time. Deduplicate on event id, because at-least-once delivery will deliver twice.
Serving: aggregated tables for dashboards, and, if needed, a streaming path for the few metrics that need minute-level freshness. Do not make everything streaming; most consumers are fine with hourly.
The parts that show experience:
Late data: partition by event time, not arrival time, and reprocess a trailing window so late events land in the right day.
Idempotency: every batch step replaces its partition; re-running converges.
Schema evolution: additive changes only, with a registry that rejects breaking ones.
Monitoring: freshness, volume against the same hour last week, and duplicate rate, with alerts on all three.
Cost: the raw layer is cheap storage; the warehouse is where compute costs live, so pre-aggregate.
Back-of-envelope: at 1KB an event, a billion a day is a terabyte raw, roughly 100 to 200GB compressed columnar, which is small.
What they are checking: a raw immutable layer, event-time partitioning, dedup, and replay.
Common mistake: a diagram of boxes with named products and no answer to "what happens when a job fails at 3am".