I've been working in Go for the past two years at Assembled (https://www.assembled.com), where it's been our primary backend language since the inception of the company. In my prior job, I worked in a mix of Ruby and Scala, and there was definitely an initial adjustment period. Overall, I've found that Go behaves essentially as-advertised: it's well-suited for professional work though annoying in some of its quirks.

Some context

Assembled is a web application used by customer support teams to manage staffing and analytics. From an architecture perspective, it's a standard web application—a React frontend accesses a Go backend via an internal HTTP API, which in turn accesses a PostgreSQL database.

That said, there are a few specific applications that we've also had to optimize for:

Go in production

We deliberately decided to build Assembled in Go over Python, Java, and Haskell (yeah...). The deciding factors came down to: static typing, simplicity, the standard library, and speed. In practice, everything I've seen maps surprisingly well to how Go presents itself in the docs:

Go is expressive, concise, clean, and efficient... Go compiles quickly to machine code yet has the convenience of garbage collection and the power of run-time reflection. It's a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language

Easy, albeit tedious, for new engineers

Go's simplicity has allowed new engineers to quickly spin up on our codebase, many of whom had never used the language before (this includes myself). I suspect Go's design has forced us to write simpler and more explicit code than we otherwise would have. That said, the simplicity does lead to repetitiveness, as has been well documented. The snippet if err != nil appears 2,919 times in our codebase as of writing. [1]

The standard library does what's needed