Expertise
Go developer — the language of performance and resilience
Go is not an alternative to another language — it is the answer to a class of problem. When I need a cross-platform, fast, lightweight and dependable tool or service, Go is where I start.
- Since
- 2018 Since
- years
- 8 years
- posts
- 19 posts
- projects
- 4 projects
Me in the Go ecosystem
Go is not an alternative to another language for me; it is the answer to a particular class of problem. When a service or a tool has to need no installation on the other end, stay up for a long time and run cheap, this is where I start.
I pick the language for the problem, not because I like it. System design itself, with its costs, is written on sade.dev.
What I build in Go
What they have in common: processes with one job, staying up for a long time, running cheap.
-
Microservices
Services with a single responsibility, scaled on their own and deployed separately.
-
Consumers and workers
Background processes chewing through a queue for days without a break.
-
HTTP APIs
Services feeding web and mobile at once — the standard library first, Gin or Fiber when it is not enough.
-
Command-line tools
Programs shipped as a single file, needing no installation on the other end.
Why Go
- 01 A single file
- go build produces one executable. Nothing has to be installed alongside it on the other end — no interpreter, no dependency directory, whether that end is a server, a container image or someone else's machine.
- 02 Cross-platform
- The same source compiles for Linux, macOS and Windows in one command. The code does not change when the target does.
- 03 Concurrency inside the language
- The goroutine and channel model lets me write a consumer that runs in parallel without handing that job to a third-party library.
- 04 Predictability
- Plain syntax and explicit error handling make life easier for whoever reads the code six months later — usually the team taking the work over.
I do not pull a package for what the standard library covers
Work written in Go usually outlives the day it was written, and what makes that possible is not the language alone but a dependency list kept short. Every dependency is a surface somebody will have to look after later; a structure that hides behaviour is a debt of the same class.
Delivery is the other half
Writing the service or the tool is half of it; without the second half, what you wrote only runs on your own machine. On the Go side I set up that second half too.
-
Cross-compilation
Output for three targets from the same source — Linux, macOS, Windows.
-
Embedded version
Version information goes into the binary at build time via ldflags.
-
Signed output
The shipped binary is signed, so the other end can verify what it downloaded.
-
An install path
Installing is not a download step but a single command through a package manager.
The other end of the tool
The person using the tool is usually not the person who wrote it, and I build the surface accordingly.
-
A command tree that reads clearly
What a command does should be clear from its name, without opening the help text.
-
Flags that behave predictably
The same flag means the same thing in every command; surprising behaviour is a class of bug.
-
Errors that say what to do
The message says not only what went wrong but what the user should do next. The same measure applies on the service side.
Go is not the language for every job
For a product that wants heavy business rules, a mature admin panel or a broad package ecosystem, PHP and Laravel still get there faster. I pick the language for the problem, not because I like it — the real cost of polyglot work is not learning a language, it is switching context.
Recent writing in this area
Packaging and Distributing a CLI Tool Written in Go
Writing a Go CLI tool is only half the work; versioning it, cross-compiling it, and distributing it in a way others can install effortlessly is the other half.
archlint: Enforcing Architecture Boundaries in CI, Deterministically
Architecture decisions stay true on the wiki and rot in the code. I built archlint: a standalone Go CLI that enforces the layer boundaries in architecture.json on every commit — with go/parser, no model, in CI. Here's why I built it this way.
One architecture rule, three languages: archlint now does Go + TypeScript + Python
In a polyglot repo, 'domain must not import infrastructure' is the same rule in every language — only how the import resolves differs. I added TypeScript and Python to archlint: one architecture.json enforces all three in CI.
What I have built in this area
Local code review without letting the diff leave the machine
A provider-agnostic Go CLI that has a model review my diff without the diff leaving the machine; it became CommitBrief.
What it does today
Reviews code locally, with the diff never leaving the machine; the `Provider` interface lets Anthropic, OpenAI, Gemini and Ollama plug into one contract. Signed binaries are published — anyone who does not want to hand their diff to a cloud provider can install it.
What shipped in this area
CommitBrief
OngoingFounder & Developer
CommitBrief is a provider-agnostic Go CLI tool that performs LLM-powered local code review on git diffs. It reviews any scope — from staged/unstaged changes to a single commit to PR-style three-dot ranges — without leaving the terminal, without leaking the diff, and with customizable project rules.
Questions in this area
9 questions answered on this axis.
Should I run several dependent operations with errgroup so the first error cancels the rest?
Move to `errgroup.WithContext` with a request-level timeout on top and thread ctx into every HTTP and DB call; an ignored ctx means no cancellation at all.
How do I propagate context cancellation correctly through nested service calls?
Cancellation propagates only if you pass `r.Context()` into every downstream call, leave no `context.Background()` in the chain, and use `WithoutCancel`.
How do I detect and prevent goroutine leaks in a long-running Go service?
Export NumGoroutine() as a metric, take a pprof goroutine dump at peak, make the spawn site behind the parked stacks honor ctx.Done(), then add goleak.
Technologies I pair it with
-
Cobra
Command tree and flag surface.
-
go-git
Commit-based operations; I fall back to the git binary when the working tree is involved.
-
Goreleaser
Cross-compilation, signed binaries and Homebrew/Scoop distribution.
-
Gin
The router I reach for once an HTTP service outgrows the standard library.
-
Fiber
The same job, in a shape familiar to anyone coming from Express.
Frequently asked
7 questions
-
How long have you used Go?
Since 2018, so 8 years. All of it alongside PHP: Go never replaced a language for me, it stands as the answer to one class of problem.
-
Why did you learn Go?
Being polyglot was never the goal; I simply did not have the right answer for a particular class of problem. Go is statically typed, it compiles, its standard library is broad and its syntax is deliberately plain. I never intended to swap PHP out for it — my depth stayed there, and Go came to represent breadth.
-
What do you build in Go?
Microservices, queue-consuming consumers and workers, HTTP APIs and command-line tools. What they have in common: processes with one job, staying up for a long time, running cheap. This site carries 19 Go-tagged posts.
-
Do you write web services, or only CLIs?
Both. For HTTP I start with the standard library; `net/http` is usually enough to put an API into production. Gin or Fiber comes in when I need a middleware chain, route grouping or ready-made binding.
-
What do you do on the delivery side?
Half the job sits there. Cross-compilation, embedding the version into the binary via ldflags, signed output and an install path — without those, what you wrote only runs on your own machine.
-
How do you switch between Go and PHP?
It has a cost, and I wrote it down: the real price of a polyglot codebase is not learning a language, it is switching context. On days when both are open at once, my error rate goes up.
-
How many projects use Go?
4 of the projects recorded here involve Go: some end to end, others on the service or SDK side.
Let us work together
If you have work in this ecosystem, tell me what you are building and we will talk about how to build it.