The first version of the spectr-ai web frontend had a spinner. You uploaded a contract, the spinner spun, and several minutes later results appeared, or didn't. My test users (friends, so they were honest) all did the same thing: around the ninety-second mark they refreshed the page, killing the audit that was about to finish. A spinner with no progress is indistinguishable from a hang, and users act accordingly.
So I rebuilt the pipeline around Server-Sent Events, and most of what I learned wasn't in the SSE tutorials, because tutorials stream a chat completion for ten seconds and call it a day. Multi-minute jobs with real state are a different problem. Here's what actually mattered.
Why SSE and not WebSockets
Short version: the browser never needs to talk back mid-job. The client uploads a contract, then listens. That's exactly the shape SSE was built for, one-directional server-to-client over plain HTTP. No connection upgrade, no socket lifecycle management, and the bro
Discussion
Break the silence
Take the opportunity to kick things off.