How to Track Online Users with Redis Sorted Sets (ZSET) – A Step‑by‑Step Guide
This article explains how to implement an online‑user counter using Redis sorted sets by detailing the four essential ZSET commands, fingerprint‑based user identification, Java and JavaScript code examples, and scheduled cleanup for accurate real‑time statistics.
Overview
This guide demonstrates a lightweight real‑time online‑user counter built on Redis sorted sets (ZSET). Four Redis commands are used:
zadd zrangebyscore zremrangebyscore zremThe sorted set stores each user identifier as a member and the expiration timestamp as the score, allowing constant‑time addition, range queries, and cleanup.
Step 1 – Identify an Online User
For authenticated sites, verify the session token. For public sites, generate a stable identifier (e.g., browser fingerprint) and send it to the backend, typically via a cookie or request header.
import FingerprintJS from '@fingerprintjs/fingerprintjs';
FingerprintJS.load().then(fp => {
fp.get().then(result => {
const visitorId = result.visitorId;
console.log(visitorId);
});
});Step 2 – Add or Refresh a User with zadd
Use the current time plus a configurable timeout as the score. This guarantees that a user appears only once in the set because a later zadd overwrites the previous score.
// Java example (Spring RedisTemplate wrapper)
LocalDateTime expireTime = LocalDateTime.now().plusSeconds(expireTimeout);
String expireScore = DateUtil.formatFullTime(expireTime); // e.g. "2024-04-18T12:34:56"
redisService.zadd("user.active", Double.parseDouble(expireScore), userToken);Step 3 – Query Online Users with zrangebyscore
Retrieve all members whose score is greater than or equal to the current timestamp. The result size equals the number of online users.
// Java example
String now = DateUtil.formatFullTime(LocalDateTime.now());
Set<String> onlineUsers = redisService.zrangeByScore("user.active", now, "+inf");
int onlineCount = onlineUsers.size();Step 4 – Periodic Cleanup with zremrangebyscore
Because ZSET entries do not expire automatically, schedule a task that removes all members whose score is less than the current time.
// Java scheduled task
String now = DateUtil.formatFullTime(LocalDateTime.now());
redisService.zremrangeByScore("user.active", "-inf", now);Step 5 – Remove a User on Logout with zrem
When a user explicitly logs out, delete the corresponding member.
// Java example
redisService.zrem("user.active", userToken);Key Points
The ZSET key (e.g., user.active) groups all online identifiers.
Member = unique user identifier (token, fingerprint, etc.).
Score = expiration timestamp (epoch or formatted datetime). Using a timestamp ensures that a later login automatically updates the entry.
Adding, querying, and cleaning the set are O(log N) or O(1) operations, making the solution suitable for high‑traffic services.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow 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.
