From bf08835d6f3147f151f825297483dc01c4267aa1 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Tue, 25 Aug 2026 00:46:07 +0200 Subject: [PATCH] perf: allow disabling websocket per-message-deflate (#28613) With delta streaming most websocket frames are tiny per-token deltas, and per-message-deflate pays zlib work on every outgoing frame per subscriber for near-zero gain there; under heavy streaming that shows up as measurable server CPU. The frames that still benefit are the rare large ones (final message, sources), and even a 100k token message is only a few hundred KB uncompressed, which any network delivers without noticeable delay. UVICORN_WS_PER_MESSAGE_DEFLATE=false (default true, current behavior) disables the extension in every entry point: open-webui serve and dev, start.sh both invocations, start_windows.bat and dev.sh. Verified against a running instance: with the flag off the server declines the client-offered permessage-deflate extension, with defaults it still negotiates it. --- backend/dev.sh | 2 +- backend/open_webui/__init__.py | 6 +++++- backend/open_webui/env.py | 3 +++ backend/start.sh | 4 ++-- backend/start_windows.bat | 3 ++- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/backend/dev.sh b/backend/dev.sh index 838b93f653..9737b3d005 100755 --- a/backend/dev.sh +++ b/backend/dev.sh @@ -1,3 +1,3 @@ export CORS_ALLOW_ORIGIN="http://localhost:5173;http://localhost:8080" PORT="${PORT:-8080}" -uvicorn open_webui.main:app --port $PORT --host 0.0.0.0 --forwarded-allow-ips "${FORWARDED_ALLOW_IPS:-*}" --reload +uvicorn open_webui.main:app --port $PORT --host 0.0.0.0 --forwarded-allow-ips "${FORWARDED_ALLOW_IPS:-*}" --ws-per-message-deflate "${UVICORN_WS_PER_MESSAGE_DEFLATE:-true}" --reload diff --git a/backend/open_webui/__init__.py b/backend/open_webui/__init__.py index 82f4e5e7ba..e803cea466 100644 --- a/backend/open_webui/__init__.py +++ b/backend/open_webui/__init__.py @@ -74,7 +74,7 @@ def serve( os.environ['LD_LIBRARY_PATH'] = ':'.join(LD_LIBRARY_PATH) import open_webui.main # noqa: F401 - from open_webui.env import UVICORN_WORKERS # Import the workers setting + from open_webui.env import UVICORN_WORKERS, UVICORN_WS_PER_MESSAGE_DEFLATE # On Windows, uvicorn's default loop factory hardcodes ProactorEventLoop, # which is incompatible with psycopg v3 async. Setting loop='none' lets @@ -87,6 +87,7 @@ def serve( port=port, forwarded_allow_ips='*', workers=UVICORN_WORKERS, + ws_per_message_deflate=UVICORN_WS_PER_MESSAGE_DEFLATE, loop=loop, ) @@ -97,12 +98,15 @@ def dev( port: int = 8080, reload: bool = True, ): + from open_webui.env import UVICORN_WS_PER_MESSAGE_DEFLATE + uvicorn.run( 'open_webui.main:app', host=host, port=port, reload=reload, forwarded_allow_ips='*', + ws_per_message_deflate=UVICORN_WS_PER_MESSAGE_DEFLATE, ) diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py index 2d610a3388..34a2df1203 100644 --- a/backend/open_webui/env.py +++ b/backend/open_webui/env.py @@ -443,6 +443,9 @@ try: except (ValueError, TypeError): UVICORN_WORKERS = 1 +# tiny delta-stream frames make per-frame websocket compression CPU-bound, allow opting out (true/false) +UVICORN_WS_PER_MESSAGE_DEFLATE = os.getenv('UVICORN_WS_PER_MESSAGE_DEFLATE', 'True').lower() == 'true' + #################################### # WEBSOCKET SUPPORT #################################### diff --git a/backend/start.sh b/backend/start.sh index 0846273b89..634f4bcc1b 100755 --- a/backend/start.sh +++ b/backend/start.sh @@ -72,7 +72,7 @@ if [[ -n "${SPACE_ID:-}" ]]; then if [[ -n "${ADMIN_USER_EMAIL:-}" && -n "${ADMIN_USER_PASSWORD:-}" ]]; then echo "Creating admin user for Space..." WEBUI_SECRET_KEY="${WEBUI_SECRET_KEY:-}" \ - uvicorn open_webui.main:app --host "$HOST" --port "$PORT" --forwarded-allow-ips "${FORWARDED_ALLOW_IPS:-*}" & + uvicorn open_webui.main:app --host "$HOST" --port "$PORT" --forwarded-allow-ips "${FORWARDED_ALLOW_IPS:-*}" --ws-per-message-deflate "${UVICORN_WS_PER_MESSAGE_DEFLATE:-true}" & webui_pid=$! echo "Waiting for server to become healthy..." @@ -102,7 +102,7 @@ UVICORN_WORKERS="${UVICORN_WORKERS:-1}" if [[ "$#" -gt 0 ]]; then ARGS=("$@") else - ARGS=(--workers "$UVICORN_WORKERS") + ARGS=(--workers "$UVICORN_WORKERS" --ws-per-message-deflate "${UVICORN_WS_PER_MESSAGE_DEFLATE:-true}") fi exec env WEBUI_SECRET_KEY="${WEBUI_SECRET_KEY:-}" \ diff --git a/backend/start_windows.bat b/backend/start_windows.bat index d5c4510baa..4a57d34694 100644 --- a/backend/start_windows.bat +++ b/backend/start_windows.bat @@ -55,5 +55,6 @@ IF "%WEBUI_SECRET_KEY% %WEBUI_JWT_SECRET_KEY%" == " " ( :: Execute uvicorn SET "WEBUI_SECRET_KEY=%WEBUI_SECRET_KEY%" IF "%UVICORN_WORKERS%"=="" SET UVICORN_WORKERS=1 -uvicorn open_webui.main:app --host "%HOST%" --port "%PORT%" --forwarded-allow-ips %FORWARDED_ALLOW_IPS% --workers %UVICORN_WORKERS% --ws auto +if "%UVICORN_WS_PER_MESSAGE_DEFLATE%" == "" set "UVICORN_WS_PER_MESSAGE_DEFLATE=true" +uvicorn open_webui.main:app --host "%HOST%" --port "%PORT%" --forwarded-allow-ips %FORWARDED_ALLOW_IPS% --workers %UVICORN_WORKERS% --ws auto --ws-per-message-deflate %UVICORN_WS_PER_MESSAGE_DEFLATE% :: For ssl user uvicorn open_webui.main:app --host "%HOST%" --port "%PORT%" --forwarded-allow-ips '*' --ssl-keyfile "key.pem" --ssl-certfile "cert.pem" --ws auto