Messaging
Real-time text communication between users — channels, DMs, and threads.
Options
Conversation Types*
Message History*
Rich Content
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
Message routing logic grows significantly; fan-out to members must be handled carefully
Storage costs grow unbounded; requires indexing strategy for search
Requires object storage (S3/R2) and content moderation policy
Server must fetch external URLs on behalf of users; adds latency and SSRF risk
Go Deeper
Message transport architecture
How messages move from sender to recipients — protocol choice, ordering, and delivery semantics.
Channel and membership architecture
Data model for channels, membership, permissions, and the fan-out problem at scale.
Message search and history retrieval
How to make millions of messages searchable without killing your database.