open-webui/backend/open_webui
Classic298 488b3c571c
perf: stop note co-editing echoing every remote update back to the server (#28185)
Every client in a note re-broadcasts each update it receives, with a full content snapshot attached, and the server appends each echo to the document log and writes the note again. Traffic and note writes therefore scale with the number of people who have the note open: every extra participant adds one more full echo of every keystroke.

Remote updates are now applied with the `'server'` origin the state path already uses, which the local listener ignores, so the echo stops. The echo did carry one thing worth keeping: the receiving client holds the merged document, which the sender had not seen yet, so each receiver now sends a content-only message once the edits settle, debounced 500ms, and flushes a pending one when the editor is torn down. The backend accepts an update message with no `update` field for that case, where it previously raised and dropped the save.

Replaying keystrokes at 120ms with a real Yjs document, socket messages fall 48.8% with two clients, 65.6% with three and 79.2% with five, with byte counts tracking the same on notes up to 50KB. Server-side update appends drop by a factor of the client count. The cost is one snapshot upload per receiving client per typing pause, which the server's own debounce then collapses into a single extra note write however many people are watching. A snapshot has to come from a client because the server cannot rebuild the markdown, HTML and JSON shape the note record stores. It also moves the merge 500ms later than the echo delivered it, so if two edits cross on the wire and every editor then loses its connection and closes inside that window, the note keeps what it was last sent and one of the two edits is lost. A client still connected at teardown flushes its pending snapshot, and any other editor left in the note closes the gap.
2026-09-21 08:53:27 -04:00
..
data refac: mv backend files to /open_webui dir 2024-09-04 16:54:48 +02:00
internal refac 2026-09-06 17:13:32 -04:00
migrations chore: format 2026-08-25 16:53:53 -04:00
models fix: keep the live prompt unchanged when a version is saved without Set as Production (#30231) 2026-09-21 08:32:02 -04:00
retrieval fix: stop sending count to the Staan search API (#30303) 2026-09-21 08:04:26 -04:00
routers fix: resolve this instance's own file URLs in edit_image regardless of the URL host (#29691) 2026-09-21 08:32:38 -04:00
socket perf: stop note co-editing echoing every remote update back to the server (#28185) 2026-09-21 08:53:27 -04:00
static refac 2026-09-06 17:27:30 -04:00
storage refac 2026-09-06 17:13:32 -04:00
tools refac 2026-09-21 00:51:28 -04:00
utils refac(images): request an unencoded body when fetching remote chat images (#29623) 2026-09-21 08:53:06 -04:00
__init__.py perf: allow disabling websocket per-message-deflate (#28613) 2026-08-24 18:46:07 -04:00
alembic.ini fix: Alembic CLI commands from failing 2025-08-15 04:17:47 -04:00
config.py fix: pgvector reads leak their connection and lose most of their neighbours (#30142) 2026-09-18 19:31:49 -04:00
constants.py refac 2026-08-29 16:14:32 -04:00
env.py feat: let operators expose chosen file metadata to the model in retrieved sources (#29696) 2026-09-19 17:02:59 -05:00
events.py refac 2026-08-16 23:21:00 -07:00
functions.py fix: honor bypass_system_prompt on the pipe route (#28739) 2026-08-19 11:08:02 -07:00
main.py refac 2026-09-21 08:43:45 -04:00
tasks.py fix: stop tracking tasks under an empty item id (#29980) 2026-09-13 20:28:54 -05:00