Some time ago I wrote about how we think about the tech lead role and why we don’t have a dedicated tech lead, but instead share the responsibilities of this role.

This post is about more concrete examples of how we actually do this. The structure of this is borrowed from “Good Tech Lead, Bad Tech Lead” and “No Tech Lead”. Both articles influenced my thinking about the tech lead role and the previous blog post in many ways, but the examples they use are a bit too generic in my opinion. This applies especially to “No Tech Lead” which influenced me most. I hope to fix this for other readers.

So, each of the following sections provides examples which explain how we share a responsibility. As we are a relatively young team and we are still in the process of learning how to share the role, I’ll give examples only for a subset of the tech lead responsibilities as mentioned by the articles.


The vaamo application is built using functional programming, CQRS, DDD and Event Sourcing. These are hot topics in certain areas of the industry and new to most of the software developers out there including us when we started working for vaamo. There were and still are many challenges. Especially in the beginning when we had no practical experience with Event Sourcing, CQRS and DDD. We discussed how to test the application and what types of tests we want, found a way to track long running processes and how to source a domain model from events. In some cases the first approach we came up with needed to be adapted to better fit the evolving requirements. In other cases we failed and needed to think about another solution to replace the existing.

This was how we learned about all these new technologies and found our way to apply them. We still do it like this but as the product is now much more stable, at least replacing an approach entirely is less likely to be necessary. However, it is crucial to be very positive about this way of learning. Everyone must accept that it is ok to fail, because this is what happens when you are in the process of learning something new.


Sometimes it is critical to get a change into production faster than initially thought possible. Rather than give up our values and lower our quality standards under those hectic circumstances, we try to find pragmatic and smaller solutions, which might only be sufficient for a limited time and a limited number of users. We take care to change these shortcuts once they are not enough anymore. This approach is much like what Martin Fowler described as Sacrificial Architecture.

This is also the way we implement new features. Often you don’t need that super-scalable and full-blown implementation of a feature. So, we strive for an implementation which satisfies the current needs of our customers. In the very early phase of our product this meant sending notifications via email was to be preferred over a Web API for in app notifications.

In discussions where we make those decisions it is therefore crucial for each of us to have a positive and productive attitude towards each other and our work. This is especially important as people in the field of software development tend to be quite opinionated about their work and often feel that taking shortcuts equals a low quality of the outcome, which of course is not necessarily a correct assumption.

Discussion and Debate

We openly discuss questions that come up during day to day implementation and the approaches for solving them. How do we implement long running transactions in a message-driven system? How to approach UI testing? Should we use a tool to check code style automatically and fail the build when there are violations? These questions for example, to name only a few, were discussed in the past. During a weekly meeting the whole team finds answers to questions like these and decides how to proceed.

We use a Kanban board to manage all the topics to be discussed and to limit the number we take care of at the same time. But, we not only discuss technical topics with this board. Rather we also challenge and evolve our standards by way of this board. In line with our shared responsibilities, everyone can and should put new topics on the agenda, prepare and moderate the discussion around their topics.


During meetings and discussions it’s very important to us to be empathic and really listen to what everybody else is saying. We’re always trying to view the product or current topic from a colleague’s perspective and take that into account. This ensures we usually don’t waste time talking at cross purposes and instead find answers and make decisions that are supported by everyone on the team.

There’s More

While there are more responsibilities to a tech lead role the above mentioned ones are currently the most important responsibilities for us, where we established a shared ownership already.
Others, such as facilitating meetings or providing input for product management, aren’t yet fully owned by the team. But we hope to change this in the future.