How to Elegantly Implement an Online User Count with Redis ZSET

This article explains how to build a real‑time online user counter by identifying users via tokens or browser fingerprints, storing them in a Redis sorted set, and using ZADD, ZRANGEBYSCORE, ZREMRANGEBYSCORE and ZREM commands to add, query, and clean the data.

SpringMeng
SpringMeng
SpringMeng
How to Elegantly Implement an Online User Count with Redis ZSET

Introduction

Online user counting is a common requirement; the article proposes using Redis sorted set (ZSET) to store active users.

Online user count diagram
Online user count diagram

Identifying Online Users

For sites that require login, a valid token indicates that the user is online. For public sites, a unique identifier such as a browser fingerprint (User‑Agent, HTTP headers, screen resolution, timezone, plugins) can be generated using JavaScript libraries like FingerprintJS or ClientJS. The fingerprint is stored in a cookie or header and sent to the backend.

// Install: npm install @fingerprintjs/fingerprintjs
// Usage example:
import FingerprintJS from '@fingerprintjs/fingerprintjs';
FingerprintJS.load().then(fp => {
  fp.get().then(result => {
    const visitorId = result.visitorId;
    console.log(visitorId);
  });
});

Implementation Steps

1. Add online user with ZADD

The zadd command takes three arguments: key (the ZSET name), score (a numeric value, here the expiration timestamp), and member (the user identifier).

Example of adding a simple member: ZADD myzset 1 "one" In practice the code adds a user token with an expiration time as the score, ensuring each user appears only once with the latest login state:

LocalDateTime expireTime = LocalDateTime.now().plusSeconds(expireTimeout);
String expireTimeStr = DateUtil.formatFullTime(expireTime);
redisService.zadd("user.active", Double.parseDouble(expireTimeStr), userToken);

2. Query online count with ZRANGEBYSCORE

zrangeByScore

returns members whose scores fall within a given range. To obtain all currently active users, query from the current timestamp to +inf:

String now = DateUtil.formatFullTime(LocalDateTime.now());
Set<String> userOnlineStringSet = redisService.zrangeByScore("user.active", now, "+inf");
int onlineCount = userOnlineStringSet.size();

3. Remove expired entries with ZREMRANGEBYSCORE

A scheduled task deletes members whose scores are older than the current time, effectively clearing offline users:

String now = DateUtil.formatFullTime(LocalDateTime.now());
redisService.zremrangeByScore("user.active", "-inf", now);

4. Remove a user on logout with ZREM

When a user explicitly logs out, remove the corresponding member from the ZSET:

redisService.zrem("user.active", "xxx");

Conclusion

The core logic is to maintain a Redis ZSET where the member is the user identifier and the score is the expiration timestamp. Adding, querying, and cleaning the set with zadd, zrangeByScore, zremrangeByScore and zrem provides a simple, efficient way to count online users.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

backendjavaredisZSETFingerprintJSOnline Users
SpringMeng
Written by

SpringMeng

Focused on software development, sharing source code and tutorials for various systems.

0 followers
Reader feedback

How this landed with the community

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.