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.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
How to Track Online Users with Redis Sorted Sets (ZSET) – A Step‑by‑Step Guide

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
zrem

The sorted set stores each user identifier as a member and the expiration timestamp as the score, allowing constant‑time addition, range queries, and cleanup.

Redis ZSET diagram
Redis ZSET diagram

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.

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.

JavaBackend DevelopmentredisNode.jsZSetFingerprintJSOnline Users
Java Architect Essentials
Written by

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.

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.