All specs
uxhigh complexity

Messaging

Used in 4 specs

Real-time text communication between users — channels, DMs, and threads.

Options

Conversation Types*

Private conversations between two users
Private multi-person conversations
Topic-based rooms users can join
Replies scoped to a specific message

Message History*

Messages are not stored; live session only
Recent messages only; older messages purged
Complete message archive, searchable

Rich Content

React to messages with emoji
Attach files to messages
Auto-expand URLs with metadata

Decision Points

Do users need to communicate in groups beyond 1:1?

If yes

Add channels. Start with just public channels; add private later.

If no

Direct messages only is much simpler to implement and moderate.

Is message history a compliance or product requirement?

If yes

Use full history. Plan your archiving and retention policy up front.

If no

Limited history or ephemeral reduces storage cost and GDPR surface.

Is synchronous real-time required, or is async acceptable?

If yes

Real-time via WebSocket or SSE — users expect sub-second delivery in chat. Budget for pub/sub fan-out infrastructure.

If no

Async messaging (poll-on-open, email-style) is dramatically simpler and fine for inbox-style products.

Support threaded replies off a specific message?

If yes

Add a parent_message_id column; surface threads as a side-panel to avoid polluting the main channel stream.

If no

Flat channels are simpler — users can quote-reply to fake threading.

Show typing indicators?

If yes

Broadcast ephemeral "user is typing" events over the same WebSocket/pub-sub channel — do not persist them.

If no

Skip typing indicators for async or low-volume chat; they add connection chatter without proportional value.

Show read receipts?

If yes

Track a per-user last_read_message_id per conversation; update on message view. Expect user pushback on privacy — make it opt-out per user.

If no

Skip read receipts for privacy-forward or async products — they create social pressure users often dislike.

End-to-end encryption required?

If yes

Use Signal protocol or MLS — but E2EE kills server-side search, moderation, and link preview. Accept those tradeoffs explicitly.

If no

TLS in transit plus encryption at rest is the standard baseline for business messaging.

Voice or video calls in addition to text?

If yes

Use a third-party (Daily, Twilio, LiveKit) — building WebRTC infra from scratch is a multi-quarter project.

If no

Text-only keeps you focused. Add calls via embedded providers only when users are actively requesting them.

File and media sharing within messages?

If yes

Wire in object storage and content-type validation; virus-scan uploads in public spaces. Presigned URLs for direct upload.

If no

Text-only messaging sidesteps storage, moderation, and security burden entirely.

Full-text search over messages?

If yes

Postgres tsvector or SQLite FTS5 up to ~10M messages; dedicated engine (Meilisearch, Typesense) beyond that.

If no

Skip search in ephemeral or short-history products — there is nothing worth indexing.

Allow edit and delete after send?

If yes

Show an edited marker; tombstone deletes in threaded views to preserve reply context. Audit-log edits for compliance.

If no

Immutable messages are correct for audit-sensitive contexts (finance, legal, regulated chat).

Queue messages sent while offline for later delivery?

If yes

Client-side outbox plus server-side reconciliation on reconnect — essential for mobile and spotty-network users.

If no

Fail-fast (error on send if offline) is simpler but poor UX on mobile.

Emoji reactions on messages?

If yes

Simple join table (message, user, emoji) — cuts reply noise dramatically and is a cheap engagement feature.

If no

Skip if your product is async-only or formal (compliance chat) where casual reactions add nothing.

Reactions on thread-level (not just individual messages)?

If yes

Support reactions on thread parents as first-class — useful in collaboration tools where teams converge on a decision.

If no

Message-level reactions only keep the data model simpler.

Push-to-device notifications for new messages?

If yes

Integrate APNs and FCM. Batch notifications to avoid flooding — one push per channel per minute, not per message.

If no

Skip push for web-only products; in-app badges plus email digests cover the re-engagement need.

Per-message delivery confirmation (sent/delivered/read)?

If yes

Track three states per recipient — storage grows quickly (N states × M recipients per message). Expensive on large channels.

If no

Single "sent" state is enough for most chat products. Add granularity only when users ask.

Tradeoffs

ComplexityChannels + threads selected

Message routing logic grows significantly; fan-out to members must be handled carefully

CostFull history selected

Storage costs grow unbounded; requires indexing strategy for search

ComplexityFile uploads selected

Requires object storage (S3/R2) and content moderation policy

ComplexityLink unfurl selected

Server must fetch external URLs on behalf of users; adds latency and SSRF risk

Go Deeper

Dependencies

user-systemnotifications

Implementation Examples

Stream Chat

Scalable chat API with SDKs for React, iOS, and Android — channels, threads, and reactions built in.

Sendbird

Chat, voice, and video APIs for in-app communications at scale.

Ably

Real-time messaging infrastructure with pub/sub, presence, and history.

Used by specs

Project Management ToolMarketplace PlatformSlack-like Messaging AppSocial / Community App