The Go programming language (Golang): a complete overview, pros, cons and limits
What the Go programming language is for, where it is the best choice and where another language wins: pros and cons, a comparison with Python, Node.js, Java, Rust and PHP, code examples, the ecosystem, limits and tips.
In short
Go (Golang) is a compiled, statically typed programming language from Google with a deliberately small syntax and concurrency built in. It is at its best in backends and APIs, microservices, network services, command-line tools and cloud infrastructure — Docker, Kubernetes and Terraform are written in it. A Go program builds into a single file with no dependencies, compiles in seconds and handles thousands of simultaneous connections with little memory. Its weak spots are machine learning and data science, desktop and mobile interfaces, games and hard real-time systems; error handling is verbose and the type system is modest.
Go at a glance
The main facts in one table — what kind of language it is, how it runs and how it evolves.
- Created by
- Robert Griesemer, Rob Pike and Ken Thompson at Google, 2007
- Released
- Announced in 2009, Go 1.0 in 2012
- Typing
- Static and strict, with type inference:
x := 10 - Execution
- Compiled to machine code; the result is one binary
- Memory
- Garbage collector running alongside the program; pauses are usually under a millisecond
- Concurrency
- Goroutines and channels, spread over all CPU cores
- Generics
- Since Go 1.18 (2022)
- Keywords
- 25 — one of the smallest sets among popular languages
- Releases
- Twice a year, in February and August; the two latest versions are supported
- Compatibility
- The Go 1 promise: code written for old versions builds with new ones
- Tooling
- Build, tests, formatting, analysis, profiling and dependencies — all in the
gocommand - Platforms
- Linux, macOS, Windows, BSD; x86, ARM and others; WebAssembly
What Go is used for: 8 areas
Go was built at Google for large networked services, and that is where it has taken root. Under each area — well-known projects written in Go.
-
01
Backends and APIs
REST, GraphQL and gRPC services. The standard library alone runs a production HTTP server — with routing, TLS and JSON.
-
02
Microservices
Small binaries, instant start-up and low memory use make Go a natural fit for dozens of services in containers.
-
03
Cloud and DevOps
The backbone of modern infrastructure: containers, orchestration and infrastructure as code are written in Go.
-
04
Monitoring
Metric collectors, log pipelines and tracing systems — they process huge streams of data around the clock.
-
05
Networking and proxies
Web servers, load balancers and DNS: thousands of connections at once is exactly the load Go was designed for.
-
06
Command-line tools
One file for every OS, no runtime to install — ideal for utilities you hand to other people.
-
07
Databases and storage
Distributed databases and object storage, where concurrency and predictable latency matter.
-
08
Developer tools and AI services
Fast bundlers and compilers — Microsoft moved the TypeScript compiler to Go for speed — and servers for running local AI models.
Pros and cons of Go
Go deliberately trades expressiveness for simplicity. Most of its strengths and weaknesses grow from that one decision.
Pros · 8
-
A language you can read
25 keywords, one loop, one formatting style for everyone (
gofmt). Someone else’s code reads like your own — a big deal for teams. -
Fast compilation
Large projects build in seconds, so the edit–run loop feels almost like a scripting language.
-
One file to deploy
No interpreter, virtual machine or dependency folder on the server. Copy the binary — it runs. Docker images shrink to a few megabytes.
-
Built-in concurrency
A goroutine starts with a few kilobytes of stack, so a program can run hundreds of thousands of them.
go f()— and the work runs in parallel. -
Performance
Native code with a fast start: many times faster than Python and PHP on computation, close to Java, with less memory.
-
A strong standard library
HTTP server and client, JSON, cryptography, TLS, SQL, templates, testing and structured logging — without a single third-party package.
-
Tooling out of the box
Tests, benchmarks, fuzzing, a race detector, a profiler and dependency management come with the compiler.
-
Stability
Code from 2012 still builds. Upgrading the compiler rarely means rewriting anything.
Cons · 8
-
Verbose error handling
No exceptions: every call that can fail is followed by
if err != nil. In 2025 the Go team said it would not change this syntax. -
A modest type system
No enums or sum types — constants with
iotainstead. Generics are limited: methods cannot have their own type parameters. -
No classes or inheritance
Structs, methods, interfaces and embedding. Clean, but developers coming from Java or C# have to rethink their habits.
-
A garbage collector
Pauses are short but not zero, and memory use is higher than in C or Rust. Hard real-time is not for Go.
-
Weak for data and ML
No counterpart to NumPy, pandas or PyTorch. Models are trained in Python; Go serves them at best.
-
No native interfaces
Desktop and mobile apps are possible (Fyne, Wails, gomobile), but these are niche tools with small communities.
-
nil traps
Writing to a nil map panics, and an interface holding a nil pointer is not itself nil. Newcomers stumble on both.
-
Heavier binaries than C
The runtime is built into every program, so even “hello world” weighs a couple of megabytes. For microcontrollers there is TinyGo.
Go compared with Python, Node.js, Java, Rust and PHP
A qualitative comparison for typical backend work. Exact numbers depend on the task and the code, so the table shows relative positions rather than benchmarks.
| Criterion | Go | Python | Node.js | Java | Rust | PHP |
|---|---|---|---|---|---|---|
| Typing | static | dynamic, optional hints | dynamic; static with TypeScript | static | static, very strict | dynamic, optional types |
| How it runs | machine code | interpreter | JIT (V8) | JIT (JVM) | machine code | interpreter, OPcache and JIT |
| Speed on computation | high | low | medium to high | high | highest | medium |
| Memory use | low | medium | medium | high | lowest | medium |
| Parallelism | goroutines on all cores | limited by the GIL; a GIL-free build is new | one thread and an event loop, plus workers | threads and virtual threads | threads and async | a process per request |
| Start-up time | milliseconds | fast | fast | slower: the JVM warms up | milliseconds | fast |
| Deployment | one binary | interpreter and packages | Node and node_modules | JVM and a JAR | one binary | PHP and a web server |
| Learning curve | low | lowest | low | medium | high | low |
| Best at | network services, infrastructure | data, ML, scripts | web, one language for front and back | large enterprise systems | system software, speed without GC | websites and CMS |
When to choose Go — and when not to
Thirteen typical tasks with a verdict. Where Go is not the best choice, the alternative is named.
-
API and web service backend
Best fitThe standard library covers the basics; fast, compact and easy to deploy.
-
Microservices
Best fitSmall images, instant start, low memory — dozens of services stay cheap.
-
Command-line tools
Best fitOne file for Linux, macOS and Windows, built from any machine.
-
Chats, WebSockets, proxies
Best fitThousands of open connections is the load goroutines were made for.
-
DevOps tools, Kubernetes operators
Best fitThe whole ecosystem and its client libraries are in Go.
-
Parsers, crawlers, queue workers
WorksGreat for parallel downloads; for complex scraping Python has richer libraries.
-
A content site with an admin panel
WorksPossible, but a ready CMS or a static generator is usually faster to launch. Hugo itself is written in Go.
-
Machine learning and data analysis
Pick anotherTake Python: the libraries and the community are there.
-
Mobile apps
Pick anotherSwift, Kotlin, Flutter or React Native.
-
Desktop interfaces
Pick anotherTauri, Electron or native toolkits; in Go — only Wails and Fyne.
-
Games
Pick anotherUnity, Godot or C++; Go has the small Ebitengine for 2D.
-
Microcontrollers
Pick anotherC or Rust; TinyGo covers only part of the chips and the language.
-
Hard real-time, drivers
Pick anotherC, C++ or Rust: no garbage collector and full control over memory.
The Go ecosystem: libraries for common tasks
In Go it is normal to start with the standard library and add a package only when it clearly saves work. The middle column is what comes with the language.
| Task | Standard library | Popular packages |
|---|---|---|
| HTTP routing | net/http (ServeMux) | chi, Gin, Echo, Fiber |
| PostgreSQL and SQL | database/sql | pgx, sqlc, sqlx, GORM, Ent |
| Migrations | — | goose, golang-migrate, Atlas |
| Logging | log/slog | zap, zerolog |
| Configuration | os, flag | Viper, caarlos0/env |
| Command-line interface | flag | Cobra, urfave/cli |
| HTML templates | html/template | templ |
| Tests | testing | testify, go-cmp, uber-go/mock |
| gRPC and RPC | — | grpc-go, connect-go |
| WebSockets | — | coder/websocket, gorilla/websocket |
| Queues | — | NATS, franz-go (Kafka) |
| Validation | — | go-playground/validator |
| Linters and security | go vet | golangci-lint, govulncheck |
| Hot reload | — | air |
The limits of Go: where it hits the ceiling
-
Garbage collection and memory
Pauses are short, but under heavy allocation the collector takes CPU and memory. Tune
GOGCandGOMEMLIMIT, reuse buffers — and for hard deadlines choose C or Rust. -
Heavy number crunching
No mature numeric libraries and little control over vectorisation. Typical split: Go orchestrates, heavy maths runs in C++ or on the GPU — that is how Ollama works.
-
Calling C (cgo)
Each call into C is expensive, and cgo breaks the easy static build and cross-compilation. Prefer pure-Go packages where they exist.
-
Reflection and JSON
encoding/jsonworks through reflection and becomes a bottleneck on hot paths. There, use code generation or faster libraries — after measuring. -
Complex domain models
Without sum types and with limited generics, rich domain logic turns into switches over interfaces and repeated checks. Keep models flat and simple.
-
Binary size
The runtime lives inside every program. Not a problem for servers, but for tiny devices and WebAssembly the size matters — there TinyGo helps.
8 tips for writing Go without the bruises
-
01
Start with the standard library
net/http,database/sqlandlog/slogcover most of a typical service. Add a framework when you know exactly what it saves. -
02
Wrap errors with context
fmt.Errorf("load order %d: %w", id, err)turns a bare “not found” into a readable trail. Never throw an error away with_. -
03
Give every goroutine an exit
A goroutine waiting forever is a memory leak. Pass
context, close channels, useerrgroupfor groups of tasks. -
04
Catch races with -race
Run tests with
go test -racein CI. The race detector finds shared-memory bugs that otherwise show up once a month in production. -
05
Small interfaces, declared by the user
An interface of one or two methods, declared where it is used. Functions accept interfaces and return concrete types.
-
06
Profile before optimising
pprofand benchmarks show where the time really goes. Guesses about speed in Go are usually wrong. -
07
Linters from day one
gofmt,go vet,golangci-lintandgovulncheckin CI. They are cheap and catch whole classes of bugs and known vulnerabilities. -
08
A simple project layout
cmd/for entry points,internal/for code no one should import from outside. Do not copy huge template layouts “for the future”.
What Go looks like: 3 code examples
Three short examples behind Go’s main strengths: a server without a framework, parallel work and shipping as one file. The programs run with go run main.go.
An HTTP API on the standard library
Since Go 1.22 the built-in router understands methods and path parameters, so a simple API needs no framework.
package main
import (
"encoding/json"
"log"
"net/http"
)
type Greeting struct {
Message string `json:"message"`
}
func main() {
mux := http.NewServeMux()
// method and path parameter right in the route pattern
mux.HandleFunc("GET /hello/{name}", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(Greeting{Message: "Hello, " + r.PathValue("name")})
})
log.Fatal(http.ListenAndServe(":8080", mux))
}
Goroutines and channels: parallel downloads
Every request runs in its own goroutine, and results come back through a channel. Three pages load in the time of the slowest one.
package main
import (
"fmt"
"net/http"
)
func main() {
urls := []string{"https://go.dev", "https://pkg.go.dev", "https://example.com"}
results := make(chan string)
for _, url := range urls {
go func() { // each download in its own goroutine
resp, err := http.Get(url)
if err != nil {
results <- url + ": " + err.Error()
return
}
resp.Body.Close()
results <- url + ": " + resp.Status
}()
}
for range urls { // wait for exactly as many answers as we started
fmt.Println(<-results)
}
}
Build for a server and ship
Two environment variables build for another OS and processor right from your laptop. For HTTPS calls from an empty scratch image, add CA certificates or use a distroless image.
# build for a Linux server from a Mac or Windows machine
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o app ./cmd/app
# checks before release
go vet ./...
go test -race ./...
# Dockerfile: an image of a single file
# FROM scratch
# COPY app /app
# ENTRYPOINT ["/app"]
Questions about Go
Go or Golang — which name is right?
The official name is Go. “Golang” comes from the old site golang.org and is used mostly for searching, because the word “go” is too common.
What is Go used for most often?
Backends and APIs, microservices, cloud infrastructure and DevOps tools, network services and command-line utilities. Docker, Kubernetes, Terraform and Prometheus are written in Go.
Is Go faster than Python?
On computation and concurrent work — yes, usually many times over, and on pure number crunching by an order of magnitude or more. Python wins on its ecosystem for data and machine learning, not on speed.
Go or Rust?
Go is faster to write and learn and has a garbage collector. Rust gives maximum performance without a collector and checks memory safety at compile time, but is much harder to learn. Services — Go; system software and performance-critical parts — Rust.
Go or Node.js for a backend?
Node.js means one language for the front end and back end and the huge npm ecosystem. Go wins on CPU-heavy work and many connections: it uses all cores, needs less memory and ships as one binary.
Is Go good for websites?
For the backend and API of a web service — very much so. Go can render HTML itself with html/template or templ. For a content site with an admin panel a ready CMS is usually quicker.
Does Go have object-oriented programming?
Partly. There are structs with methods, interfaces that types satisfy implicitly, and composition through embedding. There are no classes and no inheritance.
Is Go hard to learn?
The syntax is small: the official Tour of Go covers the basics, and you can write useful programs within days. The real learning is concurrency patterns and the idioms of simple code.
Online form
Website development
in Go
I use Go in my work for backends, APIs and services — fast, light on the server and shipped as a single file. Tell me about the task: I answer within one working day and will say honestly whether you need Go or a simpler stack will do.