FR
1.Each user account (or plan) has a maximum number of concurrent screens (or devices) allowed.
E.g., Basic Plan: 1 screen, Standard: 2 screens, Premium: 4 screen
2.When a user starts a new stream, the system should:
Check the current number of active streams.
Deny the request if the limit is already reached.
Otherwise, allow the stream and increment the active count.
3.When a stream ends (via user stop, timeout, logout, etc.), the active count should be decremented.
4.The screen limit should apply across all devices – phones, tablets, TVs, etc.
5.If a stream crashes or is not properly closed, there should be a timeout mechanism to expire stale sessions.
6.Even with multiple profiles, the screen limit applies at the account level, not per profile.
7.The system must enforce limits in real-time, so new streams can’t bypass the max limit.
NFR
1.The system must be available 24/7, as users can stream content anytime, globally
2.Stream start/stop validations should happen in real-time or near-real-time (e.g., <100ms) to ensure smooth user experience.
3.System should be highly scalable to handle millions of concurrent users and stream sessions, especially during peak hours.
4.The system must strongly enforce screen limits, so users cannot exceed the allowed number of concurrent streams.
5.Failures in components (e.g., cache server, stream tracker) should not cause system-wide failures.
Estimates
100 million daily active users (DAUs)
Peak load = ~10% of DAUs are concurrently streaming.
DAU = 100 million ⇒ Peak concurrent users = 10 million
Each user can have up to 4 screens (premium plan), but not all will hit the max.
Let’s assume average 2 screens per user at peak.
👉 Concurrent Streams = 10 million users × 2 = 20 million active streams at peak
API’s
1.POST /api/v1/stream/start
request {
"user_id": "user_123",
"device_id": "device_abc",
"profile_id": "profile_xyz",
"plan_type": "premium"
}
response {
"success": true,
"session_id": "session_789",
"message": "Stream started successfully"
}
Errors:
409 Conflict
— screen limit reached403 Forbidden
— unauthorized500
— internal error
2.POST /api/v1/stream/stop
request {
"user_id": "user_123",
"session_id": "session_789"
}
response {
"success": true,
"message": "Stream stopped successfully"
}
3.GET /api/v1/stream/active?user_id=user_123
{
"user_id": "user_123",
"active_streams": [
{
"session_id": "session_789",
"device_id": "device_abc",
"start_time": "2025-04-18T13:00:00Z"
},
{
"session_id": "session_101",
"device_id": "device_xyz",
"start_time": "2025-04-18T13:05:00Z"
}
],
"max_allowed_streams": 4
}
4.POST /api/v1/stream/force-stop
request {
"user_id": "user_123",
"session_id": "session_789"
}
response {
"success": true,
"message": "Stream forcefully stopped"
}
5.POST /api/v1/admin/plan/update
request {
"user_id": "user_123",
"plan_type": "premium", // or "standard", "basic"
"max_screens": 4
}
response {
"success": true,
"message": "Screen limit updated"
}
Databases
SQL Tables (PostgreSQL / MySQL)
users
CREATE TABLE users (
user_id UUID PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
plan_type VARCHAR(20) NOT NULL CHECK (plan_type IN ('basic', 'standard', 'premium')),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
plans
CREATE TABLE plans (
plan_type VARCHAR(20) PRIMARY KEY,
max_screens INT NOT NULL,
quality VARCHAR(10) NOT NULL
);
stream_sessions
CREATE TABLE stream_sessions (
session_id UUID PRIMARY KEY,
user_id UUID REFERENCES users(user_id),
device_id UUID,
start_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
end_time TIMESTAMP,
is_force_stopped BOOLEAN DEFAULT FALSE
);
⚡ Redis (Real-Time Stream Tracking)
🔑 Key: active_streams:<user_id>
Type: Redis Hash or Set
Example Structure (if using hash):
HSET active_streams:user_123 session_abc '{"device_id":"device_xyz","start_time":"2025-04-18T12:00:00Z"}'
🔢 Optional Counter Key:
user_active_count:<user_id>
Type: Integer
Use: Atomically increment/decrement with stream start/stop
✅ Best Practices
Use Redis TTL (e.g., 4 hours) on session keys to auto-cleanup orphaned streams.
Wrap stream start logic in a Lua script or Redis transaction to ensure atomic check-and-set:
Check current count
If < max allowed → add session & increment count
Else → reject stream start
HLD