Three Dots Labs Three Dots Labs
  • Home
  • Blog
  • Newsletter
  • Live & Podcast
  • Training & Courses
  • Get our e-book
Get our e-book
Type something to search..
to navigate to select ESC to close

Go

  • Home /
  • Tags /
  • go
Unpopular opinions about Go

Unpopular opinions about Go

Quick takeaways Simplicity isn’t enough for complex applications - while Go’s syntax is simple, complex applications still need proper design patterns; primitive code easily becomes spaghetti code in large projects. Reading the standard library isn’t the best way to learn Go - it’s optimized for different goals than typical applications and might be confusing for beginners. Router libraries are better than the standard HTTP package - libraries like Chi or Echo come with a nice high-level API.

When you shouldn’t use frameworks in Go

When you shouldn’t use frameworks in Go

Quick takeaways Frameworks promise productivity but often lead to issues as projects get larger and more complex. The Go community prefers small, focused libraries over frameworks due to Go’s design philosophy influenced by Unix principles. Watch out for risks using frameworks like vendor lock-in, deprecation, and costly migrations that can take months. Explicit code is more maintainable than magic framework abstractions.

Optimising and Visualising Go Tests Parallelism: Why more cores don't speed up your Go tests

Optimising and Visualising Go Tests Parallelism: Why more cores don't speed up your Go tests

  • Avatar
    Robert Laszczak

Recently, I struggled for a couple of hours to understand why the API tests of one project were slow. In theory, we designed tests to run in a fully parallel way – the duration of tests should be close to the longest-running test. Unfortunately, the reality was different. Tests took 7x longer than the slowest test without using 100% available resources.

Distributed Transactions in Go: Read Before You Try

Distributed Transactions in Go: Read Before You Try

  • Avatar
    Miłosz Smółka

In the previous post, I looked into running transactions in a layered architecture. Now, let’s consider transactions that need to span more than one service. If you work with microservices, a time may come when you need a transaction running across them. Especially if the way they are split was an afterthought (the unfortunate but likely scenario). Service A calls service B, which calls service C, and if something goes wrong at the end, the system becomes inconsistent.

Database Transactions in Go with Layered Architecture

Database Transactions in Go with Layered Architecture

  • Avatar
    Miłosz Smółka

As I join a new company, I often feel like an impostor. After all the interviews, they really seem to know what they’re doing. I’m humbled and ready to learn from the best. On one such occasion, a few days in, I dealt with a production outage and asked the most senior engineer for help. They came to the rescue and casually flipped a value in the database with a manual update.

Live website updates with Go, SSE, and htmx

Live website updates with Go, SSE, and htmx

  • Avatar
    Miłosz Smółka

In case you missed the memo, the Single Page Application hype period is over, and we’re now back to PHP and jQuery, I mean rendering HTML on the server. I’m excited! It brings me back to the early 2000s when we were all web developers, not frontend or backend engineers. But there’s one thing I would miss from the SPA era: live updates.

The Go libraries that never failed us: 22 libraries you need to know

The Go libraries that never failed us: 22 libraries you need to know

  • Avatar
    Robert Laszczak

Did you have a situation when you lost a ton of time finding a Go library for your need? In theory, you can check lists like Awesome Go or make a choice based on GitHub stars. But Awesome Go contains over 2600 libraries, and popularity is not always the best indicator of library quality. I often thought that it would be great to have a place where I could find just the best and battle-tested libraries I could use in my project.

The Best Go framework: no framework?

The Best Go framework: no framework?

  • Avatar
    Robert Laszczak

While writing this blog and leading Go teams for a couple of years, the most common question I heard from beginners was “What framework should I use?”. One of the worst things you can do in Go is follow an approach from other programming languages. Other languages have established, “default” frameworks. Java has Spring, Python has Django and Flask, Ruby has Rails, C# has ASP.

Increasing Cohesion in Go with Generic Decorators

Increasing Cohesion in Go with Generic Decorators

  • Avatar
    Miłosz Smółka

Cohesion is part of the low coupling, high cohesion principle that’s supposed to keep your code maintainable. While low coupling means few dependencies, high cohesion roughly translates to single responsibility. Highly cohesive code (a module or a function) is focused on a single purpose. Low cohesion means it does many unrelated things. I’ve written about coupling in the previous article on anti-patterns.

Auto-generated C4 Architecture Diagrams in Go

Auto-generated C4 Architecture Diagrams in Go

  • Avatar
    Krzysztof Reczek

Note Hello! Please give Krzysztof a warm welcome in the first guest post on our blog. 🎉 We’ve been working with Krzysztof for the past two years, and we’re excited to share his work here. Miłosz & Robert We all struggle with software architecture diagrams, don’t we? Have you ever wondered why? If you ask yourself that question, why maintenance of up-to-date and detailed software architecture diagrams is so painful, you will come up with a long list of valid answers.

Safer Enums in Go

Safer Enums in Go

  • Avatar
    Miłosz Smółka

Enums are a crucial part of web applications. Go doesn’t support them out of the box, but there are ways to emulate them. Many obvious solutions are far from ideal. Here are some ideas we use that make enums safer by design. iota Go lets you enumerate things with iota. const ( Guest = iota Member Moderator Admin ) Full source: github.

Common Anti-Patterns in Go Web Applications

Common Anti-Patterns in Go Web Applications

  • Avatar
    Miłosz Smółka

At one point in my career, I was no longer excited about the software I was building. My favorite part of the job were low-level details and complex algorithms. After switching to user-facing applications, they were mostly gone. It seemed programming was about moving data from one place to another using existing libraries and tools. What I’ve learned so far about software wasn’t that useful anymore.

Running integration tests with docker-compose in Google Cloud Build

Running integration tests with docker-compose in Google Cloud Build

  • Avatar
    Miłosz Smółka

This post is a direct follow-up to Microservices test architecture where I’ve introduced new kinds of tests to our example project. Wild Workouts uses Google Cloud Build as CI/CD platform. It’s configured in a continuous deployment manner, meaning the changes land on production as soon as the pipeline passes. If you consider our current setup, it’s both brave and naive. We have no tests running there that could save us from obvious mistakes (the not-so-obvious mistakes can rarely be caught by tests, anyway).

Repository secure by design: how to sleep better without fear of security vulnerabilities

Repository secure by design: how to sleep better without fear of security vulnerabilities

  • Avatar
    Robert Laszczak

Thanks to the tests and code review, you can make your project bug-free. Right? Well… actually, probably not. That would be too easy. 😉 These techniques lower the chance of bugs, but they can’t eliminate them entirely. But does it mean we need to live with the risk of bugs until the end of our lives? Over one year ago, I found a pretty interesting PR in the harbor project.

Microservices test architecture. Can you sleep well without end-to-end tests?

Microservices test architecture. Can you sleep well without end-to-end tests?

  • Avatar
    Miłosz Smółka

Do you know the rare feeling when you develop a new application from scratch and can cover all lines with proper tests? I said “rare” because most of the time, you will work with software with a long history, multiple contributors, and not so obvious testing approach. Even if the code uses good patterns, the test suite doesn’t always follow.

Combining DDD, CQRS, and Clean Architecture in Go

Combining DDD, CQRS, and Clean Architecture in Go

  • Avatar
    Robert Laszczak

In the previous articles, we introduced techniques like DDD Lite, CQRS, and Clean (Hexagonal) Architecture. Even if using them alone is beneficial, they work the best together. Like Power Rangers. Unfortunately, it is not easy to use them together in a real project. In this article, I will show you how to connect DDD Lite, CQRS, and Clean Architecture in the most pragmatic and efficient way.

How to use basic CQRS in Go

How to use basic CQRS in Go

  • Avatar
    Robert Laszczak

It’s highly likely you know at least one service that: has one big, unmaintainable model that is hard to understand and change, or where work in parallel on new features is limited, or can’t be scaled optimally. But often, bad things come in threes. It’s not uncommon to see services with all these problems. What is an idea that comes to mind first for solving these issues?

How to implement Clean Architecture in Go (Golang)

How to implement Clean Architecture in Go (Golang)

  • Avatar
    Miłosz Smółka

The authors of Accelerate dedicate a whole chapter to software architecture and how it affects development performance. One thing that often comes up is designing applications to be “loosely coupled”. The goal is for your architecture to support the ability of teams to get their work done—from design through to deployment—without requiring high-bandwidth communication between teams. Accelerate Note If you haven’t read Accelerate yet, I highly recommend it.

4 practical principles of high-quality database integration tests in Go

4 practical principles of high-quality database integration tests in Go

  • Avatar
    Robert Laszczak

Did you ever hear about a project where changes were tested on customers that you don’t like or countries that are not profitable? Or even worse – did you work on such project? It’s not enough to say that it’s just not fair and not professional. It’s also hard to develop anything new because you are afraid to make any change in your codebase.

The Repository pattern in Go: a painless way to simplify your service logic

The Repository pattern in Go: a painless way to simplify your service logic

  • Avatar
    Robert Laszczak

I’ve seen a lot of complicated code in my life. Pretty often, the reason of that complexity was application logic coupled with database logic. Keeping logic of your application along with your database logic makes your application much more complex, hard to test, and maintain. There is already a proven and simple pattern that solves these issues. The pattern that allows you to separate your application logic from database logic.

Introduction to DDD Lite: When microservices in Go are not enough

Introduction to DDD Lite: When microservices in Go are not enough

  • Avatar
    Robert Laszczak

When I started working in Go, the community was not looking positively on techniques like DDD (Domain-Driven Design) and Clean Architecture. I heard multiple times: “Don’t do Java in Golang!”, “I’ve seen that in Java, please don’t!”. These times, I already had almost 10 years of experience in PHP and Python. I’ve seen too many bad things already there. I remember all these “Eight-thousanders” (methods with +8k lines of code 😉) and applications that nobody wanted to maintain.

When to avoid DRY in Go

When to avoid DRY in Go

  • Avatar
    Miłosz Smółka

In case you’re here for the first time, this post is the next in our Business Applications in Go series. Previously, we introduced Wild Workouts, our example application built in a modern way with some subtle anti-patterns. We added them on purpose to present common pitfalls and tips on how to avoid them. In this post, we begin refactoring of Wild Workouts.

You should not build your own authentication

You should not build your own authentication

  • Avatar
    Robert Laszczak

Welcome in the third and last article covering how to build “Too Modern Go application”. But don’t worry. It doesn’t mean that we are done with showing you how to build applications that are easy to develop, maintain, and fun to work with in the long term. It’s actually just the beginning of a bigger series! We intentionally built the current version of the application to make it hard to maintain and develop in the future.

Robust gRPC communication on Google Cloud Run (but not only!)

Robust gRPC communication on Google Cloud Run (but not only!)

  • Avatar
    Robert Laszczak

Welcome in the third article form the series covering how to build business-oriented applications in Go! In this series, we want to show you how to build applications that are easy to develop, maintain, and fun to work in the long term. In this week’s article I will describe how you can build robust, internal communication between your services using gRPC.

A complete Terraform setup of a serverless application on Google Cloud Run and Firebase

A complete Terraform setup of a serverless application on Google Cloud Run and Firebase

  • Avatar
    Miłosz Smółka

In the previous post, Robert introduced Wild Workouts, our example serverless application. Every week or two, we will release new articles related to this project, focusing on creating business-oriented applications in Go. In this post, I continue where Robert left off and describe the infrastructure setup. We picked Google Cloud Platform (GCP) as the provider of all infrastructure parts of the project.

Building a serverless application with Go, Google Cloud Run and Firebase

Building a serverless application with Go, Google Cloud Run and Firebase

  • Avatar
    Robert Laszczak

Welcome to the first article from the series covering how to build business-oriented applications in Go! In this series, we want to show you how to build applications that are easy to develop, maintain, and fun to work with in the long term. The idea of this series is to not focus too much on infrastructure and implementation details. But we need to have some base on which we can build later.

Creating local Go dev environment with Docker and live code reloading

Creating local Go dev environment with Docker and live code reloading

  • Avatar
    Miłosz Smółka

This post is a quick how-to for starting a new project in Go. It features: Hot code reloading Running multiple Docker containers with Docker Compose Using Go Modules for managing dependencies It’s best to show the above working together with an example project. We’re going to set up two separate services communicating with messages over NATS. The first one will receive messages on an HTTP endpoint and then publish them to a NATS topic.

Keeping common scripts in GitLab CI

Keeping common scripts in GitLab CI

  • Avatar
    Miłosz Smółka

With this post, I’d like to start a series of CI-related tips, targeted mostly at GitLab, since that’s my go-to tool for things CI/CD-related. I’m sure most of them could be easily applied to other CI systems, though. While GitLab does a great job at many things (repository hosting and related stuff, like MRs, pipelines, issue boards, etc.), it sometimes lacks more specialized features in some areas.

Go + Domain-Driven Design

Build robust, scalable applications. Level up your architecture skills.

Go Backend Masterclass

Learn Go for practical backend development with real-world applications.

Go Event-Driven

Go Event-Driven

Learn building Extremely Scalable & Resilient Go backend.

Go In One Evening

Go In One Evening

Learn one of the hottest programming languages in a fun and engaging way.

Go Microservices

Did you try to use microservices and ended up with even a bigger mess than before? It’s not your fault. Microservices aren’t simple.

Go With The Domain

Go With The Domain

Examples are great for learning, so we decided to create a real, open-source, and deployable web application that would help us show the patterns. All chapters follow the same project, refactored over time.

Series
  • Building in public ( 2 )
  • Essays ( 1 )
  • Live podcast ( 9 )
  • Modern Business Software in Go ( 14 )
  • Watermill release post ( 6 )
Popular articles
  • The Go libraries that never failed us: 22 libraries you need to know
  • Safer Enums in Go
  • Common Anti-Patterns in Go Web Applications
  • How to implement Clean Architecture in Go (Golang)
  • The Repository pattern in Go: a painless way to simplify your service logic
  • Introduction to DDD Lite: When microservices in Go are not enough
Tags
  • go
  • golang
  • watermill
  • ddd
  • clean-architecture
  • domain-driven design
  • events
  • web-applications
  • anti-patterns
  • event-driven
  • ci
  • firestore
  • software-development
  • architecture
  • cloudrun
  • gcloud
  • googlecloud
  • serverless
  • testing
  • advanced
  • databases
  • devops
  • firebase
  • gitlab
  • microservices
  • reactive
  • repository
  • backend
  • basics
  • building-business-applications
  • building-in-public
  • cqrs
  • frameworks
  • kafka
  • mysql
  • nats
  • pipelines
  • scalability
  • software-architecture
  • transactions
  • amqp
  • authentication
  • balance
  • bounded-context
  • c4
  • cicd
  • code-quality
  • code-review
  • design-patterns
  • diagrams
  • docker
  • dry
  • e-book
  • efficiency
  • enums
  • event-storming
  • gamedev
  • generics
  • google-cloud
  • grpc
  • htmx
  • intermediate
  • iteration
  • javascript
  • learning
  • libraries
  • maintainability
  • metrics
  • monolith
  • open-source
  • openapi
  • over-engineering
  • overengineering
  • parallelism
  • productivity
  • programming-languages
  • prometheus
  • pull-requests
  • python
  • rabbitmq
  • retrospective
  • security
  • sql
  • sse
  • startups
  • strategic-ddd
  • swagger
  • terraform
  • tips
  • unpopular-opinions
  • versioning
Three Dots Labs Three Dots Labs
  • Contact
  • Privacy Policy
  • About us

© Three Dots Labs 2014 — 2025

We are a bootstrapped company. By supporting us, you support independent creators.

We use cookies!

Hi, this website uses essential cookies to ensure its proper operation and tracking cookies to understand how you interact with it.

Cookie preferences

Cookie usage 📢
I use cookies to ensure the basic functionalities of the website and to enhance your online experience. You can choose for each category to opt-in/out whenever you want. For more details relative to cookies and other sensitive data, please read the full privacy policy.
These cookies are essential for the proper functioning of my website. Without these cookies, the website would not work properly
These cookies collect information about how you use the website, which pages you visited and which links you clicked on. All of the data is anonymized and cannot be used to identify you
More information
For any queries in relation to our policy on cookies and your choices, please contact us.