Anarchists, Mercenaries, Farmers, and Ranchers: Engineering Teams at Startups

Dan C. Reich
Remesh Engineering Blog
10 min readMay 18, 2020

--

Software development has changed pretty significantly in the past twenty years. Whereas in the past we could lock a lone engineer in a room and expect them to come out in a few months with a completed “thing”, this is completely alien to our current day-to-day experiences. Modern software development is complex enough that it prohibits entire systems (or even portions of systems) from existing in the heads of individuals. Today, software development involves coordinating teams of engineers with varying specializations, skill sets, mental models, and levels of experience to more or less simultaneously contribute to a singular thing. This is extremely hard.

As Remesh has grown, our engineering and product organizations have changed in such a way that has necessitated constantly re-evaluating exactly how we coordinate our engineers. It occurred to me that we often take for granted the structures we use to provide inherent organization in order to get things done. So, I decided to catalog some of the team structures we’ve tried, why I think they failed or succeeded, and what we’re doing now.

Anarchists

In my experience, the vast majority of startup engineering organizations begin from anarchy. When I first joined Remesh, we had six engineers and no real team organization. While each of us had our specializations, we usually just did whatever needed to be done. At the time, this was incredibly effective.

When teams are small and the goals of the business are both clear and coupled tightly to the goals of the engineering organization (e.g. “we need to build a thing to sell”), getting things done as an Anarchist engineering organization is highly efficient. Because the team and business are generally small, engineering leaders know the skills of every engineer and simultaneously understand how business problems convert to engineering problems. This makes the mapping between individual engineers and tasks very straightforward. Further, because the team and business goals actually can live in one or two engineering leaders’ heads, there’s very little communication overhead required to coordinate work. Typically one or two leaders will “recruit” engineers from the greater pool to focus on problems. However, that’s not to say no thought should go into assigning work — this type of organization typically doesn’t last long if the organization is growing and decisions at this stage greatly influence the shape of teams to come.

Some things to keep in mind: are your engineers consistently repeating the same types of technical tasks? Are they returning the same parts of the codebase? Are they constantly jumping between different types and areas of work? Affirmative answers to these questions could suggest the organization is leaning towards team structures focused on technical specialties or a product-area focus. For some of our engineers, this wound up being true. Early on, the engineers that began to shift focus towards our machine learning systems self-organized into an R&D team — focused specifically on maintaining and developing our machine learning components. The rest of the engineers became what I call “Mercenaries”.

Mercenaries

Mercenary teams are another common structure I’ve observed in nascent organizations. Mercenary teams typically are very cross-functional with skillset representations across the stack and usually include designers and some form of product management. These autonomous teams usually have no specific mandate except to “build things”. Where leaders in the Anarchist structure pick engineers from the pool, leaders in the Mercenary structure pick projects from a greater pool of work that needs to be done. Sometimes this work is product-specific — “build out a payments portal” — while other times it’s technically focused — “scale our core API to handle 3x traffic volume”.

Some advantages to mercenary organizations are inherent in their structure. The cross-functional nature of the teams means they can tackle nearly any problem and build nearly any type of feature. Often this results in all engineers on the team gaining strong general skill sets, as even though engineers may be categorized as “frontend” or “backend”, their close collaboration with their team members often encourages skill-transfer between roles. For example, building out a payments portal requires frontend and backend engineers to negotiate regarding API structure and payloads. Further, because these teams are typically focused around solving a series of holistic “problems”, teams can build up a very strong understanding of the product or business as a whole.

Some pitfalls with mercenary teams are an inherent lack of product focus. Moving from problem to problem helps develop a good general understanding of the codebase as whole but prevents teams from gaining expertise within any particular aspect of the system. Further, because these teams aren’t tied to particular product areas or pieces of the codebase, coordinating multiple mercenary organizations requires fairly direct top-down management by leaders with in-depth knowledge of the code. Great care must be taken to manage cross-team dependencies, as the free-floating nature of these teams means dependencies from one cycle to the next are often unpredictable. Additionally, code style and conventions should be uniform and strong across the engineering organization — as teams will frequently visit and modify code created and modified by other teams.

While our R&D team at Remesh was coalescing, the rest of us self-organized in a semi-official Mercenary team, working with designers and a product manager. We tackled different problems across the product and all of our engineers gained a strong understanding of the product. However, for us, and I’d argue for most teams of this type, the Mercenary underpinnings are not built to last. Often these teams split along technical lines — frontend and backend, for example. In our case, as we added more engineers, our single mercenary team split into two teams focused on, and limited to, specific areas of the product, what I call Farmer teams.

Farmers

Farmer teams are probably the most common team structure. Farmers primarily “tend” to their specific areas of a product or codebase. I call them Farmer teams because they tend to operate independently within their product-area of expertise (their “farms”) and rarely coordinate on a multi-team level. While they may expose functions or even an API to other teams, the boundary lines are often very clear. Engineers in these teams are usually cross-functional but may have unevenly distributed skill sets as is relevant to the team’s focus. For example, I’ve seen teams where the sole focus is to develop “widgets” that draw from an existing API. These teams typically are very frontend heavy with maybe one backend engineer. At Remesh we had a “Live” team, whose focus was the live conversation experience. This team was slightly oriented towards a backend focus given the performance and scalability needs for this aspect of the product.

Farmer teams tend to get to know specific areas of the codebase very well. They revisit their own code often and — ideally — tend to refactor their “territory” as the product and technical needs change. Because Farmer teams are focused on specific aspects of the product, they typically can build out roadmaps well into the future. Where mercenary teams may never know the nature of their next task at any given time, engineers on Farmer teams tend to know what they’ll be working on to some extent well into the future. While this helps leaders see ahead and coordinate teams more effectively this inherently comes with its own pitfalls.

The major downside to Farmer teams is that the efficiency of the team is directly related to the team’s product focus. In some cases choosing a team’s focus is easy, but in many cases it’s deceptively hard. Choosing the wrong product focus can be a death sentence for collaboration and productivity, causing increasingly high overhead for coordination and communication. For example, when we shifted into Farmer teams, we had one team focus on the pre-conversation experience and another team focus on the live conversation experience. On the surface, the separation makes sense. The pre-conversation experience is focused on setup, customization, and planning for live conversations. The performance requirements are fairly low, and as such the team can be slightly more frontend oriented. The live conversations experience has high performance constraints, changes less often from a UI perspective, and thus, can lean more towards a backend focus.

One problem we discovered almost immediately was that the live conversation team suffered from downstream effects of the pre-conversation team’s decisions. If a feature is intended to be used in both contexts, while one team builds the initial component, the other team inherits code that is ill-suited from the perspective of both team specialization and performance requirements. Highly optimized code that’s hard to work with is not ideal when building features that rely on customization and configuration. Vice-versa, inefficient and over-generalized code is incredibly difficult to optimize.

Sometimes this problem is solved from a technical perspective. I have seen organizations adopt a micro-services or service-oriented architecture to solve these issues. If you constrain the teams such that they are forced to define their dependencies in, for example, an API interface, the boundaries become clear. Honestly, this feels a little backwards to me, but I understand the appeal — it’s a way to translate organizational complexity into technical complexity, which is inherently a more well defined problem. In fact, I think hypothetically splitting a codebase into micro-services like this is a good exercise to reveal any obscured structural dependencies within your application. But in practice, I think it’s a mistake to assume technical architecture decisions will solve your organization’s communication problems. While this may help identify more appropriate team splits, don’t make the assumption that you’ve automatically reduced coordination and communication overhead.

At the end of the day, building complex and interrelated features when teams are not focused on independent and isolated product areas requires very close collaboration between teams and some degree of foresight from leaders. The separate teams need to practically be in lock-step from the perspective of conventions, dependencies, and communication. Why is coordinating teams like this so hard?

The answer generally depends on the details of your product, technology, or organization. But most of the time, it’s because you’ve split the teams along arbitrary product lines — this is exactly what we did. Though our live conversation experience seems completely separated from our pre-conversation experience, the entire point of our pre-conversation experience is to be prepared for a live conversation. Even from a product perspective, if both teams are independently focused on delivering the best pre-conversation or live experience, the resulting product will be less than the sum of its parts. The answer for us, was to throw away arbitrary product divisions and align our teams along tangible user-focused goals. I call them Rancher teams.

Ranchers

Rancher teams are focused on a single core mission, which they drive through different parts of the application and codebase. Missions should be broad enough such that teams can make an impact across the entire product and can follow features through various product areas, but specific enough that it should not cover all aspects of your product. The focus of a team should be clear and every project should relate to the mission. For example, one of our team’s missions is to improve our users’ ability to realize value from the conversations they have on our platform. This goal is broad enough that it can cover any part of our application, yet specific enough that it is easy to express what a team is working on and why.

Rancher teams are typically cross-functional and include a relatively even distribution of skill sets. Because these teams can operate anywhere in the codebase, they must be prepared to do so. These teams will often need to regularly evaluate unfamiliar parts of the codebase to do things like estimation and problem decomposition, so they are most effective when they collaborate regularly in product processes, getting a head start in discovery for future projects.

One advantage with teams like this is that engineers have an opportunity to gain familiarity with various parts of the application with a focus on contexts that are relevant to users. Understanding a codebase from the perspective of users helps provide context to make better technical trade-offs, expedites troubleshooting and incident response, and increases collaboration with product teams. Additionally, due to the highly cross-functional nature of these teams, engineers will tend to gain general skillsets, high familiarity with various parts of the codebase, and learn a significant amount about product development.

One pitfall, especially in startups or startup-like organizations, is that missions are typically tied to problems identified by product or business organizations. This means that if these problems are deemed to be “solved” the focus of a team can pivot wildly, requiring entire teams to onboard to new parts of the application. Depending on the size of your organization and codebase, this may be incredibly challenging.

Further, teams with different missions may still run into dependency issues. However, with straightforward missions and teams that are regularly working within the same codebase, the preexisting familiarity between teams make collaboration and communication more effective — to the extent where teams may be able to identify another team’s dependencies in advance.

We recently experienced this. One team was focusing on reworking the post-conversation analysis tools and conversation export functionality, while another team was building out a feature that allows users to “star” interesting pieces of the conversation. Because the “starring” feature was designed to be incorporated in the live conversation, the conversation analysis, and the conversation export, the previous team was able to identify dependencies and issues in advance. Had one team focused on building “starring” in the live conversation and another in the post-conversation, the feature’s development would have been subject to down-stream dependency effects.

The main advantage of using Rancher teams is that you don’t need to predict the correct boundaries of an application. By allowing your teams to align themselves along user needs, you empower your engineers to gain familiarity with interconnected pieces of the codebase, better understand your users, and identify dependencies early and often.

In Conclusion

Organizing people is hard — especially when you add in the complexities of software. Each team structure has its own inherent advantages and disadvantages. Some organizations may provide environments entirely unsuitable for Farmer teams to thrive and must rely on Mercenaries to move quickly. Other organizations may be small enough that Anarchist teams are the only feasible option. There are no immutable rights and wrongs in perpetuity. In fact, all teams are likely to change over time.

In many cases, Rancher teams may very well morph into Farmer teams as the application becomes more focused and product areas become larger and more independent. And as those grow, they may find Farmer teams need to switch back into Rancher teams, while spinning up a Mercenary team to focus on deep technical tasks.

Admittedly, we didn’t do any of this reorganization mindfully or have these names and evaluations in advance. The ability to classify teams and identify their pain points only really comes from hindsight. That said, simply giving a name to these common structures should help to foster communication about how your teams are structured and whether those structures are beneficial overall. The main point, is not to take the structure of your teams for granted. Regardless of whether your organization contains Mercenaries, Anarchists, Farmers, or Ranchers, your teams have efficiencies, pitfalls, dependencies, and blind spots. Be mindful, consider the implications, and be open to change.

--

--