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.

Stack and technologies Updated

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 go command
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.

  1. 01

    Backends and APIs

    REST, GraphQL and gRPC services. The standard library alone runs a production HTTP server — with routing, TLS and JSON.

    net/httpchiGinEcho

  2. 02

    Microservices

    Small binaries, instant start-up and low memory use make Go a natural fit for dozens of services in containers.

    gRPCProtobufConnect

  3. 03

    Cloud and DevOps

    The backbone of modern infrastructure: containers, orchestration and infrastructure as code are written in Go.

    DockerKubernetesTerraformHelm

  4. 04

    Monitoring

    Metric collectors, log pipelines and tracing systems — they process huge streams of data around the clock.

    PrometheusGrafanaLokiJaeger

  5. 05

    Networking and proxies

    Web servers, load balancers and DNS: thousands of connections at once is exactly the load Go was designed for.

    CaddyTraefikCoreDNS

  6. 06

    Command-line tools

    One file for every OS, no runtime to install — ideal for utilities you hand to other people.

    GitHub CLIHugofzflazygit

  7. 07

    Databases and storage

    Distributed databases and object storage, where concurrency and predictable latency matter.

    CockroachDBetcdVitessMinIO

  8. 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.

    esbuildTypeScript 7Ollama

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 iota instead. 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.

CriterionGoPythonNode.jsJavaRustPHP
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 fit

    The standard library covers the basics; fast, compact and easy to deploy.

  • Microservices

    Best fit

    Small images, instant start, low memory — dozens of services stay cheap.

  • Command-line tools

    Best fit

    One file for Linux, macOS and Windows, built from any machine.

  • Chats, WebSockets, proxies

    Best fit

    Thousands of open connections is the load goroutines were made for.

  • DevOps tools, Kubernetes operators

    Best fit

    The whole ecosystem and its client libraries are in Go.

  • Parsers, crawlers, queue workers

    Works

    Great for parallel downloads; for complex scraping Python has richer libraries.

  • A content site with an admin panel

    Works

    Possible, 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 another

    Take Python: the libraries and the community are there.

  • Mobile apps

    Pick another

    Swift, Kotlin, Flutter or React Native.

  • Desktop interfaces

    Pick another

    Tauri, Electron or native toolkits; in Go — only Wails and Fyne.

  • Games

    Pick another

    Unity, Godot or C++; Go has the small Ebitengine for 2D.

  • Microcontrollers

    Pick another

    C or Rust; TinyGo covers only part of the chips and the language.

  • Hard real-time, drivers

    Pick another

    C, 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.

TaskStandard libraryPopular 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

  1. Garbage collection and memory

    Pauses are short, but under heavy allocation the collector takes CPU and memory. Tune GOGC and GOMEMLIMIT, reuse buffers — and for hard deadlines choose C or Rust.

  2. 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.

  3. 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.

  4. Reflection and JSON

    encoding/json works through reflection and becomes a bottleneck on hot paths. There, use code generation or faster libraries — after measuring.

  5. 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.

  6. 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

  1. 01

    Start with the standard library

    net/http, database/sql and log/slog cover most of a typical service. Add a framework when you know exactly what it saves.

  2. 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 _.

  3. 03

    Give every goroutine an exit

    A goroutine waiting forever is a memory leak. Pass context, close channels, use errgroup for groups of tasks.

  4. 04

    Catch races with -race

    Run tests with go test -race in CI. The race detector finds shared-memory bugs that otherwise show up once a month in production.

  5. 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.

  6. 06

    Profile before optimising

    pprof and benchmarks show where the time really goes. Guesses about speed in Go are usually wrong.

  7. 07

    Linters from day one

    gofmt, go vet, golangci-lint and govulncheck in CI. They are cheap and catch whole classes of bugs and known vulnerabilities.

  8. 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.

main.go
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.

main.go
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.

terminal
# 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.

Or write to [email protected]