Basecamp is a Ruby company. All of our customer facing applications are written with Ruby on Rails, we use Ruby for our systems automation via Chef, we deploy via Ruby through Capistrano, and underneath most rocks you’ll find a Ruby script that accomplishes some task.
Increasingly, however, Go has found its way into our backend services and infrastructure in a variety of ways:
- Our timeseries data acquisition and storage daemon was rewritten from Ruby to Go in January 2013.
- Our Ruby build scripts build new Ruby packages for our servers via Docker.
- Our log parsing and storage pipeline writes to Kafka, HDFS, and HBase via an assemblage of Go programs.
- We backup our DNS records from Dynect with a tool written in Go.
- We run a multi-master Nagios installation via a Go-based passive check bridge and multi-host notifier.
- We keep our GitHub post-commit hooks in shape using a Go program.
- The server side of our real user monitoring and pageview tracking systems are entirely written in Go.
- We regularly download, decrypt, and test the integrity of our offsite database backups with a Go program.
There are also numerous experiments in Go that haven’t made it into production: keeping multiple memcached instances in sync from packet captures, serving Campfire over websockets, packaging our Rails apps into Docker containers, and more. We’re also heavy users of some third party Go applications (etcd and sentinel) which power our failover process between datacenters.
Our use of Go is entirely organic. We never sat down one day and decided to start using it; people just started writing new things in Go.
Personally, I like Go because the semantics of channels and goroutines are a great fit for building data pipelines, and the innate performance of Go programs means I don’t have to think as much about the load that a parser might be adding to a server. As a language, it’s a pleasure to write in—simple syntax, great standard library, easy to refactor. I asked a few other people why they enjoy working in Go:
Will: “Go feels perfect for Ops work. The error handling seems to fit so naturally into the way I want to write systems software, and on top of that it’s good (and getting better) at using multiple cores effectively. Deployment is really simple too, where I’d have to think about how to package up deps and configure Ruby versions I can now just push an updated binary.”
Taylor: “When you are learning a new programming language sometimes you reach a point where trying to solve a real problem furthers your understanding of the language and it’s strengths. Go’s fantastic documentation, ease of testing and deployment (compile once and run anywhere via a single binary) are enough to help even a novice write a performant and reliable program from the start. Where you might spend hours debugging a threading bug in your Ruby program you can spend minutes implementing go channels that seem to just work. For even the basic script that needs high concurrency this is a huge win.”
It’s unlikely that you’ll ever see a fully Go-powered version of Basecamp, but Go has certainly found its way deep into our infrastructure and isn’t likely to go anywhere soon. If you’ve never tried it out, give it a shot today!