When I started writing Go professionally, I didn't expect it to become my default tool for everything backend. But after years of building systems that handle real traffic and real failure modes, I keep coming back to it.
Why Go Works for Backend Systems
Go's simplicity is not a limitation, it's a feature. When your system is handling thousands of requests per second, you want every line of code to be predictable. Take a look at this:
func (s *Service) ProcessOrder(ctx context.Context, order Order) error {
if err := s.validate(order); err != nil {
return fmt.Errorf("validation failed: %w", err)
}
return s.repo.Insert(ctx, order)
}You can understand clearly what each line does. And because of the types and the language being compiled, most of the LSPs work perfectly, making it as easy as coding or debugging can possibly be.
The Case for Clean Architecture
Separating your domain logic from infrastructure is not academic exercise. It pays off the first time you need to swap a database driver, change a queue provider, or write a test without spinning up Docker (but when I do, I use testcontainers).
The architecture should scream the use case, not the framework.
The layered approach I follow:
- HTTP handlers: thin, parse request, call service, return response
- Application services: orchestrate business logic, no infrastructure details
- Repositories: data access behind interfaces, swappable implementations
- Infrastructure: database, cache, external APIs, all behind interfaces
The elephant in the room
Yeah, I am talking about Go, but whenever we start this discussion something else comes along: which ORM will we use?
Usually, it depends. As Andreia, my co-worker and friend presented in a GopherCon, each case has its own advantages, for instance, if you are just building a simple CRUD, it is easier to choose, but if performance matters, vanilla SQL is superior. And more than that, SQL is already settled, while most ORMs may suffer from security issues, lack of features and so on. As another friend says in his site Boring SQL
Over 50 years old and [SQL is] still one of the most in-demand programming languages.
My DBMS of choice is PostgreSQL. Between JSONB for the times you actually need schema flexibility,
CTEs for readable complex queries, and rock-solid ACID guarantees, it covers virtually every use case I have encountered.
Add pgx as the driver and you get connection pooling, prepared statements, and native type support without the ORM overhead.
Boring Technology Wins
PostgreSQL over the shiny new database. Standard library over the trendy framework. Explicit error handling over exception magic. These choices compound over years of maintenance.
The best system is the one that never wakes you up at 2 AM. The second best is the one you can actually debug when that happens.