perf(web): 4 MiB file streaming + 4 hypercorn workers (fix 40s downloads) #179

Merged
bvandeusen merged 1 commits from dev into main 2026-07-01 11:55:35 -04:00
Owner

Pins down and fixes the slow image/media serving (operator: 30–58s downloads on a gigabit LAN).

Root cause: curator serves /images through the Quart app off a CIFS/SMB share (rsize=4 MiB, actimeo=1). Quart's FileBody streams in 8 KiB chunks → ~19k network round-trips per large original → 30–58s. Compounded by only 2 hypercorn workers (agent + browser thumbnail grid queue behind each other) and no reverse-proxy sendfile.

Fix (in-process, no new container — operator is already "wide"):

  • Raise FileBody.buffer_size 8 KiB → 4 MiB in create_app, matching the mount's read size: one round-trip per read, ~500× fewer. It's the MAX read, so thumbnails still read in one gulp; Range/mime/ETag/conditional handling lives on Response, so all preserved. Guarded so a Quart-internal change can't break boot.
  • HYPERCORN_WORKERS default 2 → 4 so concurrent /images requests stop queuing (env-tunable; the chunk fix is the real lever since transfers now free a worker ~20× faster).

Expected: large-file transfers drop from ~40s toward link speed (a few seconds) for the agent and the browser. Requires a curator redeploy. See issue #1223. CI green on dev (run 1827).

🤖 Generated with Claude Code

Pins down and fixes the slow image/media serving (operator: 30–58s downloads on a gigabit LAN). **Root cause:** curator serves `/images` through the Quart app off a CIFS/SMB share (rsize=4 MiB, actimeo=1). Quart's `FileBody` streams in **8 KiB** chunks → ~19k network round-trips per large original → 30–58s. Compounded by only 2 hypercorn workers (agent + browser thumbnail grid queue behind each other) and no reverse-proxy sendfile. **Fix (in-process, no new container — operator is already "wide"):** - Raise `FileBody.buffer_size` 8 KiB → **4 MiB** in `create_app`, matching the mount's read size: one round-trip per read, ~500× fewer. It's the MAX read, so thumbnails still read in one gulp; Range/mime/ETag/conditional handling lives on `Response`, so all preserved. Guarded so a Quart-internal change can't break boot. - `HYPERCORN_WORKERS` default 2 → **4** so concurrent `/images` requests stop queuing (env-tunable; the chunk fix is the real lever since transfers now free a worker ~20× faster). **Expected:** large-file transfers drop from ~40s toward link speed (a few seconds) for the agent *and* the browser. Requires a curator redeploy. See issue #1223. CI green on dev (run 1827). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bvandeusen added 1 commit 2026-07-01 11:55:30 -04:00
perf(web): stream files in 4 MiB chunks + 4 hypercorn workers (fix 40s downloads)
CI / lint (push) Successful in 4s
CI / frontend-build (push) Successful in 21s
CI / backend-lint-and-test (push) Successful in 28s
CI / integration (push) Successful in 3m27s
0fe1674753
The image library is on a CIFS/SMB share (mounted rsize=4 MiB, actimeo=1), and
Quart's FileBody streams in 8 KiB chunks — so serving one large original was
~19k network round-trips to the storage server, i.e. 30–58s per download
(operator-flagged). That's what starved the GPU agent (constant "curator
unreachable" backoff) AND slowed the browser: every byte is read off CIFS and
streamed through the Python app (no reverse-proxy sendfile), and only 2 hypercorn
workers meant the agent + the browser's thumbnail grid queued behind each other.

In-container fix, no new service:
- Raise FileBody.buffer_size 8 KiB → 4 MiB in create_app, matching the mount's
  read size: one round-trip per read, ~500× fewer. buffer_size is the MAX read so
  small thumbnails still read in one gulp, and Range/mime/ETag/conditional
  handling lives on Response — all preserved. Guarded so a Quart-internal change
  can't break boot.
- HYPERCORN_WORKERS default 2 → 4 so concurrent /images requests stop queuing.

Expected: large-file transfers drop from ~40s toward link speed (a few seconds)
for the agent and the browser. See issue #1223.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa
bvandeusen merged commit 2f9aa3d86c into main 2026-07-01 11:55:35 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/FabledCurator#179