
NO SILVER BULLET
Based on nearly 20 years of working together on various projects, we discuss when it makes sense to move fast rather than aim for perfect code, and how to avoid technical debt that can kill your project.
We focus on making mindful engineering decisions instead of blindly following rules like “always do X” or “never do Y”. Different situations need different approaches to code quality.
Latest episodes

Jul 3, 2025 • 1h 22min
AMA #1: Go and AI, Clean Architecture, Learning, Event-Driven
Discover how Go is revolutionizing AI development with its concurrency advantages. Learn about Clean Architecture and the philosophy of adding complexity only when necessary. Explore the ease of career transitions within tech and the importance of internal relationships. Dive into Go's duck typing for defining interfaces that enhance code quality. Understand best practices for managing timeouts in distributed systems. Plus, get insights on the evolving landscape of programming languages and the role of high-level knowledge in career advancement.

Jun 26, 2025 • 1h 28min
How to Create PRs That Get Merged The Same Day
Discover how to transform your pull request process for quick merges! Learn why smaller PRs are essential to avoid review bottlenecks. Unearth the hidden benefits of knowledge sharing during code reviews. Explore practical strategies for breaking down features into manageable pieces for efficient team collaboration. Plus, find out the significance of self-reviewing and fostering a culture that values timely feedback. Say goodbye to lengthy waits and hello to smoother code integration!

Jun 5, 2025 • 1h 25min
Event Driven Architecture: The Hard Parts
Event-driven architecture (EDA) offers scalability, but it’s fraught with challenges. The importance of observability can't be overstated, as debugging without proper tracing is a nightmare. Beware of over-engineering; sometimes a simple synchronous system may suffice. The outbox pattern emerges as a pragmatic solution for data consistency. Designing events carefully is crucial, balancing between specificity and complexity, while robust error handling ensures reliability. The discussion dives deep into managing complexities like message ordering and unprocessable messages.

May 29, 2025 • 1h 27min
Synchronous vs Asynchronous Architecture
Dive into the fascinating debate between synchronous and asynchronous architecture! Discover why synchronous methods are easier for beginners, while asynchronous options boost scalability and resilience. Learn about the power of message brokers for decoupling systems and enhancing error handling. Explore the complexities of observability in asynchronous environments and the importance of effective design. Plus, get insights on mastering CQRS, simplifying messaging for beginners, and balancing architectural choices to optimize your systems!

May 15, 2025 • 1h 4min
Watermill: from a hobby project to 8k stars on GitHub
Discover how a side project turned into an open-source success as Watermill gathers 8,000 GitHub stars. Learn why solving real problems is key to project growth and how minimal breaking changes build trust with users. The importance of community engagement and effective promotional strategies, like conferences and blog posts, is emphasized. Also, explore the vital role of real-world examples in documentation and how patience is essential for achieving recognition in the open-source space.

4 snips
May 1, 2025 • 1h 34min
Unpopular opinions about Go
In this discussion, simplicity in Go is scrutinized, revealing that complex applications demand thoughtful design patterns. The hosts argue that reading the standard library can mislead beginners, and prefer using router libraries for better functionality. They debate the merits of struct-based configuration over the optional pattern, advocating for clear documentation. The conversation also challenges the excessive use of channels and goroutines, emphasizing that concurrency should be applied judiciously. Finally, they explore the practicalities surrounding generics and error handling, highlighting key misconceptions.

9 snips
Apr 17, 2025 • 1h 27min
Learning Software Skills fast: what worked for us best in the last 15 years
Dive into the art of rapid software learning! Discover why practical experience beats theoretical knowledge every time. Embrace the frustrations that come with tackling real projects, as they're crucial for growth. Learn the importance of timeless skills over fleeting trends and explore the power of mentorship. The speakers also discuss how AI is reshaping education and emphasize the value of writing in tech. Tune in for insights on balancing theory and practice while navigating the complexities of software engineering!

Apr 3, 2025 • 2h 2min
Is Clean Architecture Overengineering?
The discussion reveals the contentious nature of Clean Architecture, weighing its benefits against concerns of overengineering. It highlights the crucial role of separating domain logic from implementation details for maintainable code. The hosts share insights on the importance of understanding the rationale behind architectural choices and the common pitfalls developers face. Personal anecdotes illustrate the flexibility needed in implementation, while the evolution of team dynamics and project complexity is emphasized to tailor solutions effectively.

Apr 3, 2025 • 1h 38min
When you shouldn’t use frameworks in Go
Quick takeawaysFrameworks 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.Choose your approach based on project size and maturity - frameworks might work for prototypes, while modular libraries are better for long-term projects.IntroductionIn this episode of the No Silver Bullet podcast, we discuss frameworks in Go and when they're useful or problematic.We talk about why the Go community generally avoids frameworks compared to other languages, and how small, modular libraries are often preferred in Go development.We share our experiences with frameworks across different projects, including tradeoffs between productivity and long-term maintenance.NotesModel-View-Controller (MVC): Pattern first described in the 1970s for Smalltalk, still widely used today.Unix Philosophy: https://en.wikipedia.org/wiki/Unix_philosophy: design concept created by Ken Thompson (also a Go creator) promoting small programs that do one thing well and work together.When to avoid DRY in Go: https://threedots.tech/post/things-to-know-about-dry/Watermill: https://watermill.io: Our event-driven library for Go designed to not be a framework.Repository Pattern: https://threedots.tech/post/repository-pattern-in-go/: Our blog post that is still relevant and frequently referenced.tdl: https://github.com/ThreeDotsLabs/cli and pq: https://github.com/ThreeDotsLabs/watermill/tree/master/tools/pq - the CLI tools we mentioned.Clean Architecture: https://threedots.tech/post/introducing-clean-architecture/: The topic of our next podcast episode, a design approach that helps maintain separation of concerns.Wild Workouts: https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example : Our example Go codebase demonstrating clean architecture. The Best Go framework: no framework?: https://threedots.tech/post/best-go-framework/QuotesThe happy path is easy enough, but the happy path is usually not the hard part of software. We often overvalue how much effort the boilerplate requires. - MiłoszFramework knowledge tends to become out of date. You can spend days or weeks learning something about a framework, but it can be outdated. And if you switch to another programming language or company, a lot of effort that you spent to learn stuff will be just wasted. - RobertIt's more important to learn even-driven architecture because you learn the theory behind it and how it works in general - it transfers better to whatever you will do later. Focus on timeless skills like how to split modules in your application, how to make it decoupled, how to write business logic so it's easy to read and modify. - MiłoszThe Go language is heavily influenced by Unix philosophy - write programs that do one thing and do it well, write programs that work together. It's visible in Go's standard library. This is why Go promotes building independent components that you can connect together. - RobertYou need to be careful not to go too far with foundations. It's better to start with some modular libraries, have some reasonable setup in place, but don't go too crazy with it. Most of the time you'll need to refactor the project anyway, whatever you do, because it can change drastically. - MiłoszOne big decision at the beginning may cost you six months of work later. Understanding if something is tightly coupled to your application is simple - just think about how easy it would be to remove it. - RobertFull episode notes: https://threedots.tech/episode/when-you-should-not-use-frameworks/

Apr 3, 2025 • 1h 47min
When it’s worth to write low-quality code
Quick TakeawaysHigh-quality code is mainly about keeping good iteration speed over time - can you add features without breaking what works?Not all code needs to be high quality - focus your efforts on the code that's most important, changes often, or creates the most value.The right time to refactor is after you know your product has value, but before technical debt gets too big - make small improvements bit by bit.Architecture decisions need more thought than other code quality factors since they're hardest to change later - ask "how hard would this be to remove?"Balance between MVP and quality depends on your situation - for experiments, cut corners on purpose; for critical systems or enterprise products, focus on quality from the start.IntroductionIn the first episode of No Silver Bullet live podcast, we talk about the balance between writing high-quality code and taking shortcuts.Based on nearly 20 years of working together on various projects, we discuss when it makes sense to move fast rather than aim for perfect code, and how to avoid technical debt that can kill your project.We focus on making mindful engineering decisions instead of blindly following rules like "always do X" or "never do Y".Different situations need different approaches to code quality.Notes"No Silver Bullet": The classic 1986 paper by Fred Brooks that our podcast name references, discussing how there's no single development that will solve all software engineering challenges.Our Learning Platform: /learn: The project we discussed that started as an MVP and was later refactoredArchitecture Patterns:Pareto Principle: The 80/20 rule we mentioned - often 20% of the code creates 80% of the valueFuture Episodes:Development Practices:QuotesQuality is not about some kind of elegance of code because it's just an artificial thing. It's not really helpful for your team if it's pretty. - MiłoszOften you have in the code places that you don't touch often or it's not earning a lot of money... Ask what are the places that we're changing the most often? What are the places that are creating most of the value? - RobertI remember one project when we started applying Domain-Driven Design... Everyone loved it in the team... But what I also remember is that it had no paying users and we had to shut it down. - MiłoszIf you did your dirty POC, don't miss the time when you should clean it up, because it's easy to go into a spot where it's no longer possible to do that. - RobertAfter working with [legacy systems] for long enough, you might think, 'I've had enough of this, I won't allow my next project to rot like this one.' It sounds like a good idea, but it can also be a trap. - MiłoszSometimes it can be even the opposite. Having everything super consistent can actually be worse than having inconsistent things, because keeping this consistency requires effort... Sometimes it requires you to use an approach that is not optimal just because 'we're doing it consistently.' - RobertA useful mental model here is to care about the useful product first, not the technical design, which of course is important, but I think it's easy to overvalue it. - MiłoszTry to find some places where you can do refactoring in one week... Often you don't need to rewrite an entire service. You can just do some refactoring in the code and iterate on that. - RobertEpisode notes and summary: https://threedots.tech/episode/when-to-write-low-quality-code/