We separate the heavy ingestion of data (writes) from the user-facing display of data (reads).
1. Record a View Event (Fire and Forget) POST /v1/videos/{video_id}/events/view JSON
JSON
{
"userId": "user-8847",
"ipAddress": "192.168.1.1",
"timestamp": "2026-03-02T12:00:00Z",
"watchDurationSeconds": 15
}
(Note: The API Gateway returns a 202 Accepted immediately upon dropping this payload into the message queue, rather than waiting for database confirmation).
2. Fetch Video Statistics GET /v1/videos/{video_id}/stats JSON
JSON
{
"videoId": "vid-xyz123",
"viewCount": 4502394,
"lastUpdated": "2026-03-02T11:59:00Z"
}
GET API requests with sub-millisecond latency.This is exactly how you want to present your thoughts during a high-stakes technical whiteboard session. Structuring your answer this way demonstrates to an engineering panel that you can take a massive, open-ended problem and systematically break it down into scalable components.
Here is the complete system design document for the Video View Count System, swapping out the fragile synchronous approach for the robust, event-driven architecture we discussed.
Functional Requirements:
Non-Functional Requirements:
We separate the heavy ingestion of data (writes) from the user-facing display of data (reads).
1. Record a View Event (Fire and Forget) POST /v1/videos/{video_id}/events/view JSON
JSON
{
"userId": "user-8847",
"ipAddress": "192.168.1.1",
"timestamp": "2026-03-02T12:00:00Z",
"watchDurationSeconds": 15
}
(Note: The API Gateway returns a 202 Accepted immediately upon dropping this payload into the message queue, rather than waiting for database confirmation).
2. Fetch Video Statistics GET /v1/videos/{video_id}/stats JSON
JSON
{
"videoId": "vid-xyz123",
"viewCount": 4502394,
"lastUpdated": "2026-03-02T11:59:00Z"
}
GET API requests with sub-millisecond latency.Let's dig into the core mechanics that make this architecture capable of handling YouTube-level scale.
1. Asynchronous Ingestion (The Shock Absorber) When a video goes viral, traffic spikes unpredictably. If our API tried to write directly to a database or even a Redis cluster, the connections would max out. By routing all POST requests directly to Kafka, the API Gateway simply appends a message to a log. Kafka can easily handle millions of these appends per second, acting as a buffer so the rest of the system can process the backlog at its own maximum safe speed.
2. Real-Time Fraud Detection (Time-Windowing) The Apache Flink workers pull batches of events from Kafka. Before counting a view, Flink evaluates it against sliding time windows.
ipAddress or userId within a 1-minute window, it flags them as bot activity and drops the events from the pipeline entirely.watchDurationSeconds to ensure the user actually watched enough of the video to constitute a "view" (e.g., > 10 seconds).3. Micro-Batching and Aggregation Instead of the "Write-Through" approach where 10,000 views result in 10,000 database updates, Flink aggregates the valid views in memory over a short interval (e.g., 10 seconds).
Add 5,000 to Video A's total. This drastically reduces the write load on the primary database.4. Cache Invalidation Strategy A separate background worker monitors the database for updates. When a video's count is updated in Cassandra, the worker pushes the new total to the Redis cluster. The client application always reads from Redis, ensuring the database is never overwhelmed by read queries.
For a system where the primary operation is incrementing counters at a massive scale, an AP (Available and Partition-tolerant) NoSQL database like Cassandra is the industry standard due to its masterless architecture and specific data types.
Table: Video_View_Counts | Column Name | Data Type | Constraints / Indexes | Description | | :--- | :--- | :--- | :--- | | videoId | UUID / String | Partition Key | Uniquely identifies the video. | | totalViews | Counter | | A special Cassandra data type optimized for concurrent increments without read-before-write locking. |
Table: Fraud_Logs (Optional, for Analytics) | Column Name | Data Type | Constraints / Indexes | Description | | :--- | :--- | :--- | :--- | | ipAddress | String | Partition Key | The offending IP. | | flaggedAt | Timestamp | Clustering Key | When the fraud was detected. | | reason | String | | e.g., "RATE_LIMIT_EXCEEDED". |