Backend Development 7 min read

Implementing Online User Counting with Redis Sorted Sets (zset)

This article explains how to track online users by assigning each user a unique identifier, storing it in a Redis sorted set with an expiration timestamp, and using zadd, zrangeByScore, zremrangeByScore, and zrem commands together with browser fingerprinting to reliably count and clean up active sessions.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Implementing Online User Counting with Redis Sorted Sets (zset)

Hello! I'm sum Mo, a frontline developer who enjoys researching and documenting technical topics. This article describes a common online user counting feature implemented with Redis sorted sets (zset) and outlines the core Redis commands used.

1. Determining whether a user is online – For authenticated sites, the validity of a user token can be used; for public sites, techniques such as IP, deviceId, or browser fingerprinting are employed. Browser fingerprinting (e.g., using FingerprintJS or ClientJS) collects data like User-Agent, headers, screen resolution, timezone, language, and plugins to generate a unique ID.

// 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);
  });
});

The generated visitor ID is sent to the backend (via cookie or header) and used as the member in the Redis sorted set.

2. Adding online users with zadd

zadd takes a key, a score, and one or more members. Example: ZADD myzset 1 "one"

When a user logs in, we calculate an expiration timestamp and add the token to the sorted set:

// Set expiration time for the user token
LocalDateTime expireTime = LocalDateTime.now().plusSeconds(expireTimeout);
String expireTimeStr = DateUtil.formatFullTime(expireTime);
// Add token to sorted set
redisService.zadd("user.active", Double.parseDouble(expireTimeStr), userToken);
Because a user may log in multiple times, the same token could be added repeatedly; using the expiration timestamp as the score ensures only the latest login is kept.

3. Querying online users with zrangeByScore

zrangeByScore retrieves members whose scores fall within a given range. Example: ZRANGEBYSCORE myzset 1 3

To get all currently online users we query from the current time to +inf :

// Get current timestamp
String now = DateUtil.formatFullTime(LocalDateTime.now());
// Retrieve all users with score >= now
Set
userOnlineStringSet = redisService.zrangeByScore("user.active", now, "+inf");
The size of userOnlineStringSet represents the number of online users.

4. Periodic cleanup with zremrangeByScore

zremrangeByScore removes members whose scores fall within a range. Example: ZREMRANGEBYSCORE myzset 1 3

A scheduled task removes entries whose expiration time is earlier than the current time:

// Get current timestamp
String now = DateUtil.formatFullTime(LocalDateTime.now());
// Remove all members with score <= now
redisService.zremrangeByScore("user.active", "-inf", now);

This ensures that offline users are automatically purged from the set.

5. Removing a user on logout with zrem

zrem deletes specific members from a sorted set. Example: ZREM myzset "xxx"
// Delete a specific member (e.g., when the user logs out)
redisService.zrem("user.active", "xxx");

Removing the member guarantees that a voluntarily logged‑out user is no longer counted as online.

Conclusion – By creating a Redis sorted set where the key is the online‑user collection, the member is the user identifier, and the score is the expiration timestamp, we can efficiently add, query, and clean up online user data with a few simple Redis commands.

backendJavaJavaScriptRedisZsetFingerprintJSOnline Users
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.