Scaling View Tracking with Redis Counters in Social Video App

Tracking user engagement like views and replays is critical for content ranking, personalization, and analytics β but doing it in real time can overwhelm your database. That's where Redis shines.
In this post, you'll learn how to build scalable view and replay counters using Redis, and flush them periodically into your database.
π§± Why Use Redis?
Traditional view tracking can easily create millions of rows β especially if you log every view. Thatβs overkill unless you need granular logs. Instead, use Redis counters for:
Fast, in-memory incrementing
Throttle-proof updates (with TTLs)
Easy batching and flushing to DB
Scalable with low overhead
π§ Key Design
Use simple, structured Redis keys:
view:<media_id> β Total views
replay:<media_id> β Total replays
user_view:<user_id>:<media_id> β To prevent abuse (with TTL)
Example
view:4382 β 129
replay:4382 β 27
user_view:982:4382 β true
π Incrementing Counters (Laravel Example)
$mediaId = 4382;
$userId = 982;
// Avoid duplicate views within 30 minutes
if (!Redis::get("user_view:$userId:$mediaId")) {
Redis::incr("view:$mediaId");
Redis::setex("user_view:$userId:$mediaId", 1800, true); // 30 mins TTL
}
// On replay
Redis::incr("replay:$mediaId");
You can extend this logic to support anonymous users using session_id
or IP-based tracking.
ποΈ Flushing Redis to Database
Use a scheduled job (e.g., every 5β15 minutes) to flush counters:
$keys = Redis::keys('view:*');
foreach ($keys as $key) {
$mediaId = explode(':', $key)[1];
$views = Redis::get($key);
$replays = Redis::get("replay:$mediaId") ?? 0;
DB::table('media')->where('id', $mediaId)->update([
'views_count' => DB::raw("views_count + $views"),
'replay_count' => DB::raw("replay_count + $replays")
]);
Redis::del("view:$mediaId");
Redis::del("replay:$mediaId");
}
This way, your main database only sees updates every few minutes, not every few milliseconds.
π§ Bonus: Querying Redis Keys
# All view keys
KEYS view:*
# Safer in production
SCAN 0 MATCH view:* COUNT 100
# Get counter value
GET view:4382
βοΈ Final Notes
β Start with Redis + DB flush
π Add message queue (e.g., BullMQ, Sidekiq) if scale grows
π Use Redis Streams or analytics DB (e.g., ClickHouse) for full logs later
π Protect routes with throttling to avoid abuse
π Conclusion
Redis counters give you a clean, scalable foundation to track video engagement like views and replays without crushing your database. This approach is perfect for apps where speed and simplicity matter.
Subscribe to my newsletter
Read articles from Mohammad Shabaz Moosa directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
