Back to Blog

Why Go Became My Default Language for SRE and Platform Tooling

Published: Mar 1, 2025 by Joe Hernandez
GolangSREPlatform EngineeringTerraformDevOps

Having a computer science degree and starting my career writing Java, I used to reach for either Java for backend services or Python for quick infrastructure scripts. Both get the job done, but each comes with friction in an SRE workflow. Java carries a heavy runtime footprint for small CLI tools, and Python scripts inevitably turn into a headache of virtual environments, pip dependencies, and version mismatches on CI runners.

When I started picking up Go, it clicked almost immediately. It sits in the exact sweet spot between a compiled systems language and a fast scripting language.

Why Go Fits Infrastructure Work So Well

Most of the cloud-native ecosystem is already written in Go. Kubernetes, Terraform, Prometheus, and the OpenTelemetry Collector all use it. Knowing the language changes how you debug production issues. When a Terraform provider or an operator behaves weirdly, you do not have to guess what it is doing or wait on a GitHub issue. You can read the source code, trace the API call, and see the exact struct validation that failed.

That is actually how I ended up contributing to HashiCorp's terraform-provider-azurerm. Because I was already comfortable reading and writing Go, adding new Azure resource schemas and fixing import bugs felt like normal day-to-day engineering instead of a massive hurdle.

Static Binaries Beat Dependency Management

If you have ever had a production deployment pipeline fail because a build agent updated Python or broke a pip install step, you know how frustrating script maintenance can be.

With Go, I can compile a CLI tool or a self-healing webhook worker into a single static binary. There is no runtime to install on the runner and no dependency tree to break six months later. You copy the binary into a minimal container image or drop it into a pipeline step, and it runs the exact same way every time.

Interfaces and Concurrency Without the Clutter

Coming from Java, the lack of classes and inheritance felt strange for about a week. After that, I started to prefer Go's approach. Using small interfaces and struct composition keeps code flat and easy to read. When I open a Go file I wrote a year ago, I do not have to jump through five layers of abstract base classes to figure out what an HTTP client is doing.

Concurrency is another huge win for platform work. When you need to query health endpoints across 100 services or check quota utilization across dozens of Azure subscriptions, running those checks sequentially in a script takes forever. Spinning up a bounded pool of goroutines with errgroup or channels lets you fan out those API calls safely in seconds.

When I Still Use Python vs. Go

I still use Python for quick data analysis, one-off capacity reports, or glue scripts that nobody else needs to distribute. But as soon as a tool needs to run in CI/CD, handle webhook alerts in production, or be shared across multiple engineering teams, I build it in Go.

The compiler catches mistakes early, the standard library has almost everything you need for HTTP and JSON work out of the box, and the resulting tool is fast and easy to support over the long haul.

Share this post