Go 1.18 Generics: Real Use Cases Worth the Complexity

Go 1.18 was still months away when the design was finalised, but the proposal was public and we were already prototyping. After building several services at the European fintech firm with the experimental toolchain, the pattern of when generics help versus when they don’t was becoming clear. The answer is not “always use generics” or “avoid them.” It’s more specific than that. ...

April 7, 2021 · 5 min · MW

gRPC in Production: Lessons After Two Years

We moved our internal service communication from REST+JSON to gRPC when the data pipeline scaled past a point where JSON parsing overhead was measurable in profiles. Two years later, the performance win was real and smaller than expected; the developer experience wins were larger; and the operational complexity was a genuine tax that we underpriced initially. ...

January 13, 2021 · 4 min · MW

Generics Are Coming to Go: What the Proposal Actually Solves

Go had resisted generics for years. The arguments against were practical: generics complicate the language, they interact badly with Go’s interface system, and most cases where you want generics can be handled with interface composition or code generation. The arguments weren’t wrong. But the proposal that eventually shipped in Go 1.18 (2022) addressed a real gap — a gap that was producing either duplicated code or interface{} with runtime type assertions everywhere. Here’s what the proposal was solving. ...

October 5, 2020 · 5 min · MW

Go's Scheduler: GOMAXPROCS, Work Stealing, and Why It Matters

Go’s goroutine scheduler sits between your code and the OS. Understanding it is useful not because you’ll tune it (you rarely should) but because its behaviour explains a class of performance surprises and concurrency patterns that look odd until you see why they exist. ...

August 12, 2020 · 5 min · MW

Building a High-Throughput Event Pipeline in Go Without Losing Your Mind

The fintech startup processed market events at sustained rates of 50,000–200,000 per second through a normalisation and enrichment pipeline. Go channels and goroutines are the natural tool. The naive implementation falls apart at scale. Here’s what works. ...

July 1, 2020 · 6 min · MW

Profiling Go Services in Production with pprof

Every Go service should have profiling endpoints enabled by default. The overhead of having net/http/pprof imported and listening is negligible — a few goroutines, no continuous sampling. The payoff when you need it is enormous. This post is about the workflow I use for diagnosing real performance problems in production Go services. ...

April 1, 2020 · 5 min · MW

Go Benchmarks: Writing Ones That Actually Tell You Something

Go has first-class benchmarking built into the testing package. go test -bench=. is enough to get started. The hard part isn’t running benchmarks — it’s writing ones that measure what you intend to measure. These are the patterns I’ve found essential and the mistakes I’ve made repeatedly enough to write down. ...

March 17, 2020 · 6 min · MW

Context Propagation in Go: Deadlines, Cancellation, and Tracing

context.Context appears in the signature of almost every non-trivial Go function. It’s the idiomatic way to carry deadlines, cancellation signals, and request-scoped values across API boundaries and goroutines. After years of reading Go codebases, the misuse patterns are as common as the correct uses. ...

February 19, 2020 · 5 min · MW

Go Module System: Dependency Management Done Right (Mostly)

Go modules are one of the more carefully designed dependency management systems I’ve worked with. The core ideas — versioned module paths, minimum version selection, reproducible builds via go.sum — are sound. After running services on modules since 1.11, the rough edges are predictable enough to document. ...

January 8, 2020 · 5 min · MW

Error Handling in Go: Patterns That Actually Work at Scale

When I started writing Go after years of Java, the error handling felt tedious. Every function returns an error. Every callsite checks if err != nil. There’s no try/catch, no exception hierarchy, no automatic stack traces. The verbosity was jarring. A year into building services at the fintech startup, I’d changed my view. The verbosity is real and the boilerplate is real, but the explicitness surfaces things that exception-based languages hide. The question is how to handle errors well rather than just correctly. ...

September 11, 2019 · 7 min · MW
Available for consulting Distributed systems · Low-latency architecture · Go · LLM integration & RAG · Technical leadership
hello@turboawesome.win