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.
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
