When I started at Babbel earlier this year, I was struck by how many great ideas the engineering department here had and how they saw their technology evolving. In fact, in my first week, a compelling document was shared with me outlining the engineering strategy. When we attempted to put the strategy into action, we encountered many problems:
- Prioritizing tasks related to the engineering strategy proved difficult because we had no way to judge their importance
- Tasks were often started but not finished because there was a lack of time and urgency
When we retrospected on what was done – and not done – we realized something that should have been obvious to us: the strategy wasn’t really a strategy at all. A strategy enables you to make decisions. This was rather a list of tasks.
There was no overarching vision of the future guiding us. We had no sense of mission.
Vision & Mission
We started by reflecting on our values. What do we want to be as an organization? Where do we want to position ourselves? What makes an engineering organization work well and how do we want to foster that? After weeks of introspection, brainstorming, and several rounds of feedback, we finalized our vision as follows:
Anyone anywhere at anytime can use our products to learn languages
By anyone, we make accessibility a priority. By anywhere, we give the mobile app priority as well as ensuring our products work just as well in America as they do in Asia. By anytime, we ensure that our systems are running as optimally as possible at all times, are performant, and that we deliver frequently.
As our mission to enable this vision, we outlined 5 key topics:
Living customer centricity
We make customers our first priority – be they external users of our products or internal stakeholders. We will be responsive to their needs and aim to provide a good customer experience.
We prefer delivering incremental value over successive iterations rather than big bang approaches. We aim to have short lead times and to release anytime.
Fostering autonomous teams
Our teams have end-to-end responsibility over what they do. They are empowered to make decisions that affect them and have the accountability that goes with it.
Building scalable products
We build systems that minimize dependencies while maximizing extensibility. We aim to create an ecosystem of services that allows us to grow easily.
Having a great place to work
We have a fun, energetic, creative environment where people are respected and that has an honest and approachable leadership team. We aim to provide engineers opportunities to grow and develop in their career.
Now that we had a view of the world we wanted to create and a view of how to get there, what then? How do we meaningfully execute on these ideas? How do we go from thought to action?
We realized we needed to change who we are.
We decided to start with our engineering teams since the engineering team is the fundamental organizational unit for our department. We developed a set of principles for organizing our teams.
- Be stable, long-lived, and autonomous
- Have end-to-end responsibility
- Be cross-functional consisting of:
- 1 engineering manager
- 1 product manager
- A mix of core team members (no more than 6) and complementary team members
- Have 2-3x redundancy for each critical role (e.g. frontend engineers on a user-facing product)
- By core team members, we mean team members that are fully dedicated to the team and report to the engineering manager. There should be no more than 6 core team members per team in order to maintain focus and cohesion. By complementary team members, we mean team members that are partially dedicated to the team for a specific period of time and support its efforts. They may report to different line managers. For example, a designer, business analyst, or didactics expert can be a complementary team member.
Inherent in our concept of autonomous teams having end-to-end responsibility is the idea of ownership. We felt strongly that teams should “own” their work and drive it accordingly. But what do we mean by “own”? To deconstruct this idea more formally, we introduced responsibility and authority. In order for ownership to work, teams need to have not just a clear understanding of their accountabilities but also a clear understanding of how they are empowered to deliver on those accountabilities.
For us, ownership means the following:
You have the RESPONSIBILITY to:
- Turn product requirements into working software
- Deliver high quality (correctness, reliability, integrity, security, performance)
- Operate, monitor, and maintain your product(s)
- Contribute to the department and company (especially when you are a dependency)
You have the AUTHORITY to:
- Choose and improve your way of working
- Make informed decisions about tools & technology
- Clean up technical debt
- Challenge when something is unclear, unfeasible, or disadvantageous
Traditionally, when one thinks of engineering teams, one thinks of component teams. These are teams that own a software component – be it an application or service – that they are responsible for updating, deploying, and maintaining. Features requiring cross-component updates often entail the need for strong alignment between these component teams. When you have multiple such features, alignment creates costly overhead. Furthermore, component teams tend to feel disconnected from the overall feature because they lack end-to-end impact. They feel like cogs in the wheel.
To activate team autonomy and end-to-end responsibility, we introduced the concept of feature teams. A feature team is a long-lived, cross-functional team that designs, implements, and operates end-to-end customer features. In practice, feature teams are able to work across multiple components allowing them to take the feature from beginning to end. Rather than feeling like cogs in the wheel, they have end-to-end responsibility and are invested in the successful delivery of the feature. In their day-to-day work, they experience the value they are creating for the customer first hand.
To operationalize the feature team concept, we introduced Innersourcing. Innersourcing essentially applies the practices of open-source software development to an organization. It requires that the ownership is clearly defined in a maintainers and a contributors file, that appropriate tests are created to ensure the stability of the product, and that proper documentation exists to guide any team to run and test the codebase. Once these are in place, a team wishing to make a change in a code repository owned by another team need only clone it and create a pull request. The owning team can then review the pull request, request changes, and ultimately merge and deploy the change.
With component teams, you have to align the teams in such a way that they deliver the right thing at the right time. With feature teams, you can use Innersourcing to allow teams to deliver value on their own. Understandably, due to limitations in skill set and overall knowledge of system architecture, Innersourcing does not necessarily preclude the need for alignment in some cases. Also code ownership does not simply go away with feature teams but rather becomes redefined. Documentation, testing, and a stable release process come to the fore. Thus, in the end, the feature team has two functions: one operational, the other strategic.
As we developed this concept, a major problem arose. The concept of end-to-end responsibility works in different ways for different teams. For a product team, it is quite clear. End-to-end responsibility easily applies to features. Nevertheless, there are teams that do not necessarily follow this model. For example, the infrastructure and payment teams, which are teams that have business critical components or components upon which there are many low-level dependencies. The scope and impact of these teams would make sharing operational tasks difficult because different access rights and security concerns come into play.
We realized there is case for service teams.
We therefore made a conscious decision to divide the engineering organization into product and platform teams. While product teams work on implementing features, platform teams are service teams that own non-customer-facing, integratable, and business critical components that serve multiple teams. Among these are our cloud infrastructure hosted on AWS, our payment systems, and our user account management systems. This makes it possible to have governance and auditability around critical aspects of our ecosystem while allowing the rest to innovate rapidly.
Back to Strategy
We have recently introduced these concepts and are now aligning our teams along these principles. These kinds of changes rarely work in a day; it takes time to realize them. With our vision & mission to guide us, we will also start planning our 2019 engineering strategy. We have a lot of great ideas and not enough time to do them all, but now we can effectively prioritize them and make decisions about what to do – and what not to do.