COMPAX

COMPAX AND MATRIX

One difference,
and what follows

Matrix is the mature federated messenger, and most of what is written comparing the two is written by people who have used neither codebase. What follows was read off both.

Measured 27 August 2026. Synapse 246,976 lines of Python — 71,349 in storage alone. Continuwuity, a second implementation of the same network, 95,220 lines of Rust. This server 17,041 lines. Both sides move, and half of what is below is about today rather than about the nature of things; the parts that are the nature of things are marked.

THE DIVERGENCE

Who is the authority
on what a room is

Matrix — the server
  • A room is a DAG of events, each carrying its own authorisation chain.
  • When servers disagree, state resolution v2 settles it.
  • Hence state groups, forward and backward extremities, outliers, backfill — and 71,349 lines in the storage layer alone.
  • A commit is taken locally even when the network splits, and merged afterwards.
Compax — the MLS tree
  • The server is a delivery service. One order, held by the room’s home.
  • Compare the epoch, append under the same lock. There is nothing to diverge.
  • So there is no DAG, no state resolution, no backfill.
  • And a commit needs a round trip home, and gets a 409 on a race.

The trade is honest in both directions, and MLS leaves no choice about it: applying a commit destroys the previous epoch’s secrets. There is nothing to roll back to.

A CLAIM WORTH GETTING RIGHT

“Their server reads your messages”
is wrong in both directions

In an encrypted Matrix room the body of a message is ciphertext and the server does not read it — Megolm, exactly as MLS is here. What is true is narrower and, for most people, worse.

What is actually open
  • Encryption is a switch on the room. Public rooms usually do not have it, and there everything is readable.
  • Room state is never encrypted: name, topic, avatar, membership, invitations, power levels — plaintext even in an encrypted room.
  • That is not an oversight. The server applies the authorisation rules to events, so it must be able to read them.
So the real difference is the graph
  • Who is in a room with whom, who invited whom, and when — always visible to their server.
  • Here that lives in the MLS tree. The server sees a group_id and an epoch.
  • And a consequence easy to miss: server-side search in encrypted rooms does not work for them at all. Element searches locally — so on search this is behind Element, not behind Matrix.

WHERE EACH ONE PUTS ITS EFFORT

Focus

Matrix — reach and operation
  • Surviving a network split, because the DAG merges afterwards.
  • Twelve room versions shipped and migrated on a live network.
  • Scale proven in the field: stream writers, instance maps, Redis replication.
  • Moderation in depth — admin API, room ACLs, media quarantine, an MSC process.
  • Third-party implementations checked as black boxes by Complement.
  • Recovery after losing every device, via server-side key backup.
Compax — what the server cannot do
  • In the open there is a group_id and an epoch, and that is what ordering needs.
  • Identity is not issued by the server: a root key signs a device attestation and everyone checks it locally.
  • Order costs one row — a compare-and-set, measured at 239 appends a second in a room.
  • Push carries nothing. Theirs carries a room_id, so the room reaches the push provider anyway.
  • A call inherits its room: the media key comes from the epoch secret, so removing a member removes them from the media as a side effect.
  • Bots are leaves in the tree, not a server-side detour — there is no place where plaintext sits for a bot.
  • A complaint is provable: a message proof shows authorship. Megolm is a group key and proves nothing.
  • Money the group holds together, which is not part of Matrix at all.

THE CONSEQUENCES

What each protocol
cannot do

Not a scoreboard. Each line is the price of the choice above it, and both columns contain things their side would rather not have.

Matrix

Compax

Message bodies in an encrypted room

Ciphertext. Megolm — the server does not read them.

Ciphertext. MLS — the same.

Whether encryption is on

A per-room switch, m.room.encryption. Public rooms usually are not, and there the server reads everything.

Not a switch. There is no unencrypted room to be in.

Room state — name, topic, membership, invitations, power levels

Plaintext, always, even in an encrypted room. Not an oversight: the server applies the authorisation rules, so it has to read them.

In the MLS tree. The server sees group_id and the epoch.

Who is in a room with whom

Visible to the server, always.

Not visible. This, and not the message text, is the real difference.

Server-side search in an encrypted room

Does not work at all — the encrypted event has no content.body to index. Element searches locally.

Does not work either, and for the same reason. The path out is the same one Element took: an index in the client.

A commit accepted during a network split

Yes. The event is taken locally and merged afterwards by state resolution.

Impossible. Applying a commit destroys the previous epoch’s secrets — two commits in one epoch are two incompatible key states.

History after losing every device

Server-side key backup under a recovery key — end-to-end as well.

Gone. A wrapper the phrase alone could open would be permanent access nobody could revoke; it was refused on purpose.

Room rules enforced by the server

Yes — power levels, and the server rejects an event that breaks them.

No. The policy runs in shadow: it counts disagreements and rejects nothing, because a rejected valid commit does not spoil an MLS group, it ends it.

Link previews, moderation by content, push carrying text

Possible wherever a room is not encrypted.

Impossible. This is not “not yet” — it is what everything else was bought with.

Money held by the group

Not part of the protocol.

Five chains, every signer’s key on their own device, the payment arriving as a message.

AND WHERE THEY MEET

The same, on both sides

Postgres for what must last and Redis for what must be fast. Token buckets per action. History on a second device — their key backup, sealed windows and a QR transfer here. Retry backoff on a dead peer. Batching many records into one request. Version announcement over HTTP. Blocking a provider. Deduplication on receipt. Attachments outside the event log. Prometheus and alert rules. And no server-side search in an encrypted room, on either side.

NEXT

The questions
that come first

Sixteen of them, answered plainly — including the two where the answer is not the comfortable one.