Skip to content

Revert "Limit outgoing to_device EDU size to 65536"#19614

Merged
erikjohnston merged 1 commit into
developfrom
revert-18416-edu-limit-size
Mar 27, 2026
Merged

Revert "Limit outgoing to_device EDU size to 65536"#19614
erikjohnston merged 1 commit into
developfrom
revert-18416-edu-limit-size

Conversation

@erikjohnston

@erikjohnston erikjohnston commented Mar 27, 2026

Copy link
Copy Markdown
Member

Reverts #18416

Unfortunately, this causes failures on /sendToDevice endpoint in normal circumstances. If a single user has, say, a hundred devices then we easily go over the limit. This blocks message sending entirely in encrypted rooms.

cc @MadLittleMods @MatMaul

@erikjohnston erikjohnston marked this pull request as ready for review March 27, 2026 10:31
@erikjohnston erikjohnston requested a review from a team as a code owner March 27, 2026 10:31
@MatMaul

MatMaul commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

Humm sorry for that, annoying.

We could also split the map of devices for a single user.

@MatMaul

MatMaul commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

I'll probably not be able to do so before the next RC however so let's revert indeed.

@erikjohnston

Copy link
Copy Markdown
Member Author

Humm sorry for that, annoying.

It happens!

We could also split the map of devices for a single user.

I think there are a few things we can do:

  1. Split the map of devices up
  2. For EDUs that can't be split up, send in their own transaction (so long as its lower than the max request size)
  3. Add a proper hard-error when a client tries and sends a to-device message that is too big to fit into a transaction. I very much doubt any existing to-device message being sent is anywhere near the limit

@erikjohnston erikjohnston merged commit 0549307 into develop Mar 27, 2026
33 of 36 checks passed
@erikjohnston erikjohnston deleted the revert-18416-edu-limit-size branch March 27, 2026 10:53
erikjohnston added a commit that referenced this pull request Jun 2, 2026
This is based on #18416, which
got reverted (#19614) due to it incorrectly rejecting to-device messages
to users with many devices (and thus breaking message sending).

Fix #17035

A to-device message content looks like:

```jsonc
{
  "@user:domain": {"device1": {...}, "device2": {...}},
  ...
}
```

The previous PR would split up into multiple EDUs, each with a subset of
the users. However, if one user's entry was too large it would not
further split it up and then error out.

The main change in this PR is to allow splitting up a single user into
multiple EDUs.

Other changes:
1. Rename to `SOFT_MAX_EDU_SIZE` to indicate that we sometimes send EDUs
with larger size than that, and its more a target than a hard limit.
2. Check early if any to-device message (to a specific device) is too
large to send, even if we're not going to send it over federation. This
ensures that we catch issues where clients try to send too large
to-device.

This still means that if a client send a large individual to-device
message it will fail, but I don't believe we ever send such large
to-device messages (normally they're in the range of a few KB).

---

I ended up changing the implementation a bunch to make it easy to reuse
the code to split up dictionaries. Instead of repeatedly splitting up
the EDU until each bit fits into the size, we instead record the size of
each entry in the dict and instead split up based on cumulative size.
This means we call `encode_canonical_json` on each entry rather than
once on the entire struct, but its not significantly slower to do so.

--

cc @MatMaul @MadLittleMods

---------

Co-authored-by: Mathieu Velten <matmaul@gmail.com>
Co-authored-by: mcalinghee <mcalinghee.dev@gmail.com>
Co-authored-by: Eric Eastwood <madlittlemods@gmail.com>
FrenchGithubUser pushed a commit to famedly/synapse-upstreaming that referenced this pull request Jun 12, 2026
Reverts element-hq#18416


Unfortunately, this causes failures on `/sendToDevice` endpoint in
normal circumstances. If a single user has, say, a hundred devices then
we easily go over the limit. This blocks message sending entirely in
encrypted rooms.

cc @MadLittleMods @MatMaul
FrenchGithubUser pushed a commit to famedly/synapse-upstreaming that referenced this pull request Jun 12, 2026
This is based on element-hq#18416, which
got reverted (element-hq#19614) due to it incorrectly rejecting to-device messages
to users with many devices (and thus breaking message sending).

Fix element-hq#17035

A to-device message content looks like:

```jsonc
{
  "@user:domain": {"device1": {...}, "device2": {...}},
  ...
}
```

The previous PR would split up into multiple EDUs, each with a subset of
the users. However, if one user's entry was too large it would not
further split it up and then error out.

The main change in this PR is to allow splitting up a single user into
multiple EDUs.

Other changes:
1. Rename to `SOFT_MAX_EDU_SIZE` to indicate that we sometimes send EDUs
with larger size than that, and its more a target than a hard limit.
2. Check early if any to-device message (to a specific device) is too
large to send, even if we're not going to send it over federation. This
ensures that we catch issues where clients try to send too large
to-device.

This still means that if a client send a large individual to-device
message it will fail, but I don't believe we ever send such large
to-device messages (normally they're in the range of a few KB).

---

I ended up changing the implementation a bunch to make it easy to reuse
the code to split up dictionaries. Instead of repeatedly splitting up
the EDU until each bit fits into the size, we instead record the size of
each entry in the dict and instead split up based on cumulative size.
This means we call `encode_canonical_json` on each entry rather than
once on the entire struct, but its not significantly slower to do so.

--

cc @MatMaul @MadLittleMods

---------

Co-authored-by: Mathieu Velten <matmaul@gmail.com>
Co-authored-by: mcalinghee <mcalinghee.dev@gmail.com>
Co-authored-by: Eric Eastwood <madlittlemods@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants