open-webui/backend/open_webui
Classic298 091c44c621
perf: stop rescanning the whole response for tag boundaries on every streamed chunk (#28861)
Streamed responses are scanned for reasoning and code interpreter tags. To work out where the last complete tag ended, the scanner searched backwards from the start of the accumulated text on every chunk, once per tag set. Ordinary prose contains no angle bracket, so that search never stopped early and read the entire response back every time. The cost grows with the square of the response length, and this scanning is on unless a model turns it off.

The two positions are now carried forward as the text grows, so each chunk only scans the characters it added.

Measured on CPython 3.12, a 270 KB response streamed in 27000 chunks:

| response text | before | after |
|---|---|---|
| no newlines | 7690 ms | 40.6 ms |
| with newlines | 5695 ms | 41.7 ms |

The carried positions match a full rescan at every step of 36282 randomized replays, covering text with no markers, newlines only, dense markers, real tags and truncation part way through.
2026-08-24 05:11:32 -05:00
..
data refac: mv backend files to /open_webui dir 2024-09-04 16:54:48 +02:00
internal perf: route native JSON columns through JSONCodec instead of stdlib json (#28396) 2026-08-10 19:39:49 -05:00
migrations fix: index the chat queries that make large SQLite instances unusable (#27663) 2026-08-23 16:11:54 -05:00
models fix: index the chat queries that make large SQLite instances unusable (#27663) 2026-08-23 16:11:54 -05:00
retrieval refac: drop the redundant .keys() from two dict membership tests (#28859) 2026-08-23 16:02:09 -04:00
routers refac: drop the redundant .keys() from two dict membership tests (#28859) 2026-08-23 16:02:09 -04:00
socket fix: keep the usage pool cleanup task alive across lock loss and Redis errors (#28834) 2026-08-20 12:59:38 -07:00
static refac 2026-07-27 19:39:36 -04:00
storage refac 2026-07-31 17:41:14 -04:00
tools refac 2026-08-17 00:24:47 -07:00
utils perf: stop rescanning the whole response for tag boundaries on every streamed chunk (#28861) 2026-08-24 05:11:32 -05:00
__init__.py refac 2026-07-27 19:39:36 -04:00
alembic.ini fix: Alembic CLI commands from failing 2025-08-15 04:17:47 -04:00
config.py refac 2026-08-20 13:13:51 -07:00
constants.py refac: make the web search error message a plain constant (#28948) 2026-08-23 13:27:02 -04:00
env.py refac 2026-08-20 13:13:51 -07: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-08-17 00:47:32 -07:00
tasks.py refac 2026-08-23 13:40:13 -04:00