Menu
← All posts

Homerun and Penombre are both getting a Go worker

I don't have benchmarks for this post. I have a feeling, the feeling that comes from clicking deploy on Homerun and watching the progress bar sit there, or dragging a folder into Penombre and watching the upload queue crawl. No profiler, no flamegraph, just enough repeated annoyance to go do something about it. If that's not rigorous enough for you, close the tab now.

The rule

Anything that's pure logic, actual algorithmic work, processing rather than I/O or request handling, moves out of the SvelteKit app and into a Go worker. Both projects, same rule. The web app stays SvelteKit because it's good at being a web app: forms, sessions, routing, rendering. It was never good at being a compute engine, and I'd been asking it to be one anyway.

Homerun: deploys were dragging

Build orchestration, log streaming under load, health-gated rollouts, all the stuff that happens the moment you hit deploy, was living in the same event loop as everything else the dashboard needs to do. It worked. It also meant a busy deploy could make the rest of the app feel sluggish, and the deploy itself felt slower than the work actually justified.

That processing now runs in a Go worker instead. Not a rewrite of Homerun, a relocation of the parts that were never web-app logic to begin with.

Homerun's other problem: the releases were obese

This one had nothing to do with runtime performance and everything to do with me being embarrassed. The CLI, the installer and the agent were all shipping in a way that pushed every release past 800MB. That number is bad in every direction at once: slower CI because there's more to build and upload, more storage sitting in the registry for no reason, a bigger download for anyone installing or updating, and a self-update that takes longer than it has any right to.

Converting the CLI, installer and agent to Go fixes that directly. Static binary, no runtime to drag along, a fraction of the size. It's a boring fix. Boring fixes are the ones that actually ship.

Penombre: same worker, different container story

Uploads on Penombre were hitting the same wall: chunking, processing, anything CPU-bound was sharing space with the request handling that's supposed to stay responsive while a multi-gigabyte file is being pushed through it. Same diagnosis as Homerun, same fix, a Go worker for the processing path.

The one real difference is deployment shape. Homerun already assumes more moving parts. Penombre's whole pitch is one container, and I'm not breaking that promise to make uploads faster. So the worker runs inside the main container by default, in-process, with the option to split it out as a sidecar if you want to scale it separately. Single container stays the default. Sidecar stays available for anyone who actually needs it.

What I'd actually want instead

None of this is the end state I actually want. It's the trade-off available today.

If I could have it my way, both of these would be tiny Bun binaries instead of a second language and toolchain living in the repo. Or further out, something like a SvelteKit-for-Go: the same routing and rendering ergonomics I like in SvelteKit, without paying a JS runtime's overhead for pure compute work. Neither of those exist in a form I can ship today, so Go is what's landing, because it's boring, it compiles to a static binary, and it's fast enough that I stop thinking about it.

No numbers to close this out with. Deploys feel faster. Uploads feel faster. Releases are smaller and that part I can actually prove, since a number on a release page doesn't lie. If you want real benchmarks, wait for the release notes once this ships and I'll put some in there instead of adjectives.