Implementing Online User Counting with Redis Sorted Sets (ZSET)
This article explains how to track online users using Redis sorted sets by describing the core ZSET commands (zadd, zrangeByScore, zremrangeByScore, zrem), showing code examples for adding, querying, and cleaning up user sessions, and discussing fingerprint-based identification methods.
Online user counting is a common requirement, and a practical way to implement it is by using Redis sorted sets (ZSET) to store user identifiers with expiration timestamps as scores.
1. Introduction
The core Redis commands used are zadd , zrangeByScore , zremrangeByScore , and zrem .
2. Implementation Steps
2.1 Determining Whether a User Is Online
If the site requires login, the validity of the user's token can be used to judge online status. For public sites, a custom rule such as browser fingerprinting is recommended. Fingerprint data may include User-Agent, headers, screen resolution, timezone, language, plugins, etc.
Example using FingerprintJS:
import FingerprintJS from '@fingerprintjs/fingerprintjs';
FingerprintJS.load().then(fp => {
fp.get().then(result => {
const visitorId = result.visitorId;
console.log(visitorId);
});
});2.2 Adding Online Users with zadd
The zadd command requires a key, a score, and a member. Example:
ZADD myzset 1 "one"In Java, adding a user token with an expiration timestamp as the score:
// Set expiration time for the token
LocalDateTime expireTime = LocalDateTime.now().plusSeconds(expireTimeout);
String expireTimeStr = DateUtil.formatFullTime(expireTime);
// Add token to the sorted set
redisService.zadd("user.active", Double.parseDouble(expireTimeStr), userToken);This ensures each user has only one latest entry because the score (timestamp) is unique.
2.3 Querying Online Users with zrangeByScore
To get all users whose scores are within a range (e.g., from now to +inf):
ZRANGEBYSCORE myzset 1 3Java example:
// Get current time
String now = DateUtil.formatFullTime(LocalDateTime.now());
// Query users with scores from now to +inf
Set
userOnlineStringSet = redisService.zrangeByScore("user.active", now, "+inf");The size of userOnlineStringSet represents the number of online users.
2.4 Periodically Removing Expired Users with zremrangeByScore
Example to delete members with scores between 1 and 3:
ZREMRANGEBYSCORE myzset 1 3Java scheduled task:
// Get current time
String now = DateUtil.formatFullTime(LocalDateTime.now());
// Remove entries from -inf to now
redisService.zremrangeByScore("user.active", "-inf", now);2.5 Removing a User on Logout with zrem
Example to delete a specific member:
ZREM myzset "xxx"Java code:
redisService.zrem("user.active", "xxx");3. Summary
The solution creates a Redis sorted set where each online user is a member, the expiration timestamp is the score, and the set is manipulated using the four ZSET commands to add, query, and clean up user sessions efficiently.
Note: The article also contains promotional material for ChatGPT services, a community group, and related offers, which are not part of the technical tutorial.
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.