Why We Still Reach for Go for Security Tooling
Go is not the trendy choice anymore, but for the class of software that has to run everywhere with a small footprint and never surprise you, it is still the right one.
Go does not get much attention anymore. The interesting conversations in engineering circles are about Rust for systems work or TypeScript everywhere else, and Go quietly sits in the middle looking unfashionable. For a specific category of software we build, it remains the correct choice, and the fact that it is unfashionable is mostly irrelevant to why.
The category is security and compliance tooling
When we built the continuous compliance monitoring and anomaly detection layer for NimbusGuard, the requirements were unglamorous but specific: the agent needed to run on every host in a fleet without a noticeable memory footprint, it needed to compile down to a single static binary with no runtime dependencies to manage across mismatched host environments, and it needed concurrency primitives good enough to watch dozens of event streams simultaneously without the code turning into a callback maze.
Go was built for almost exactly this problem. Goroutines make the concurrent event-watching code readable instead of a tangle of async callbacks. The compiled binary has no dependency tree to audit or version-mismatch in production, which matters enormously for something that has to be deployed onto infrastructure we do not fully control. And the memory footprint stays small and predictable, which matters when the tool's entire value proposition is that it should not be the thing that causes a performance problem on the systems it is protecting.
What we would not use it for
We do not reach for Go for product feature work, and we would push back on a client who wanted us to. The standard library is deliberately minimal, the ecosystem for typical web application concerns is thinner than TypeScript's, and the generics support, while real now, arrived late enough that a lot of idiomatic Go code still avoids leaning on it the way a comparable Rust or TypeScript codebase would use its type system. For a product team iterating quickly on user-facing features, that tradeoff is not worth it.
The actual decision rule
- Does the software need to run continuously with a small, predictable resource footprint?
- Does it need to compile to a single dependency-free binary for deployment onto infrastructure you do not fully control?
- Is the core problem concurrent I/O — watching many things at once — rather than complex business logic?
If those three are true, Go is still, in our experience, the least risky choice available, unfashionable or not. Security tooling is exactly that category: it runs everywhere, it needs to be boring and predictable, and the last thing you want is your security agent itself becoming the thing that needs debugging.