Skip to content

perf(markers): batch SSE flushes + serve /js/ from embed.FS#125

Merged
robouden merged 1 commit into
mainfrom
perf/stream-markers-flushing
May 1, 2026
Merged

perf(markers): batch SSE flushes + serve /js/ from embed.FS#125
robouden merged 1 commit into
mainfrom
perf/stream-markers-flushing

Conversation

@robouden

@robouden robouden commented May 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • streamMarkersHandler flushed once per marker (~70k flushes per viewport request). Wrap the response in a 64KB bufio.Writer and flush every 256 markers or 50ms. Also send X-Accel-Buffering: no so nginx stops buffering the SSE stream.
  • /js/ was served via http.Dir("public_html/") — a relative path resolved against runtime cwd. In production the binary lives in /usr/local/bin, no public_html/ next to it, so /js/marker-worker.js 404'd and marker JSON parsing fell back to the main thread. Serve /js/ from the embedded StaticFS instead.

Why

WebPagetest comparison (simplemap.safecast.org vs pelora.org, same viewport): simplemap took ~29s for /stream_markers vs pelora's ~7.5s for a similar payload, plus a reproducible 404 /js/marker-worker.js. Both come from this code path.

Test plan

  • go build -tags duckdb -o safecast-new-map ./cmd/unified-server/
  • go vet -tags duckdb ./cmd/unified-server/ ./pkg/httpapi/
  • go test -tags duckdb ./pkg/httpapi/ -run TestRegisterStaticRoutes
  • Re-run WebPagetest after deploy and confirm stream_markers wall-clock drops and /js/marker-worker.js returns 200

🤖 Generated with Claude Code

streamMarkersHandler called flusher.Flush() once per marker, producing
~70k chunked-write/syscalls per viewport request. Wrap the response in a
64KB bufio.Writer and flush every 256 markers or 50ms instead. Also send
X-Accel-Buffering: no so nginx forwards chunks immediately.

/js/ was being served via http.Dir("public_html/"), a relative path that
resolves against the runtime cwd. In production (binary in /usr/local/bin)
no such dir exists next to it, so /js/marker-worker.js 404'd and JSON
parsing of the 12MB SSE stream fell back to the main thread. Serve /js/
from the same embedded StaticFS used by /static/ instead.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@robouden robouden merged commit 39b7186 into main May 1, 2026
2 checks passed
@robouden robouden deleted the perf/stream-markers-flushing branch May 1, 2026 07:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant