How to Create a Messaging App: Architecture and Cost
A messaging app looks simple and is a distributed-systems problem underneath. This guide walks delivery guarantees and ordering, the long-lived transport, fan-out and storage, end-to-end encryption in plain terms, push and presence on a battery budget, and what the build costs.

If you map out how to create a messaging app, the screens trick you into thinking it is a small project. A list of conversations, a thread of bubbles, a text box. Having built realtime products to production, we can report that the screens are the part that ships first and matters least. A messaging app is a distributed-systems problem wearing a chat UI: a message has to arrive exactly once, in the right order, even when the sender was offline when they pressed send and the recipient was offline when it landed. Chat app development is mostly the engineering behind that guarantee. This guide walks it in the order the decisions actually have to be made: delivery and ordering, the transport, storage and fan-out, encryption, push and presence, and what the whole thing costs.
The short version
- The hard part of a messaging app is not the UI but the delivery guarantee: making each message arrive once and in order even when either side was offline, which an idempotency key plus a server-assigned sequence number solves.
- Realtime chat rides a long-lived connection, and WebSocket is the default, with MQTT the common pick for low-power mobile networks.
- Message delivery uses the inbox/timeline fan-out pattern: fan out on write for 1:1 and small groups, and switch to fan-out-on-read for large channels.
- End-to-end encryption is right for private consumer messaging but works against team or support apps that need server-side search and compliance, where TLS plus encryption at rest is the honest choice.
- Because a backgrounded app has no open socket, notifications go through APNs on iOS and FCM on Android, and presence stays approximate to protect the battery.
- A 1:1 and small-group chat MVP is an 8 to 16 week build on one platform, and cost scales with encryption, group scale, whether you build or rent the transport, and platform count.
Messaging is a delivery-guarantee problem
Start with the contract, because every other system inherits it: a message the user sent must be delivered, once, and conversations must read in the order they happened. That sounds obvious and is the hardest thing in the product.
Networks lose packets, phones drop off Wi-Fi mid-send, and servers retry. If the client sends a message and the connection dies before the ack comes back, the client does not know whether the server got it. The safe move is to retry, which means the server can receive the same message twice. At-least-once delivery is cheap and gives you duplicates; exactly-once is what users expect and nobody gets for free. The standard way to fake exactly-once on top of at-least-once is the idempotency key: the client generates a unique message ID (a UUID or a ULID) before the first send attempt and reuses it on every retry. The server stores messages keyed by that ID, so the second copy of the same send is a no-op instead of a duplicate bubble. The client did the hard part by deciding the identity of the message before the network got involved.
Ordering is the second half of the contract. Wall-clock timestamps from clients are useless for ordering: phone clocks drift, and two messages can carry the same millisecond. Order is assigned server-side, per conversation, with a monotonic sequence number. The client renders by that sequence, not by send time, so a message that took three seconds to reach the server still lands in the slot the server gave it.
Then there is the user who was offline. Their messages queue locally and flush when the connection returns; meanwhile the conversation moved on without them. So the device also needs to sync, to ask the server "what did I miss since sequence N?" and merge the answer with whatever it sent while disconnected. The offline queue going out and the sync coming back are the two halves of making a network you do not control feel like a reliable one. Get this layer right and the app feels solid on a subway; get it wrong and no amount of UI polish saves it.
The transport: long-lived connections
HTTP request-response is the wrong shape for chat, because the defining feature is the server pushing a message to a client that did not ask at that moment. That needs a connection held open, and there are three common ways to hold it.
WebSocket is the default for a reason: a single full-duplex TCP connection, bytes flowing both directions, supported everywhere from browsers to native mobile. Most chat backends run on it. MQTT is the pub/sub protocol built for unreliable, low-power networks (it is what Facebook Messenger famously moved to for exactly that reason), and its quality-of-service levels map cleanly onto delivery guarantees: QoS 0 is fire-and-forget, QoS 1 is at-least-once, QoS 2 is exactly-once at the cost of a four-step handshake. Server-sent events are one-directional, server-to-client only, so they cover live updates but still need a separate channel for the client to send, which makes them a poor fit for symmetric chat and a fine fit for a notifications feed.
| Transport | Direction | Best for | Delivery model |
|---|---|---|---|
| WebSocket | Full-duplex, both directions | General-purpose chat, the default choice | Application-level acks; you build the guarantees |
| MQTT | Full-duplex pub/sub | Low-power, unreliable mobile networks | Built-in QoS 0/1/2 maps to at-most/at-least/exactly-once |
| Server-sent events | Server-to-client only | Notification and live update feeds | One-way, so it needs a separate channel to send |
On top of the connection sits a layer of state, and the important distinction is durable versus ephemeral. The messages themselves are durable: they get stored, they survive a reconnect, they are the product. Presence ("online now"), typing indicators, and the live half of read receipts are ephemeral: they describe this moment, and if they are lost in a reconnect nobody cares, because a fresh one arrives in seconds. Storing typing indicators durably is a classic early mistake that turns a cheap signal into write load. Read receipts straddle the line: the fact that a message was read is durable state worth persisting, but the realtime flicker of the checkmark turning blue is ephemeral delivery of that fact.
Connections die constantly on mobile (tunnels, elevators, app backgrounding), so reconnection is not an edge case, it is the steady state. The client reconnects with exponential backoff and jitter: wait a little, then longer, then longer still, with a random offset so ten thousand phones coming back after an outage do not stampede the gateway in lockstep. On reconnect it runs the sync from the previous section. The transport's job is to make a fundamentally flaky link look continuous.
Storage and fan-out
How a message gets from one outbox to the right inboxes depends entirely on the conversation shape, and there are three.
1:1 is the simple case: one sender, one recipient, write the message once, deliver to two devices. Group chat (a bounded set of named members, everyone an equal participant) fans a single send out to every member's inbox; the cost is linear in group size and stays manageable while groups are small. Channels (one-to-many broadcast to a large, loosely-defined audience, the Telegram-channel or Slack-announcement shape) are where naive fan-out breaks, because a single post to a hundred-thousand-member channel is a hundred thousand inbox writes.
The model that absorbs all three is the inbox/timeline pattern borrowed from feed systems: each user has a per-conversation inbox, and delivering a message means appending its ID to the inboxes of the people who should see it. For 1:1 and modest groups you fan out on write (push into every member's inbox at send time) so opening a conversation is a cheap read of a ready list. For large channels you flip to fan-out-on-read for the long tail, storing the message once and assembling the view when a member opens it, because writing to a hundred thousand inboxes for a post most members will never open is wasted work. An MVP should not build the hybrid on day one; it should fan out on write and instrument the group size where the write amplification starts to hurt, so the team sees the cliff coming.
History pagination is a cursor, not an offset. Conversations grow without bound, and OFFSET 10000 makes the database count past ten thousand rows it then throws away. Paginate on the sequence number ("give me 50 messages before sequence N") so scrolling back is a cheap indexed range scan no matter how deep the history goes.
Media attachments never travel through the message channel. The client uploads the photo or file to object storage through a pre-signed URL, and the message carries a reference (a URL plus dimensions and a content hash), not the bytes. The realtime path stays small and fast; the heavy transfer happens out of band over plain HTTPS. If the product grows into voice notes and video, that pipeline is the same upload-transcode-deliver shape our live streaming work runs on, just without the live constraint.
End-to-end encryption, honestly
Transport encryption (TLS) protects messages in flight; encryption at rest protects them on disk. Neither stops the server operator from reading the plaintext, because the server holds the keys. End-to-end encryption (E2E) means only the two endpoints hold the keys, so the server relays ciphertext it cannot read. That is a different and stronger promise, and it costs more than founders expect.
The mechanism most apps reach for is the Signal protocol, and its core is the double ratchet. In plain terms: every message advances a key, so each one is encrypted with a fresh key derived from the last, ratcheting forward like a combination lock that clicks once per message. Compromising one key does not unlock the conversation behind it (forward secrecy) or ahead of it (post-compromise security). It is a genuinely good design, and it is also the reason E2E is expensive to live with.
What E2E takes away is server knowledge, and a surprising amount of product depends on server knowledge. There is no server-side search, because the server only ever sees ciphertext: search has to run on-device against the local copy, which means it cannot find a message that lives only on another device. Key management becomes your problem: keys live on devices, so losing the device can mean losing the history, and "forgot my password" cannot restore what the server never had. Multi-device stops being free: each device is a separate cryptographic identity that has to be provisioned and have keys synced to it, which is most of why multi-device E2E is hard and why it took the major messengers years to ship well.
So the honest position is that you do not always need it. If the promise to users is that private conversations are nobody's business (a consumer messenger), E2E is the product and you pay for it. If the app is team collaboration, customer support, or anything where the business itself needs to search messages, retain them for compliance, or give admins visibility, then E2E works directly against the product, and TLS plus encryption at rest is the right and defensible choice. Deciding this early matters because it reaches into the data model and the multi-device design; bolting E2E onto a server-trusting architecture later is close to a rewrite. We walk this tradeoff with founders on every chat app development engagement, because the wrong default here is expensive in both directions.
Push, presence, and the battery budget
A messaging app spends most of its life backgrounded, and a backgrounded app has no open socket: mobile operating systems suspend it to save battery. So when a message arrives for a user who is not in the app, the server cannot reach them directly. It goes through the platform push services: APNs on iOS, FCM on Android. The flow is: the app registers for a push token while in the foreground, hands that token to your server, and when a message lands the server sends a push to APNs or FCM, which wakes the device enough to show the notification or hand the app a few seconds to fetch the message.
This is a hard constraint, not a detail. You do not control delivery timing once the OS has the app suspended: push is best-effort, and aggressive battery optimization on some Android devices delays or drops it. For E2E apps there is an extra wrinkle: the push payload cannot contain the plaintext (the server does not have it), so the notification carries a signal to wake the app, which then decrypts the message locally before showing it. Getting "you have a message" to display without the server knowing what the message says is a small piece of real engineering.
Presence lives under the same battery budget. "Online now" and "last seen" come from the open socket while the app is foregrounded; the moment it backgrounds, that signal goes stale, and pretending otherwise drains the battery for a green dot. Presence is therefore approximate by design: heartbeat while connected, decay when the socket drops, and accept that "last seen 2 minutes ago" is the honest resolution. None of this is exotic, but it is exactly the platform-specific behavior that separates a chat app that feels native from one that feels like a website in a wrapper, which is why the mobile client is real product work. Our React Native app development team builds these push, background, and presence paths against the real APNs and FCM constraints rather than the simulator's friendlier version of them.
What it costs and how long
A focused chat MVP (1:1 and small-group messaging with presence, typing, read receipts, push, and offline sync) is the cluster's standard 8 to 16 week build on one platform; the social practice page carries the reasoning behind that range, so this article will not re-derive it. The spread inside it is set by the same drivers that move the number on any realtime product.
Four things drive cost. Build versus rent on the transport: a managed messaging backend (Stream, Sendbird, or the like) sells the realtime layer, delivery guarantees, and a chat SDK metered per monthly active user, which collapses the hardest engineering into an integration, the right call for most MVPs, with the crossover to building your own arriving only at large sustained volume. End-to-end encryption adds the key-management and multi-device surface from earlier and pushes toward the back of the range. Group and channel scale turns fan-out from a few lines into a subsystem once audiences get large. Platform count multiplies the client work: iOS, Android, and web are three sets of push, background, and reconnection behavior, not one.
For the actual ranges, tier by tier, see what a social media app costs: messaging sits inside that same cost model, and the article spells out the assumptions rather than handing you a single number that needs them. And if you want the encryption, transport, and scale decisions pressure-tested before any code gets written, book a scoping call; thirty minutes there routinely saves a sprint.
Frequently asked questions
A focused chat MVP (1:1 and small-group messaging, presence, typing, read receipts, push, and offline sync) is an 8 to 16 week build on one platform. What stretches it is the same handful of things every time: end-to-end encryption adds a key-management and multi-device surface that touches every read and write path, large group or channel scale turns fan-out into its own subsystem, and supporting a user across phone, tablet, and web means provisioning and syncing keys to several devices instead of one.
It depends on who you are protecting messages from. If the promise is that nobody, including you, can read private conversations, as in a consumer messenger, then yes, and you build around the cost: no server-side search, key management, and a real multi-device story. If the app is team collaboration, customer support, or anything where the business needs server-side search, compliance retention, or admin visibility, end-to-end encryption works against the product, and transport encryption plus encryption at rest is the honest choice. Most B2B chat does not need E2E; most private consumer messaging does.
Four things move the number: whether you build the realtime transport and delivery guarantees yourself or rent a messaging backend, whether messages are end-to-end encrypted (which adds key management and multi-device complexity), how far group and channel scale has to go, and how many platforms ship at launch. A 1:1 and small-group MVP on rented infrastructure sits at the lower end of the agency market; an encrypted, multi-device, large-group platform costs several times more. Our social media app development cost guide breaks the ranges down by scope tier.
More from the journal

How to Build a Live Streaming App: Architecture and Cost
Latency decides everything in streaming app development: pick sub-second WebRTC and the architecture looks one way, accept five seconds of LL-HLS and it looks another. A walk through the ingest-transcode-deliver pipeline, chat and gifting, live moderation, and the cost drivers.

How to Build a Dating App: Matching, Safety, Monetization
Dating apps are matching engines with a social UI on top. This guide covers how matching algorithms and queue fairness work, the verification and safety tooling app stores now require, the monetization math of subscriptions and boosts, and what a build realistically costs.

Creator Monetization Platforms: How They Work, When to Build
Every creator platform is a payments company wearing a content UI. This article explains the four monetization rails, what actually happens inside the payout stack (KYC, splits, holds, tax forms), and when building a custom platform beats renting a white-label one.