Backend Development 6 min read

Designing Efficient Read/Unread Tracking for Enterprise Group Chats

The article analyzes the memory inefficiency of storing per‑message read/unread user lists in large group chats and proposes a bitmap‑based solution that maps users to sequential IDs, uses compact bitmaps for read status and handles member exits, achieving over 95% storage reduction.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Designing Efficient Read/Unread Tracking for Enterprise Group Chats

A friend shared an interview question about implementing the read/unread feature in enterprise IM group chats (e.g., WeChat Work, DingTalk), where each message has a unique messageid and each user a unique userid . The naive approach stores two lists— readids and unreadids —for every message, which quickly becomes memory‑intensive.

Analysis shows that the naive design consumes 8 bytes per group member per message (e.g., a 200‑person active group would need 1.6 KB per message), which is unacceptable for mobile clients and costly for servers.

To reduce space, the article suggests using a bitmap. First, each group member is assigned an auto‑incrementing mapid that maps bidirectionally to the userid :

struct UserInfo {
    uint64_t userid;
    uint32_t mapid;
};

struct GroupMetaInfo {
    vector
members;
    string name;
    uint32_t maxid;
    // other info
};

When a message is sent, its read/unread status can be stored as a compact structure:

{ uint32_t maxid, uint8_t readbit[] }

For a group of five members, the storage becomes {5, readbit[0]=bin(0000 0000)} (5 bytes). If member D reads the message, the bitmap updates to {5, readbit[0]=bin(0000 1000)} ; when all four non‑sender members have read it, it becomes {5, readbit[0]=bin(0001 1110)} .

Member departure is handled by a soft‑delete flag: leaving members are marked but not physically removed, preserving their mapid . An additional quitbit bitmap records whether a member had left at the time a message was sent, resulting in a final storage format {maxid, readbit[], quitbit[]} .

The benefits are substantial: the per‑member cost drops from 8 bytes to 2 bits, saving roughly 95 % of space (e.g., 200 members require only about 54 bytes per message instead of 1.6 KB). The design also scales well as long as group size limits are respected, and fallback to the original method is possible if maxid grows excessively.

backendstorage optimizationbitmapData StructureGroup Chatread-unread
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

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.