Assume 100 million events daily.
Write / read QPS = 100M / 86400 = 1.2k QPS
Use 2x at peak, 2.4k QPS at peak
Assume each incoming event is 1 KB. Inbound throughput = 1.2k * 1 KB = 1.2 MB
Assume each event triggers an action of 1 KB. Outbound throughput = 1.2 MB
Throughput can be fit on one single server. QPS can also be handled by one server. However, users may come from different regions globally, and for availability, we may want sharding and replication.
Incoming events:
POST /webhooks/events. Request contains an event payload and include a secret auth token
incoming events:
100M * 365 * 5 yr * 1 KB = 183 TB for 5 yrs. Assume some increase per year, say 250 TB for 5 yrs
outgoing events:
similar to incoming, say 250 TB for 5 yrs
Typically too big for a RDB. However, since a webhook event is always tied to an auth token which is linked to a specific account, we can shard RDB based on accounts. Due to strong consistency requirement, we choose RDB.
See high level diagram
We have chosen strong consistency because of financial events being involved.
We used RDB and shared by user accounts because events from different user accounts do not share overlap information between each other.
We use replicas for high availability.
When a leader is dead, the followers will elect a new leader, e.g., use Raft algorithm. The new leader will be responsible for taking future incoming events.
Every leader and follower keeps a event log, so that in case they become dead, the new leader can recover from what was supposed to happen but not yet processed before the old leader went dead.
We may consider using NoSQL if consistency becomes less important in the future.