Implementing Online User Count with Redis Sorted Sets (zadd, zrangeByScore, zremrangeByScore, zrem)
This article explains how to track online users by storing their identifiers in a Redis sorted set, using zadd to add entries, zrangeByScore to query active users, and zremrangeByScore and zrem to clean up expired or logged‑out sessions, with code examples in Java and JavaScript.
Online user statistics can be efficiently implemented using Redis sorted sets (zset). The core Redis commands involved are zadd , zrangeByScore , zremrangeByScore , and zrem .
First, determine whether a user is online. For authenticated sites, check the token's validity; for public sites, generate a unique identifier using browser fingerprinting libraries such as FingerprintJS or ClientJS.
Example of using FingerprintJS in a Node.js project:
// install: npm install @fingerprintjs/fingerprintjs
// usage example:
import FingerprintJS from '@fingerprintjs/fingerprintjs';
FingerprintJS.load().then(fp => {
// get visitor ID
fp.get().then(result => {
const visitorId = result.visitorId;
console.log(visitorId);
});
});When a user accesses the site, store the generated ID in a cookie or request header and send it to the backend.
1) Adding online users with zadd
key: name of the sorted set
score: expiration timestamp (e.g., current time + timeout)
member: user token or visitor ID
Example (Java):
// expireTime gives the token an expiration time
LocalDateTime expireTime = LocalDateTime.now().plusSeconds(expireTimeout);
String expireTimeStr = DateUtil.formatFullTime(expireTime);
// add user token to the sorted set
redisService.zadd("user.active", Double.parseDouble(expireTimeStr), userToken);Using the timestamp as the score ensures each user has only one latest entry.
2) Querying online users with zrangeByScore
key: the sorted set name
min and max: score range (e.g., now to +inf)
Example (Java):
// get current time
String now = DateUtil.formatFullTime(LocalDateTime.now());
// query all members with score between now and +inf
Set
userOnlineStringSet = redisService.zrangeByScore("user.active", now, "+inf");The size of userOnlineStringSet represents the number of online users.
3) Removing expired users with zremrangeByScore
Periodically delete entries whose score (expiration time) is less than the current time:
// get current time
String now = DateUtil.formatFullTime(LocalDateTime.now());
// remove all members with score between -inf and now
redisService.zremrangeByScore("user.active", "-inf", now);4) Removing a specific user on logout with zrem
// delete a specific member (e.g., "xxx")
redisService.zrem("user.active", "xxx");By combining these operations, you can maintain a real‑time online user count: add a user with zadd , query active users with zrangeByScore , and clean up stale entries with zremrangeByScore or zrem . The approach is simple, efficient, and works across multiple programming languages.
Conclusion
The key idea is to use a Redis sorted set where each member represents a user identifier and the score represents the expiration timestamp; then perform add, query, and delete operations to keep the online user count accurate.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.