Go: The Cloud-Native Language
Abstract
Go was sketched on a whiteboard at Google on 21 September 2007 by Robert Griesemer, Rob Pike and Ken Thompson, three engineers tired of 45-minute C++ builds and of languages that kept adding features. They designed a small, statically typed, garbage-collected language that compiled in seconds, built concurrency in through goroutines and channels, and left out classes, exceptions and (for its first twelve years) generics. Go became open source on 10 November 2009 and stable with Go 1 in March 2012, under a compatibility promise that has held since. It became the language of cloud infrastructure: Docker, Kubernetes, Prometheus, Terraform and etcd are written in it, and in 2025 Microsoft chose it for the native port of the TypeScript compiler. Its omissions drove its longest arguments: generics arrived only in 2022, and in 2025 the team gave up trying to shorten Go’s error handling.
Forty-Five Minutes
Rob Pike told the origin story in a 2012 essay, “Less is exponentially more”. In September 2007 he was working on “an enormous Google C++ program”, whose builds took “about 45 minutes on our huge distributed compile cluster.” During one of those builds he attended a talk by a member of the C++ standards committee about the coming revision of the language, C++0x, which presented “something like 35 new features.” Pike’s reaction was that C++ did not need more features; it needed fewer. “I started another compilation, turned my chair around to face Robert, and started asking pointed questions. Before the compilation was done, we’d roped Ken in and had decided to do something.”
The three had unusual backgrounds for the job. Ken Thompson had created Unix and the B language, the predecessor of C, at Bell Labs (see Ken Thompson and Unix). Rob Pike had worked on Unix, the Plan 9 operating system and the concurrent languages Newsqueak and Limbo, and had designed UTF-8 with Thompson in 1992. Robert Griesemer had taken his doctorate at ETH Zurich in the group of Niklaus Wirth and had worked on the Java HotSpot virtual machine and Google’s V8 JavaScript engine. The language’s ancestry follows them: C for the syntax, Pascal, Modula and Oberon for declarations and packages, and Newsqueak and Limbo for concurrency.
On 21 September 2007 the three began sketching goals on a whiteboard. Thompson started a compiler in January 2008, the project became full-time in mid-2008, and Ian Lance Taylor independently began a front end for the GCC compiler from the draft specification in May 2008. Russ Cox joined late in 2008 and helped turn the prototype into a working system.
What Go Left Out
The Go FAQ describes the problem the designers saw: programmers had to choose between efficient compilation, efficient execution and ease of programming, and no mainstream language offered all three. Go’s answer was a statically typed, compiled language that felt almost as light as a scripting language, with a short list of rules:
- No header files, no forward declarations. Packages declare what they export by capitalization (an identifier starting with a capital letter is public), and the compiler reads each dependency’s compiled export data only once. Large programs compiled in seconds on one machine.
- No class hierarchy. Types have methods, and interfaces are satisfied implicitly: any type with the right methods implements an interface without declaring it. Composition replaces inheritance.
- No exceptions. Functions return errors as ordinary values, usually as the last of several return values, and callers check them with
if err != nil. The FAQ argues that coupling exceptions to control structures “results in convoluted code” and encourages treating ordinary failures, such as a missing file, as exceptional.panicandrecoverexist for real emergencies. - No generics in the first version, because the designers had not found a design whose value justified its complexity.
- Garbage collection, because manual memory management was the main source of the bookkeeping they wanted to remove.
- One format. The
gofmttool rewrites every source file into a single canonical layout, which ended arguments about brace placement and indentation and made machine rewriting of code safe. Rust’s rustfmt and Python’s Black later took the same approach.
Pike summed up the design in his essay’s title and in one sentence: “Less can be more. The better you understand, the pithier you can be.”
Goroutines and Channels
Go’s concurrency comes from Tony Hoare’s Communicating Sequential Processes (1978), by way of Pike’s earlier languages (see Concurrency and Parallelism).
- A goroutine is a function started with the keyword
go. It begins with a stack of a few kilobytes that grows as needed, and the Go runtime schedules many thousands of goroutines onto a small number of operating-system threads. - A channel is a typed pipe through which goroutines send each other values; sending and receiving synchronize the two sides. The
selectstatement waits on several channels at once.
The Go proverb is: “Do not communicate by sharing memory; instead, share memory by communicating.” Go also kept mutexes and atomic operations, and much real Go code uses them, but the goroutine made it practical to write a network server as one simple sequential function per connection and let the runtime handle the rest.
Open Source and Go 1
Google released Go as an open-source project on 10 November 2009. The mascot, a gopher drawn by Renée French (who had also drawn Glenda, the Plan 9 bunny), came with it. So did a naming dispute: Francis McCabe, who with Keith Clark had published an agent-programming language called Go! in 2003, asked Google on the project’s issue tracker to change the name. The request, issue number 9, drew a long discussion and was closed without a change. The language is officially called Go; “golang” comes from the original web address, golang.org.
Go 1, released on 28 March 2012, came with a promise that programs written for it would keep compiling and running on all later Go 1.x releases. The team kept that promise for more than a decade, and it made Go attractive to companies with large code bases. In August 2015 Go 1.5 removed the last C code from the compiler and runtime, so that Go was written in Go, and introduced a concurrent garbage collector that did most of its work while the program ran, sharply reducing pause times. Pike’s 2012 essay also noted who adopted Go and who did not. “C++ programmers don’t come to Go because they have fought hard to gain exquisite control of their programming domain,” he wrote, while “Python and Ruby programmers come to Go because they don’t have to surrender much expressiveness, but gain performance and get to play with concurrency.”
The Cloud-Native Language
Go’s arrival coincided with the move from large single applications to distributed services running in containers (see The Container Revolution and The Cloud Computing Era). Its properties fitted that world: fast builds, a single statically linked binary with no interpreter or shared libraries to install, built-in concurrency and a strong networking standard library. A Go binary could be dropped into an almost empty container image.
The infrastructure of the 2010s was written in it. Docker (2013), which made Linux containers easy to use, was written in Go, and so was Kubernetes (2014), Google’s open-source container orchestrator, which became the standard way to run containers at scale. etcd, the key-value store Kubernetes depends on, the monitoring system Prometheus, HashiCorp’s Terraform, Consul and Vault, the databases CockroachDB and InfluxDB, and the static-site generator Hugo followed.
In March 2025 Microsoft announced that it was porting the TypeScript compiler from TypeScript to Go, reporting builds about ten times faster. Anders Hejlsberg’s team explained that C# or Rust would have meant a rewrite rather than a port: the compiler’s data structures are full of cyclic references that suit a garbage-collected language, and Go was, as Hejlsberg put it, “the lowest level language we can get to and still have automatic garbage collection.”
Generics and Errors
Go’s two longest arguments were about features it left out.
Generics. Critics argued from the start that Go without generics forced programmers to copy code or give up type safety with the empty interface. The team agreed in principle and rejected several designs over a decade. Ian Lance Taylor and Robert Griesemer finally produced a design based on type parameters constrained by interfaces, checked with the help of the type theorist Philip Wadler, and Go 1.18 shipped it in March 2022.
Error handling. The repeated if err != nil { return err } became Go’s best-known complaint. Russ Cox published a design with check and handle keywords in 2018; it was judged too complicated. A simpler try built-in proposed in 2019 drew about 900 comments on GitHub and was withdrawn after objections that it hid control flow. A proposal borrowing Rust’s ? operator in 2024 and 2025 also failed to reach consensus. On 3 June 2025 Griesemer announced that “for the foreseeable future, the Go team will stop pursuing syntactic language changes for error handling” and would close such proposals: no design had won general agreement, even among the language’s architects.
Russ Cox, who had led the Go project for more than twelve years, stepped down as tech lead on 1 September 2024, saying that twelve years of one leader was enough. Austin Clements took over the project and Cherry Mui the core of the compiler and runtime.
Dead End
The clearest dead end in Go’s history is its first approach to dependency management. Early Go had none: all code lived in one directory tree named by the GOPATH variable, go get fetched the latest version of whatever a program imported, and there was no way to say which version a project needed. That matched Google’s internal practice, a single repository where everything was built from the current head, and it fitted almost no one outside Google. Third-party tools (godep, glide, govendor and others) appeared to fill the gap.
In 2016 a community committee organized by Peter Bourgon, with Sam Boyer, Andrew Gerrand, Ed Muller and Jessie Frazelle, wrote a specification, and Boyer led its implementation as dep, released in January 2017 and promoted as “the official experiment”. Many companies moved to it. In February 2018 Russ Cox published a different design, “vgo”, based on a new algorithm he called minimal version selection, and in August 2018 it shipped as Go modules in Go 1.11. Cox argued that dep had “showstopper” flaws, such as not supporting several major versions of a package in one build, and wrote in 2018: “In retrospect I made lots of mistakes, but the biggest one was not communicating concerns with Dep and plans for go command integration more widely and publicly.” Bourgon replied that the core team had not engaged with the committee’s work before proposing its own. Dep was deprecated and its repository archived; GOPATH mode was phased out. Modules worked, but the episode cost the volunteers who had built dep two years of work and left a lasting suspicion that Go’s community proposals mattered less than the Google team’s.
📚 Sources
- Rob Pike, “Less is exponentially more” (June 2012): the 45-minute build, C++0x talk, founding conversation, who adopted Go
- Go FAQ: history (21 September 2007, January 2008, mid-2008, Ian Lance Taylor, Russ Cox, 10 November 2009), gopher, name, ancestry, reasons for no exceptions and no initial generics
- Rob Pike, “Go at Google: Language Design in the Service of Software Engineering” (2012)
- The Go Programming Language official site and Wikipedia: Go (programming language)
- Go blog, “Go version 1 is released” (28 March 2012)
- Phoronix, “Go 1.5 Released, Its Compiler Toolchain Is Now In Go” (August 2015) and Go blog, “Six years of Go”
- Hacker News, “Go! – the non-Google programming language by Keith Clark and Francis McCabe” (2009) and Wikipedia: Go! (programming language)
- Go 1.18 Release Notes
- Robert Griesemer, “[ On | No ] syntactic support for error handling”, Go blog (3 June 2025)
- The New Stack, “Russ Cox Steps Down as Tech Lead of Go Programming Language” (August 2024)
- Visual Studio Magazine, “Microsoft Ports TypeScript to Go for 10x Native Performance Gains” (11 March 2025) and The New Stack, “Microsoft TypeScript Devs Explain Why They Chose Go Over Rust, C#”
- Russ Cox, “Go += Package Versioning” (February 2018) and Go blog, “Go Modules in 2019”
- Peter Bourgon, “A response about dep and vgo” (27 July 2018) and Sam Boyer, “An Analysis of Vgo”
- C. A. R. Hoare, “Communicating Sequential Processes” (1978)
- Image: Go gopher frontpage.png by Renee French (CC BY 3.0), via Wikimedia Commons
- Image: Robert Griesemer.jpg by Eugene Zelenko (CC BY-SA 4.0), via Wikimedia Commons