Backend Development 19 min read

Design and Optimization Strategies for High‑Concurrency Instant Messaging Processing

This article explains how to handle high‑concurrency instant‑messaging scenarios by designing message deduplication, optimizing SQLite write performance with batch inserts and WAL mode, improving query speed with indexes and caching, and reducing UI refresh overhead through delayed and scroll‑aware updates.

JD Retail Technology
JD Retail Technology
JD Retail Technology
Design and Optimization Strategies for High‑Concurrency Instant Messaging Processing

In the instant‑messaging domain, handling high‑concurrency messages is critical; for example, during promotions the JD customer‑service system may receive a flood of user inquiries that must be displayed and responded to quickly to avoid user loss.

The message flow is: server pushes messages to the client, they are placed in a queue, processed, and finally rendered on the UI. The article breaks down each step and its optimizations.

Message Deduplication Design

Clients send acknowledgments after storing messages; if the server does not receive an ack (due to slow processing or network loss) it assumes the client missed the message and resends it, leading to duplicate processing and resource waste.

1.1 Duplicate Message Filtering Mechanism

Before a message enters the processing queue, a filter checks whether an identical message is already queued; if so, the new message is discarded.

1.2 Local Cache Filtering Mechanism

After a message reaches the queue, the system checks a local cache (memory + database) to see if the message has already been processed; if found, it is dropped, saving a database I/O.

Write Performance Optimization

2.1 Message Batch Write

Instead of inserting each message individually, messages are accumulated and written in a transaction. This reduces file open/close overhead and the number of fsync() calls.

The following table shows write times on an iPhone 6s for single‑insert vs. batch‑insert approaches:

Data Count (rows)

Single Insert (ms)

Batch Insert (ms)

1

6

6

10

34

11

50

96

21

100

120

32

500

551

90

1,000

909

163

2,000

2,230

325

Batch writes dramatically improve performance for larger data sets, though they add code complexity.

2.2 Enabling WAL Mode

SQLite’s Write‑Ahead Log (WAL) mode further speeds up writes by appending changes to a -wal file and committing them later via a checkpoint. To enable it, execute:

PRAGMA journal_mode = WAL;

WAL also reduces the number of fsync() calls, improving write throughput.

Performance comparison (iPhone 6s):

Rows

Rollback (ms)

WAL (ms)

1

6

2

10

34

10

50

96

32

100

20

40

500

551

105

1,000

909

270

2,000

2,230

535

WAL yields 3‑4× faster writes while read performance remains comparable.

Query Performance Optimization

3.1 Adding Indexes to Frequently Queried Columns

SQLite uses B+‑tree indexes. Adding appropriate indexes (single, unique, implicit, composite) can drastically reduce disk I/O.

Example of creating a composite index:

ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');

Follow the “left‑most prefix” rule to ensure queries can use the index.

Benchmark (iPhone 6s) shows indexed queries are orders of magnitude faster, especially as table size grows.

Rows

No Index (ms)

With Index (ms)

1,000

4

2

5,000

5

2

10,000

14

2

50,000

37

2

100,000

62

2

500,000

195

2

1,000,000

567

5

While indexes boost read speed, they consume disk space and add overhead to inserts/updates, so they should be used judiciously.

3.2 Adding an In‑Memory Cache Layer

Placing a key‑value cache in front of the DB allows reads to be served from memory, avoiding costly disk I/O. The cache key is typically the primary key or another frequently queried unique column.

Message UI Refresh Design

4.1 Delayed Refresh

When a message reaches the UI queue, delay the actual UI update by a short interval (e.g., 100 ms). If new messages keep arriving, keep delaying until a maximum threshold (e.g., 2 s) is reached, then flush the UI.

4.2 Pause Refresh During Scrolling

While the user scrolls the conversation list, suspend UI refreshes and resume once scrolling stops. On iOS this can be achieved by adding a timer to NSDefaultRunLoopMode .

Complete Design Overview

The final diagram summarizes the end‑to‑end processing pipeline from message reception to UI display, incorporating deduplication, batch writes, WAL, indexing, caching, and UI refresh strategies.

By applying these four optimization dimensions—message deduplication, write‑performance tuning, query‑performance enhancement, and UI refresh design—developers can build robust, high‑throughput instant‑messaging solutions.

performance optimizationhigh concurrencySQLiteWALInstant MessagingMessage Deduplication
JD Retail Technology
Written by

JD Retail Technology

Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.

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.