Skip to content
OpenE2EE
Engineering journal

E2EE changes your application architecture

The crypto is the small part. Search, notifications, moderation, and recovery all move to the device. Every feature that read message bodies changes.

Who this is for: an engineer or technical founder who might add end-to-end encryption to an existing product. You need to know the cost before you commit. The protocol documentation lives elsewhere. This article covers the layer above it.

Timothy Buck described this cost after working on end-to-end encryption for Meta’s Messenger:

People have come to expect a large number of features in Messenger, across messaging and calling, well over 100. And each of those had to be redesigned and rebuilt. Obviously, originally they were very server-centric. A lot of the logic was on the server and that doesn’t work anymore.

Security Cryptography Whatever, December 2023 (opens in a new tab)

The rest of this article is the inventory: what stops working, what replaces it, and what the shift cost teams who shipped it.

Where the authoritative copy lives

Ink & Switch’s local-first essay states the shift: “The key difference between traditional systems and local-first systems is not an absence of servers, but a change in their responsibilities.” (Ink & Switch (opens in a new tab))

In a conventional application, the server holds the authoritative copy and the client holds a cache. End-to-end encryption inverts this relationship. The device holds the authoritative, readable copy. The relay holds an encrypted replica that it cannot interpret and routes envelopes between devices. Your infrastructure remains. The work moves across the boundary.

Where search, notifications and moderation run before and after end-to-end encryption Two rows on the same two columns. In the top row the device on the left holds readable content and nothing else, an arrow marked plaintext runs from it to the server on the right, and the three work blocks labeled search, notifications and moderation sit inside that server. In the bottom row the same three work blocks sit inside the device, a dotted rule marked seal stands in the canvas between the columns, and the right-hand column is now a relay container holding two sealed slabs with metadata ticks along their top edges. Every box in both rows is the same size and stands in the same place.Server-authoritative device · a cacheplaintextsearchnotificationsmoderationyour server · reads rows, does the workDevice-authoritativesearchnotificationsmoderationdevice · source of truth, does the worksealenvelope metadatarelay · routes envelopes

Search, notifications, and moderation run on the server while it holds plaintext. Under end-to-end encryption the same three run on the device, and the middle only routes envelopes.

What stops working, in the order you will hit it

Week one: WHERE content LIKE '%...%' stops existing. Search breaks first, and users notice it fastest. Link previews, thumbnail generation, profanity filters, auto-tagging, and anything else that reads the body of a record break with it. They have no input any more.

Week two: push notifications go quiet. Your push provider cannot render “Sarah: are we still on for 3pm?” because it cannot read the message. Instead, send a contentless push that wakes the app. The app decrypts the message locally and rewrites the notification. On iOS, the app does this work inside a UNNotificationServiceExtension.

This extension is a separate process with its own keychain access. It has seconds of execution budget and cannot access your JavaScript runtime. Apple and Google document the parts. Few sources explain how to assemble them for a React Native app.

Month one: the admin dashboard becomes a row count. Support cannot “log in as user” because the architecture prevents it. Every internal tool that read customer content needs a different design. Usually, the user must export or share their own data.

Month three: moderation. Enterprise buyers most often object to moderation. An encrypted channel requires a new moderation design. One approach combines user reporting with cryptographic message franking. Message franking lets a reporting user prove that a specific sender sent a specific message. This proof prevents forged reports.

Another approach uses metadata-based abuse signals such as rate and fan-out. Academic work on the problem (opens in a new tab) supports both approaches. You lose proactive content scanning. You keep reactive enforcement with better evidence than a screenshot.

Month six: a keypair is not a user. Your users table becomes a directory of public keys. A person is a changing set of devices, not one account row. Every protocol decision must name the applicable device.

What Zoom, Discord, and Meta published

Zoom publishes its feature-loss list. Zoom’s meeting documentation (opens in a new tab) lists unavailable features when a host enables E2EE: “Zoom AI features, Cloud recording, Meeting chat before and after the meeting, Live streaming, Live transcription, Polling and Surveys, Zoom Apps, Zoom Notes, Zoom Whiteboard.” This list covers much of Zoom’s product differentiation. Each feature needs a server that can see the meeting.

Discord published the lab-versus-field gap. Discord described its DAVE rollout for voice and video: “The initial proof-of-concept worked well and DAVE’s encryption functioned as expected in controlled tests. However, when we tried using DAVE in real Discord calls, it stopped working.” (Discord (opens in a new tab)) A working prototype does not show that production is close.

Meta announced plans for default end-to-end encryption in Messenger in 2019. It made E2EE the default about four and a half years later (opens in a new tab).

Meta was still revising the backup protocol in May 2026 (opens in a new tab). Labyrinth 1.1 lets messages reach encrypted backup as users send them. Previously, backup waited for a device to return online. Meta continued to improve lost-phone reliability two and a half years after launch.

Your product is smaller than Messenger. These timelines show where the work sits: in the application layer, not the protocol.

The patterns that replace what you lose

Teams use established patterns for these problems.

Search moves to the device and needs a local store. Only the device can read messages, so it needs an index. The OpenE2EE Signal Protocol SDK makes storage required and relay optional. Proton downloads and decrypts the mailbox, then indexes it locally. Proton says this “may take a few minutes and can be quite resource-intensive” (Proton (opens in a new tab)). Include that experience in the product plan.

Which queries run on the relay and which run on the deviceOn the left, an outlined relay container holding three sealed slabs, each with metadata ticks along its top edge: recipient, device, group and time can still be queried there. A dotted rule marked open stands in the canvas between them. On the right, an outlined device holding readable content and a filled private key, where content search happens. No arrow joins the two: it is one message, asked two questions in two places. by recipient, device, group, timerelay · routing fields onlyopen by anything in the messagedevice · your search index

Routing fields sit outside the seal, so the relay can still answer a query by recipient, device, group, or time. Content search sits inside the device outline.

Notification content moves to the extension. Send a wake-up, decrypt locally, rewrite the notification body. Design a fallback for decryption failure and for the extension budget expiring.

Analytics moves to counts and shapes. Envelope volume, delivery latency, error rates, and session establishment failures remain visible and useful. Content-derived metrics are gone.

Sync becomes convergence rather than commitment. Devices go offline, and messages arrive out of order. The relay cannot compact unreadable records, so the operation log grows. One developer summarized work on an encrypted local-first app: “Synchronization has been my nightmare for the past couple of months. I have rewritten it a couple of times and still not fully satisfied.” (Roman Zaynetdinov (opens in a new tab))

Encrypted state creates distinct failure modes. Each decrypt advances the ratchet, so the app must persist session state atomically. A partial write can corrupt that state beyond recovery. A common production symptom is a “Bad MAC” error.

One gateway logged a burst of 479 such exceptions (opens in a new tab) while its status still showed connected and listening. Matrix’s meta-issue catalogs over 70 causes (opens in a new tab) of undecryptable messages. It says diagnosis generally requires logs from both the sender and receiver. Test encrypted failure paths before release.

Observability must stay outside the plaintext. Element shipped a bug that wrote “the private part of the backup key pair” to application debug logs. The issue affected 156 users’ key material (Element (opens in a new tab)). Log envelope ids, session states, and error codes. Never log key material. Add a test that rejects it.

Recovery: decide it before launch

Users lose devices on a months-long clock, so this problem surfaces after launch, not during development. By then your architecture has already decided the answer.

There is no universally correct answer. 1Password’s security design paper puts it directly: “Recovery mechanisms are inherently weak points in maintaining the secrecy of data.” (1Password (opens in a new tab))

Pick a named profile deliberately:

  • A server-confidential business archive prioritizes continuity. History survives device loss, and multiple devices see everything. The recovery path is a target for coercion or account compromise. This profile can fit a team collaboration product.
  • A higher-risk messaging profile limits recoverable data. Lose the device and lose the history. A new device starts empty. This profile can fit a threat model that includes device seizure.
  • A collaboration profile sits between them, balancing offline work, membership changes, and recovery, and usually accepts more complexity than either.
Moving to a new device without any server-held keyAbove, an outlined relay container holding two sealed slabs, each with metadata ticks along its top edge, and no key. Below it, two outlined devices side by side: the old one holds readable content and a filled private key, and the new one is empty. One arrow runs from the old device up into the relay, carrying sealed envelopes. One arrow runs across the gutter from the old device to the new one. No arrow runs from the relay to the new device, because there is no path from it. relay · sealed envelopes, no keys old device · holds the keynew device · starts emptydevice to device

Under the higher-risk profile the old device holds the private key and the relay holds no key. A new device can only be restored from the old device. Nothing reaches it from the relay.

The SDK provides device-to-device transfer, encrypted backup primitives, and QR-based provisioning for linked devices. Signal Protocol in React Native and Expo in 2026 records the limits on state transfer.

The SDK does not choose the recovery policy. That product policy determines what users lose. Recovery, backup, and migration (opens in a new tab) compares the profiles.

What metadata the relay still sees

The most common overclaim in this category is that end-to-end encryption makes an application private. It makes the contents unreadable to the operator. The envelope stays readable.

Your relay still knows who sent to whom, when, how often, from which device, and roughly how large. It is not blind.

The relay never needs message plaintext or device private keys.

Sealed sender reduces this metadata. It does not eliminate it. Research on Signal Messenger found that “the promise of sealed sender does not compose over a conversation of messages.” With delivery receipts enabled by default, “Signal could link sealed sender users in as few as 5 messages” (NDSS 2021 (opens in a new tab)). Follow-up work (opens in a new tab) extended the technique to entire group conversations. The SDK exports a sealed-sender module, and we recommend its use. Limits and metadata (opens in a new tab) states these limits beside the feature.

TLS is not end-to-end encryption covers endpoint compromise and first-contact trust.

Is it worth it?

Sometimes not, and that is a real answer. Slack (opens in a new tab) sells customer-managed encryption keys in AWS KMS, not end-to-end encryption. Meta ended support (opens in a new tab) for end-to-end encrypted Instagram DMs in May 2026, saying very few people opted in. Regulated finance needs an archival story first, because SEC Rule 17a-4(b)(4) (opens in a new tab) makes a broker-dealer preserve its communications for three years.

When E2EE is worth the cost, one of three reasons usually drives the decision:

  • A customer segment requires it before buying.
  • A sovereignty requirement favors client-side encryption.
  • Reduced server-side breach exposure supports the product’s risk model.

An attacker who reaches the relay database gets ciphertext instead of message content. Applicable law and incident facts determine notification and disclosure duties. TLS is not end-to-end encryption examines that architecture.

Plan your app’s E2EE architecture → (opens in a new tab)

Start with local-first and offline state (opens in a new tab) to understand where data lives. Limits and metadata (opens in a new tab) explains what remains visible. The threat model (opens in a new tab) separates SDK guarantees from application responsibilities.