I met Go on a real problem
I started using Go at the beginning of 2026 when I picked up the DSPM project. Before that, most of my comfort zone was TypeScript on the UI side and Python for a lot of backend and data work. That mix still feels natural to me, but on DSPM I wanted something that felt calmer on the backend side.
The work itself pushed me there. We had jobs that needed to scan data, run multiple tasks at once, move results through a pipeline, and still stay understandable when I came back to the code later. I did not want clever code. I wanted software that stayed readable even after the first burst of excitement was gone.
I did not pick Go because I thought I had mastered it. I picked it because the project needed reliability more than language tricks. That changed my relationship with the language immediately. Instead of trying to show off in code, I started looking for the shortest path to something solid.
That is what made Go click for me. It felt like a language that kept asking one useful question: can you make this simple enough that another engineer can understand it quickly and trust it in production?
What Go Gets Right
Simplicity as a Feature
The first thing I liked was how small the language feels. Go gives you a handful of keywords, a small standard shape for programs, and very little room to be too clever. That can feel limiting at first, especially if you come from TypeScript on the frontend where you can express almost anything at the type level. But for backend work, that limitation started feeling like a feature.
When I read my Go code, it usually says exactly what it is doing. When I read some of my older code in other stacks, I sometimes see too much abstraction, too many helper layers, or clever ideas that were annoying to carry in my head later. Go has pushed me toward writing plainer software, and I mean that as praise.
There is another reason that simplicity landed quickly for me. I learned C during my bachelor's and again through CS50. Go is not C. You are not hand managing memory the same way, and the tooling is from a different decade. Still, Go often reminds me of that same mindset: a small language, straight control flow, and types that stay close to the surface. When I write Go, part of me is back in those exercises, just with better batteries for real services.
Concurrency That Makes Sense
This is where the language really won me over. I like goroutines and channels because they gave me a mental model that was easier to trust.
In other stacks, I can absolutely write concurrent work too. I still do. But once you start mixing retries, partial failures, cancellation, and rate limits, that flow can get noisy fast. In Go, a lot of that work starts from a shape that feels closer to how I think.
I stopped thinking about concurrency as hidden runtime magic and started thinking about work moving through a small, readable pipeline.
Scan one table or task without blocking the rest.
Keep another unit of work moving at the same time.
Send the result back when it is done.
Collect results, apply backpressure, and keep the whole thing easy to follow when you come back to it later.
One goroutine does some work. It sends a result through a channel. Another part of the program receives it. That is not the whole story, of course, but it is a great place to start. It gives concurrency a shape.
This is the kind of code that made me smile the first few times I wrote it:
type scanResult struct {
table string
rows int
err error
}
results := make(chan scanResult, len(tables))
for _, table := range tables {
go func(name string) {
rows, err := scanTable(name)
results <- scanResult{table: name, rows: rows, err: err}
}(table)
}
for range tables {
result := <-results
if result.err != nil {
log.Printf("scan failed for %s: %v", result.table, result.err)
continue
}
log.Printf("scanned %s with %d rows", result.table, result.rows)
}It is not advanced or magical. That is exactly why I like it. I can read it six months later and still see the flow immediately.
The other part that helped me was that Go does not force me into a huge framework story first. If I want to spin up workers, pass results, and keep moving, the language already gives me the basic building blocks.
The Standard Library
Go's standard library is probably the most quietly impressive part of the language. Need an HTTP server? net/http. Need JSON? encoding/json. Need tests? testing. Need context propagation? context.
I really enjoy how far you can get before installing anything. That matters to me because smaller dependency surfaces usually mean fewer moving parts to debug. On DSPM, that made the backend feel more stable from the start.
Here is another small example that captures the kind of software I like writing in Go now:
func healthHandler(w http.ResponseWriter, r *http.Request) {
response := map[string]string{
"status": "ok",
"service": "dspm-api",
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}It is direct. No ceremony, no digging through layers to see how a simple response is built. I have learned that I enjoy that feeling more than I enjoy fancy abstractions.
What I still find hard
I do not want this to sound like I switched teams and now I am here to trash the languages I already use. TypeScript is still my default for UI work. Python is still a language I trust for backend and data tasks. I just notice a different kind of clarity when I am in Go.
Type inference in TypeScript can feel amazing. Tooling around React and Next.js is still where I feel the fastest on the frontend. Python also still earns its place because it is practical, flexible, and easy to reach for. In Go, I am still learning how to write code that feels idiomatic instead of merely correct. Those are not the same thing.
I also still hit moments where I know the software works, but I can tell a more experienced Go engineer would shape it better. That part does not discourage me. Honestly, I like it. It means the language still has depth for me to grow into.
I am still mastering Go, but I am already comfortable building real software in it. That is part of why I like recommending it. You can become productive before you become advanced.
Why this matters to me as an engineer
The bigger lesson for me has not been "Go is better than TypeScript or Python." It has been that the language you choose changes the way you think about the system you are building.
Go makes me reach for simplicity earlier. It makes me think about concurrency in a way that feels concrete. It makes me depend on fewer things by default. And for the kind of backend software I want to get better at, that has been a very healthy influence.
I still use TypeScript for frontend work, and Python still makes sense to me for plenty of backend and data tasks. But when I am building services, internal tools, small APIs, or anything that needs to do a lot of work without becoming hard to reason about, Go has started becoming my default pick.
I am saying that as someone who is still learning, not as someone pretending to know everything about the language. Maybe that is exactly why I like it so much right now. It already lets me write good software, and it still has a lot more to teach me.