How WeChat Powers Group Chats and Red Packets: Inside the Backend Architecture

This article dissects the design of WeChat's group chat system, covering functional and non‑functional requirements, high‑level component architecture, database schemas, face‑to‑face group creation, real‑time messaging, red‑packet algorithms, and Go code implementation, revealing how massive concurrency, performance, and storage challenges are solved.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
How WeChat Powers Group Chats and Red Packets: Inside the Backend Architecture

Introduction

Hello, I am Su San. While chatting in a WeChat group, a congratulatory message "恭喜发财,大吉大利" appeared, prompting the question: how is the group chat system, including the famous red‑packet feature, designed?

WeChat Group Chat System Design

WeChat, with over a billion users, offers a core group‑chat capability that can host hundreds of friends or strangers in a single group space.

Have you ever wondered how this system works under the hood? Let's explore.

System Requirements

2.1 Functional Requirements

The group‑chat feature allows users to create circles, manage members, send various media, and grab red packets.

Create Group Chat : Users can create a new group and invite friends or strangers.

Group Management : Owners and admins manage members, set rules, and permissions.

Message Send/Receive : Supports text, images, audio, video, and pushes them to all members.

Real‑time Communication : Messages are delivered instantly for interactive chat.

Grab Red Packet : Users can send any number of red packets with random amounts, and members can claim them.

2.2 Non‑functional Requirements

High Concurrency : Must support millions of users creating and using groups simultaneously.

High Performance : Fast message delivery and response are essential.

Massive Storage : Scalable storage for massive text, image, audio, and video data.

High‑level Design

We consider core components and basic business flow.

3.1 Core Components

The system involves the following components and protocols.

Client : Receives group messages on mobile or PC and forwards them to the backend.

WebSocket Transport Protocol : Low‑overhead, high‑real‑time communication between client and server.

Long‑Connection Cluster : Maintains WebSocket connections and forwards messages to application servers.

Message Processing Server Cluster : Handles real‑time message processing, storage, and database interaction.

Message Push Server Cluster : Routes messages to the correct group members.

Database Server Cluster : Stores user text, image thumbnails, and media metadata.

Distributed File Storage Cluster : Stores user images, audio, and video files.

3.2 Business High‑level Design

Group Creation

Unique ID Allocation : Generate a unique group ID (e.g., using Snowflake or MySQL auto‑increment).

Group Info Storage : Store group ID, name, creator ID, etc., in the group table.

Member Association : Add the creator as the first member and admin.

Message History : Associate the group ID with historical messages for new members.

In addition to friend‑invited groups, WeChat supports face‑to‑face group creation.

We will dive into three core functions: face‑to‑face group, message send/receive, and red packet.

Face‑to‑Face Group

A user initiates a face‑to‑face group by entering a random 4‑digit code; nearby users enter the same code to join.

4.1 Database Table Design

User Table : Stores user ID, nickname, avatar, etc.

Group Table : Stores group ID, name, creator ID, member count.

GroupMember Table : Links users to groups.

RandomCode Table : Stores the random code and associated group ID.

4.2 Core Business Interaction Flow

User A creates a group, the system stores HashMap {random code, user list[UserA(ID, name, avatar)]} in cache with a 3‑minute TTL. {随机码,用户列表[用户A(ID、名称、头像)]} User B enters the same code, sees the waiting page with other members' avatars and nicknames.

When the first user clicks “Enter Group”, the random code is saved in the RandomCode table and linked to the new group ID, updating member count.

The system then stores user and group info in Group and GroupMember tables.

Member Join and Refresh

When users B and C join with the code, the backend validates the code, checks cache expiration, ensures the group is not full (max 500), and inserts them into GroupMember, returning a success response.

The client updates the group list to show the new members.

Other Technical Components

Redis GeoHash can be used to locate users within a 50‑meter radius.

Message Sending and Receiving

When a member sends a message, the system processes distribution, notifies other members, and ensures proper display.

5.1 Interaction Flow

User A sends a message with media (image, video, audio).

The client uploads the content and media to the backend.

The backend stores the message in the Message table and media in the distributed file storage cluster, recording MediaID, thumbnails, etc.

The backend broadcasts the message to all group members; the client renders it according to its type.

When a user clicks a thumbnail, the client retrieves the media path via MediaID from object storage and displays it.

5.2 Message Storage and Display

Key tables:

Message Table : Stores each message with ID, type, content, sender ID, group ID, timestamp.

Media Table : Stores uploaded images, videos, audio with unique MediaID, path, uploader, timestamp.

MessageState Table : Tracks read/unread status per user for push notifications and unread counts.

MySQL select count queries cause full table scans, slowing unread count retrieval.

To improve performance, unread counts are cached in Redis; when the count exceeds 99 it is capped at 100 and displayed as “99+”.

Red Packet

The red‑packet feature lets users send any number of packets with random amounts; each claim must be at least 0.01 ¥.

6.1 Database Design

redpack Table fields: id (PK), totalAmount, surplusAmount, total (packet count), surplusTotal, userId (sender).

redpack_record Table fields: id (PK), redpackId (FK), userId, amount (claimed).

6.2 Real‑time

Send Red Packet

User sets total amount and count; a record is inserted into the red‑packet table.

Redis stores a record with red‑packet ID and total participants.

The red‑packet notification is pushed to all group members.

Grab Red Packet

Since 2015, grabbing and opening a red packet are separate steps; sometimes the packet is already exhausted.

User receives notification and opens the group chat.

Backend validates eligibility (not already claimed).

If valid, the backend allocates an amount and records the claim.

User sees the amount; status changes to “claimed”.

Asynchronously, the amount is transferred to the user's wallet.

6.3 Red Packet Allocation Algorithm

Real‑time Split

Amount is calculated at grab time using a random algorithm.

Pre‑generate

Amounts are split beforehand; grabbing simply takes the next pre‑generated value.

Double Average Method

We adopt the double‑average method for real‑time split: each claim is a random value between 0.01 and twice the current average (remaining amount ÷ remaining count).

Thus large differences may appear, but that’s the fun! 🐶

Example: remaining amount 10 ¥, remaining count 5 → average 2 ¥, claim range 0.01 ~ 4 ¥.

Algorithm Optimization

Observations suggest the algorithm may pre‑process amounts, ensuring each packet has a minimum of 0.01 ¥.

Go implementation:

import (
    "fmt"
    "math"
    "math/rand"
    "strconv"
)

type RedPack struct {
    SurplusAmount float64 // remaining amount
    SurplusTotal  int    // remaining packet count
}

// keep two decimal places
func remainTwoDecimal(num float64) float64 {
    numStr := strconv.FormatFloat(num, 'f', 2, 64)
    num, _ = strconv.ParseFloat(numStr, 64)
    return num
}

// get random red packet amount
func getRandomRedPack(rp *RedPack) float64 {
    if rp.SurplusTotal <= 0 {
        return 0
    }
    if rp.SurplusTotal == 1 {
        return remainTwoDecimal(rp.SurplusAmount + 0.01)
    }
    avgAmount := math.Floor(100*(rp.SurplusAmount/float64(rp.SurplusTotal))) / 100
    avgAmount = remainTwoDecimal(avgAmount)
    rand.NewSource(time.Now().UnixNano())
    var max float64
    if avgAmount > 0 {
        max = 2*avgAmount - 0.01
    } else {
        max = 0
    }
    money := remainTwoDecimal(rand.Float64()*max + 0.01)
    rp.SurplusTotal -= 1
    rp.SurplusAmount = remainTwoDecimal(rp.SurplusAmount + 0.01 - money)
    return money
}

func main() {
    rp := &RedPack{SurplusAmount: 0.06, SurplusTotal: 5}
    // reserve 0.01 per packet
    rp.SurplusAmount -= 0.01 * float64(rp.SurplusTotal)
    total := rp.SurplusTotal
    for i := 0; i < total; i++ {
        fmt.Println(getRandomRedPack(rp))
    }
}
0.01、0.01、0.01、0.01、0.02

The result matches expectations.

Conclusion

The WeChat group‑chat and red‑packet features hide complex interaction techniques and carefully crafted product experiences. By combining core components, database tables, and detailed interaction flows, users can effortlessly enjoy group communication and red‑packet fun, which is a key reason for WeChat's massive popularity.

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.

Backend ArchitectureGoSystem Designhigh concurrencyWeChatred packetgroup chat
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

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.