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
- 21 posts
- projects
- 5 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
You chose RAG. The real work starts now
RAG or fine-tuning gets answered everywhere. The three questions left after it — the key, the model choice, the budget — get answered nowhere.
18,750 req/s: precise, repeated, and three times wrong
Two phases of the same run measured the same service three times apart. What caught the wrong one was not a better statistic but a second method.
Packaging and Distributing a CLI Tool Written in Go
Writing a Go CLI is half the work; versioning it, cross-compiling it and distributing it so others can install it effortlessly is the other half.
Measurements in this area
64 goroutines on four cores: Mutex and channel run at the same speed, but the Mutex's p99 is five times higher
When G goroutines on P cores hammer the same shared counter, how many operations a second do sync.Mutex, an owner-goroutine channel and a buffered channel manage, and how do tail latency and fairness of waiting change?
Finding
With 64 goroutines on four cores, sync.Mutex and a one-way channel run at the same speed (7.69 and 7.94 million operations/s) but the Mutex's p99 wait is 5 times higher. On eight cores the Mutex is 2.4 and 4.0 times faster (15.96 million operations/s; the channels 6.65 and 3.97 million); the ratios come from unflagged cells.
measured 5 days ago
One core carries 14,330 OAuth2 requests in Go and 5,152 in PHP-FPM
The same API verifies an RS256 bearer token on every request and then reads or writes one row in PostgreSQL — on one, two and four cores, how much mixed traffic does it carry in Go, PHP-FPM and FrankenPHP worker mode?
Finding
On four cores Go carried 57,321 mixed requests a second, FrankenPHP 25,659 and php-fpm 20,606 — 14,330, 6,415 and 5,152 per core. The number that goes into a capacity plan is not that one but application CPU per request: 66.8, 110.7 and 187.7 microseconds. At saturation FrankenPHP uses only 2.84 of its four cores, against Go's 3.83 and php-fpm's 3.87. The database is not the constraint: on the same four cores PostgreSQL alone writes 68,212 rows a second, above the mixed ceiling of the fastest candidate.
measured 17 days ago
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
Tier: Main FocusCommitBrief 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
11 questions answered on this axis.
Does my channel buffer size choice hide backpressure problems, and how do I decide it?
Keep channel capacity near the worker count, let blocking propagate to the Kafka poll loop, and when consumer lag climbs grow workers, not the buffer.
My Go worker in a container never receives SIGTERM and won't shut down gracefully—is this a PID 1 problem?
Flip `CMD` to exec form and listen with `signal.NotifyContext(..., syscall.SIGTERM)` instead of `os.Interrupt`; add tini only if the worker forks.
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.
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 21 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?
5 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.