Why I Use Go (and Why You Might Like It Too)

Go (often incorrectly referred to as Golang) has gained significant popularity over the past few years. According to the StackOverflow 2024 Survey, 68% of developers want to work with it, and 23% already use and love it.
I began writing Go at Robinhood, where it was starting to get adopted. At the time, I thought it was the dumbest language to exist. I tried it out and ignored it, going back to Python for everything. I saw it again at LinkedIn, where Go was used on services that were highly concurrent; I again discarded it and thought it made no sense. Only after running into issues with my own personal projects did I begin to realize the things I hated about Go were made to solve problems I hadn't considered. Fast-forward to today, where Go is my favorite statically typed programming language.
Why is Go Gaining Popularity?
Go’s rise to prominence is driven by its simplicity and practicality. Developed by Google, it was designed with the intent of providing a language that freshly graduated engineers could use to write high-performance code without getting bogged down by the complexities of C or C++. Google wanted something that allows developers to just start writing Go code without much overhead.
My Journey with Go
I’m writing to talk about why I’m using Go, not why big tech companies are. That said, learning Go makes you more attractive to companies that are using or transitioning to Go, which is a lot of them.
The Three Reasons I Use Go
The three main reasons I choose Go are:
- Simplicity
- Concurrency Model
- Developer Experience
Simplicity in Go
Go was built with simplicity at its core. It avoids unnecessary complexity (if you consider OOP unnecessary), letting developers focus on problem-solving rather than wrestling with the language itself.
Minimal Syntax, Homogenous Code
Go has a minimal syntax and a small feature set, resulting in homogenous code. While this may sound boring, it also ensures that every Go programmer similarly approaches problems. For example, everyone sums up a list by iterating over it with a for
loop, and no one is going to write a custom reduce
function or use list comprehensions. By contrast, Python takes a very different approach and provides multiple ways to do the same thing. In Python, you will never be able to get people to agree on which method is "cleanest" or most acceptable, whereas in Go, you don't have that issue (in my experience at least).
// Go Engineer A, B, C and D's Implementation
for _, num := range nums {
sum += num
}
// Python Engineer A
for num in nums:
total += num
// Python Engineer B
while i < len(nums):
total += nums[i]
i += 1
total = sum(nums) // Python Engineer C
total = reduce(lambda x, y: x + y, nums) // Python Engineer D
This minimalism ensures that everyone’s Go code looks similar. The Go team has remained steadfast in their goal of simplicity, even at the cost of verbosity—the community fought hard to get generics introduced in Go 1.18. Given Go didn't have generic, you could click into any Go package and understand the code, with TypeScript and Java you will meet generics hell in package internals.
Explicitness Over Magic
Go doesn’t rely on magic or hidden operations. There are no hidden constructors, and error handling is so explicit that, at first, I found it unnecessary. However, I later realized that this explicitness was an intentional decision by the language designers. Writing more code is acceptable if it makes things more explicit and easier to understand. In general, if you are not explicitly expecting an error in an OOP language, you are not going to make the effort to write code to catch and handle it.
Concurrency Model
Go's simplicity extends to it's concurrency model, making traditionally challenging techniques like multi-threading surprisingly approachable. Go makes concurrency easy and fun with just a few simple concepts like channels
, mutexes
, and WaitGroup
. With these tools, you can quickly write powerful concurrent applications. If your application is heavily I/O-bound, you can achieve massive performance gains as the CPU can switch between threads when one is waiting. Even if it's compute-bound, by launching several threads equal to the CPU cores, you can take full advantage of modern multicore hardware.
Before Go, I rarely wrote multi-threaded code after my computer systems class because working with PThreads was cumbersome and error-prone. However, I made the mistake of confusing the capability (multi-threading) with the implementation (PThreads) and discarded multi-threading as a solution to problems. Go's sync
package offers a minimal yet incredibly powerful set of concurrency primitives that make concurrent programming both accessible and enjoyable. Writing concurrent code in Go feels natural, and this ease has made concurrent programming genuinely fun for me.
Go supports both shared memory (common in OOP languages) and message passing via channels (similar to Beam VM languages), providing an easy way to manage data with global ordering, while also allowing the use of shared data protected by locks. The simplicity of multi-threading in Go is why Go is my go-to language for server-side applications where I need concurrency beyond making an API call in a background thread.
Developer Experience
I'm consistently impressed with the developer experience of Go. From the get-go, testing and building are simple thanks to the go test
and go build
commands. With a single command, I can create a static binary for any platform, making deployment straightforward. Plus, the go race
tool is a lifesaver for concurrent programming, identifying race conditions.
What really sets Go apart, though, is its robust standard library. Whether I'm spinning up an HTTP server, handling files, or tackling other everyday tasks, I rarely need to look beyond the built-in tools. And when I do, the go mod
package management system is easy to work with. Minimizing import and versioning headaches, I cannot begin to describe how much time I have spent dealing with Python dependency issues, nothing makes me lose my minder quicker then that.
One of the things I appreciate most about Go is how it just works, right out of the box. No fuss, no elaborate configuration—the essentials for building a solid Go app are all readily available and incredibly easy to use. I highly recommend considering what the standard library provides before bringing in a framework, especially in the case of HTTP servers as the Go router in go version 1.22
made it very powerful and easier to work with.
Performance Considerations
People often mention Go alongside C/C++ and Rust. While C, C++, and Rust will always outperform Go in terms of raw performance due to their non-GC nature, Go excels in developer velocity. Unless your competitive advantage hinges on ultra-low latency, the ease of development and faster iteration (DevX) that Go offers often outweighs the performance gains of other languages.
Developer Velocity
However, there are areas where Go is outshined. Despite my love for writing Go, I acknowledge that using TypeScript or Python (for anything unrelated to concurrency) can be significantly faster for making progress. When rapid prototyping is the goal, and long-term maintainability is less of a concern, Python allows me to move very quickly (though this doesn't mean good practices can't be applied).
Both Python and TypeScript are scalable, capable of horizontal scaling until a company reaches a point where it handles billions of events a day—justifying a rewrite in Go to save on server costs. For a startup, developer time is usually more valuable than the cost of a server, and Go could potentially slow things down (unless the server has complex concurrency logic).
For instance, Reddit only recently migrated its Python-based 'Thing' service, which pushed Python to its horizontal limits, leading to massive AWS bills. Robinhood moved to Go on their critical path to reduce latency on services in the critical path. Both examples highlight valid but different reasons to transition to Go.
Conclusion
These reasons are why I use Go. However, determining if Go is the right solution for an enterprise service involves more considerations. My opinions are those of a 21-year-old developer who has yet to hold a full-time position, so take them with a grain of salt.