June 18, 2026 Go Backend Production

Go 1.26: What We're Using in Production

We upgraded our core ingestion services to Go 1.26 last week. It was not a trivial migration — we had been running a patched 1.23 for the better part of a year — but the improvements in runtime observability and HTTP/3 stability made it worth the effort.

The biggest immediate win is the new runtime/metrics histogram support. We export custom latency distributions to Prometheus without the overhead of client-side aggregation. Previously we used a third-party library that added roughly 3% CPU overhead under load. The native implementation is free. We have already replaced four internal histograms and plan to migrate the rest this quarter.

HTTP/3 support in net/http matured enough that we enabled it on our edge proxies. The improvement is not dramatic for our workload — most clients are internal services with low latency — but for mobile clients on flaky networks the reduction in handshake time is measurable. We see about 8% fewer timeouts on 4G connections, which is significant for our mobile ingestion path.

The compiler now does a better job of inlining small functions across package boundaries. We noticed a 2–4% reduction in binary size and a small improvement in hot-path latency. It is not revolutionary, but it is the kind of improvement that compounds over years. Our largest binary, the event router, dropped from 42MB to 39MB. Every megabyte matters when you deploy hundreds of instances.

"We do not upgrade for features. We upgrade because the runtime gets faster and safer while we sleep."

One breaking change caught us: the crypto/tls package no longer accepts SHA-1 signatures in certificates by default. We had one legacy internal CA that was still issuing SHA-1 intermediates. It took two days to rotate the CA and reissue certificates. The lesson, learned again: internal infrastructure ages faster than you think.

We also took the opportunity to remove our last use of syscall in favor of golang.org/x/sys. The deprecation warnings had been noisy for months. The migration was mechanical — mostly unix.EpollCreate1 and signal handling — and took about four hours.

Overall, the upgrade took one engineer three days, including testing and staging. The production rollout was a rolling restart with no downtime. Our SLOs held. If you are still on 1.23 or 1.24, I would recommend planning the migration. The runtime improvements alone justify the work.

Filed under: Go, Backend, Production