Almost a year ago, we blogged about our reasoning and methodology for choosing Go as our next generation platform here at clypd. A year is a long time, both in software technology and in the lifetime of a startup. Since paper is the traditional gift for a one year anniversary, it seems appropriate to write down our learnings so far.
When we posted “Getting to Go,” we included a list of the selection factors we used to evaluate potential platforms. The list includes:
So, how did we do?
I’ve observed new engineers ramping up very quickly relative to other languages. Our process has been to ask a new team members to write real Go code within their first few days and contributing to our production codebase within a week. The simplicity of the language and maturity of the toolchain seems to align well with Andrew Gerrand’s sentiment productive in one day, efficient in one week, expert in one year.
The community has been a fun part of our experience learning Go. Gophercon was both informative and motivational and we’ve enjoyed the high signal-to-noise ratio on golang-nuts. We’ve initiated a few pull requests to open source Go projects (envconfig, gorp) and even open-sourced our implementation of munkres algorithm.
We’ve relied heavily on the built-in testing package for test automation and testify has been a useful addition for lightweight assertions. When simple unit tests were insufficient, we combined the testing package with Docker to build a complete database integration testing framework that’s helped us avoid an entire class of errors. And now that application performance is a concern, we’ve explored the built-in profiling capabilities and they’ve helped us quickly uncover some obvious inefficiencies in our code.
We’ve leaned heavily on community packages with positive results. go.rice, go-json-rest, go-dogstatsd, goamz, and many others have helped us build a lot with a little. These packages all excel at doing one thing well, yet they all easily integrate together within our applications. From our perspective, the Go community has provided a diverse set of packages for third-party products and services. We have yet to struggle with a technical integration due to a lack of Go support. We’ve even added support for some older standards, like SOAP in Go, although the tooling hasn’t been as flexible as we’d prefer.
Our builds and deployments are very straightforward, simple, and fast. Our current codebase builds from scratch in the time it takes you to read this paragraph. And deployments couldn’t be simpler since we’re distributing stand-alone binaries.
As a team, we’ve mostly settled on Sublime Text and the integration with GoSublime works great. We’ve caught bugs early using external static analyzers like gofmt, govet, golint, and errcheck. The styling decisions imposed on us by gofmt took some time to get used to, but no one misses the useless style debates that we experienced with less opinionated languages. We even built a rudimentary source code rewriter using ast/parser and friends from the standard library to automate a fairly major source code refactoring.
I’m happy to report that deploying Go binaries into production has been a breeze.
We haven’t encountered any issues related to the Go compiler or runtime yet. (But I’m sure my boss will say that I’m jinxing us by writing it down.)
However, this past year hasn’t all been unicorns and roses. Perhaps the most difficult hurdle was overcoming the endless barrage of puns related to the name “Go.” Thankfully, this has tapered as the novelty has worn off. I find myself groaning much less frequently.
As you can probably tell, we’re very happy with our Go experiences so far. From our first commit on January 8th, our team has written nearly 60k lines of Go. The Go platform has helped us avoid struggling with compilers, interpreters, virtual machines, and complicated third-party package integrations. Instead, we can focus on addressing our immediate business needs.