Cooking your Software: Roles vs. Tasks
I moved to Italy a few months after my 19th birthday — I stayed there for almost two years. I moved around a lot, staying in five different apartments and three cities. As a consequence, I had a lot of different roommates — some of them a lot better than others. One particular roommate I had in Turin was an excellent cook.
One day, I had a revelation. I knew that my roommate, while quite passionate about cooking, really hated all the cleanup. In fact, it was pretty clear that he would happily cook (and he always shared what he cooked) more than he already did if he just didn’t have to wash all the dirty dishes afterwards. So I made a bold move. I told him that I was willing to do all the dishes and kitchen cleanup anytime he wanted to cook. He agreed and thus began a marvelous partnership. My roommate happily did all the cooking, and I happily cleaned up afterwards, with a belly that was always warm and satisfied. I never ate so well! And my roommate, equally thrilled, cooked as much as he wanted (it truly was his passion), without ever having to scrub a dish or wipe a counter. Unfortunately, we only shared an apartment for a few more months, but I look back in fondness on those days living in downtown Turin, eating like a king.
After returning home from Italy, I pursued my degree. At the University, I would sometimes get together with a group of people in my apartment complex in the evening and we would cook a meal together. Sometimes we would even pile into a car and drive to the grocery store to do the shopping together. We would wander around the store looking for inspiration until someone would suggest a dish that sounded good to everyone. Some of us would then branch off and try to organize side dishes around the main course. When we got back to the apartments, we pulled out all the cutting boards and pots and pans and got to work. One of us would chop the onions while another would chop the bell peppers. Someone else would start some garlic cooking in a pan with olive oil. In the end, we pulled together a meal and enjoyed each other’s company.
In both of these scenarios I made food, but the situations were quite different. In fact, these two approaches demonstrate two general strategies for dividing labor: by roles and by tasks. In software development, you can divide work in the same way. But when deciding how to divide work on a project, it is crucial to understand the trade-offs of choosing one strategy over the other. The difference may seem subtle or even inconsequential, but it has dramatic effects on the culture of your organization.
When you divide work into separate roles, you assign responsibility over one or more code modules, major features, or broad services like networking libraries or devops. What distinguishes this type of delegation from task delegation is that you transfer broad responsibilities to your workers, with high level requirements, and the smaller tasks are left for workers to determine. The granularity of the deliverable is typically on the order of several months — although the individual is free to release parts of the deliverable whenever they are ready.
Like when I did cleanup for my roommate, details are left up to each individual. My roommate cooked what and how he wanted. I didn’t get involved. I left it all to him. Likewise, he had little interest in how I cleaned up, as long as everything was clean by the time he wanted to cook again.
In software, this type of collaboration is usually coordinated through interfaces. As long as predefined interfaces are fulfilled, there is no need to be involved in the internals of someone else’s code or in the methods by which it is produced.
When dividing labor by tasks, a team designs a product or service as a group. They create a list of tasks and corresponding estimates. This list is referred to as the backlog. Usually, the backlog is maintained (prioritized and ordered) by a product specialist. This strategy is very much in vogue among agile practitioners (scrum, extreme, kanban). Completing the work at this point is a matter of individual engineers taking items off the top of the list. When they finish one, they take then next one, until the list is empty or you run out of time.
This is like my group cooking experiments in college. The overall goal is identified and strategized collectively and then small tasks are partitioned and performed in parallel (chopping onions, chopping carrots, heating oil, chopping garlic).
There are clear benefits and draw-backs to both of these approaches when developing software. Below I outline some of the most important difference between the two.
As these cooking examples demonstrate, there is a clear distinction in quality levels between role based and task based collaboration. When focused on one role (ideally a role that you are passionate about) your mastery and skill increase over time. The autonomy that you hold over your domain allows for experimentation and a high degree of customization in your process. Over time, my roommate in Italy honed his skills and process. He had an order and style that was all his own. His food was consistently excellent.
On the other hand, the group cooking of my college days yielded varied results. Our fragmented vision made it difficult to produce the highest quality results. It wasn’t ever terrible food, but it never reached the heights of what I experienced in Italy.
Something that is important to consider, however, is that group cooking was less likely to descend into major disaster. With many cooks in the kitchen, there was enough oversight to head off a trouble before it was too late. If my roommate in Italy took a culinary wrong turn, he could more easily botch the whole enterprise. Had my roommate been a poor cook, dividing the work by roles would have be an obviously dubious arrangement.
In Software development, the highest quality results also come from skilled engineers partitioned by roles. But there is also more risk involved in dividing work this way, as ill fated attempts can drag on longer and waste more money.
In summary, dividing work by tasks, as most agile methodologies (scrum, kanban, extreme) recommend, is a safe choice that is predictably average. While there is less risk of orchestrating a complete failure, there is also little chance for the most innovative approaches to develop. Ideas are typically watered down or ignored in favor of the vision of more senior or vocal engineers.
Notably, there is supporting evidence for these observations in a recent study of collaboration by Harvard Business School. Researchers observed problem solving abilities of groups at different frequencies of collaboration. They demonstrated that infrequent collaborations (think roles) yielded both the best and the worst problem solutions while frequent collaborations (think tasks) produced consistently average results.
When I did the cleaning and my roommate did the cooking, we both had very clear ownership. He could use the recipes and utensils that he liked. He could cook dishes in whichever order he chose. He could bring them out in any order he liked. He even had control of his environment. He could play music or have silence. He could cook by candle light or with all the lights on. He was totally in charge.
But when it was time for me to clean, it was my time. The environment and process was my business. I had total authority. He was no longer even in the kitchen.
Compare this to cooking as a group. What if I liked a certain recipe but someone else liked a different one? What if I was chopping onions and I want to listen to rock music but my friend wanted to listen to classical music? What if someone else needed silence to concentrate? Everything becomes a group decision and discussion. No one has unilateral authority. The group shares the ownership.
It is hard to argue that anything other than role based collaboration yields tangible ownership. When you code as a group, you may feel an abstract sort of ownership for the product as a whole, but there really isn’t any actionable ownership in play. You can’t make unilateral decisions. You can’t protect your work from clutter or design corruption — anyone can modify the code. You simply don’t own your project or code in any material way. The best that could be said is that you participate in a kind of collective ownership.
A much fuller ownership is enjoyed as a result of role based delegation, because you have complete control over how your particular domain is managed. This has many advantages. For one, it is easier to evaluate individual contributions. It is simply a matter of looking at the artifacts they create, since they are the sole contributor — unlike task based collaboration where everyone contributes. Also, product design is less fragmented, as it is the result of one mind. Most importantly, there is much greater engagement and pride taken in one’s work. After all, it is theirs. It represent the product of their personal vision and effort.
When mentoring is required, group cooking has some clear advantages. If I aspired to be a great cook one day, it would be of no benefit to me to limit myself to cleaning for my roommate. I would have much preferred to help him with the meals. That way he could walk me through all the steps, demonstrate techniques and critique my skills.
Likewise, when all are working at a task level together, less experienced engineers can see all the work in progress and glean important information about the project. They can see more experienced workers in motion and make fast leaps forward in their personal development.
Role based collaboration, because it isolates each worker, makes it hard to spread knowledge to those who are learning. If specific actions are not taken to do training or write documentation, information that lives inside of an engineer’s mind may never be shared with the organization as a whole. Most destructively, it may prove difficult for someone to takeover a role if someone leaves or goes on vacation.
To leverage the most benefit from uninterrupted concentration, it is better to define work by roles. A chef that assumes responsibility over one duty (ex. soups, grilling, frying) can be more immersed in their work while others perform their responsibilities. To contrast, consider a set of chefs that are simply available for any task in the kitchen. One task could be chopping, the next could be to stir the soup, then to tend to the baked deserts. Their attention would be strung between a whole host of activities. Each time they switched they would have to prepare themselves for different action — mentally and physically. This is in addition to any coordination that must take place with the person switching off of the task that you are about to begin.
The pain of context switching is lessened considerably under a role based collaboration structures because one person sticks with one area for the duration of their work. When dividing and sharing work at a task level, context switching is constant and painful. Task are often from differing areas of the code base, or even from different code bases all together. Every task that is pulled from the backlog caries with it tax — the time it takes to understand a new context. Only individuals that has been at a company for a long time, that fully understand context across a broad portion of the product, can move easily from one task to the next.
Imagine that after I cooked with my apartment friends, we wanted to determine who was the most productive member of our group. This poses a significant problem. Since we were all involved at a very minute level, it would be hard to determined who was more diligent or capable. We could use a peer review system, but there is still no measure by which to compare individual contributions, so input would be largely subjective.
If I wanted to rate how my roommate in Italy cooked, it would be very simple. The expectation is very clear — good food — and the person responsible is equally apparent— my roommate. Because of how we divided our work, we could more easily judge each other’s efforts. Likewise, if the kitchen wasn’t clean when my roommate wanted to cook, there would be no place for me to hide. The fault was obviously mine.
Using roles, performance evaluations are more easily performed on the software artifacts and the results of individual effort (service up-time, bug rate, speed of completion, features completed). When everyone works on the same projects and artifacts, as is the case when you collaborate with tasks, such an evaluation is much more difficult. Everyone has their fingers the same pies. Performance evaluations become subjective opinions offered by coworkers. Without metrics or products to consult, you are only left with matters of personal taste and sometimes politics, scapegoating and popularity contests. Such subjective conditions yield a great deal of stress, and can cripple a teams ability to work toward common goals.
Cooking with my apartment friends, we were talking constantly. “Who is slicing the bread?”, “Is the oven preheated?” There was no other way to succeed. But that was kind of the point — the main reason we were cooking together was to talk. It was a social event. This is in stark contrast to my arrangement in Italy. For the most part I left my roommate alone to cook, and he left me alone to clean. In this situation, that was also the point. We had no interest in being involved with each other’s work — we had other things to do.
The need for communication among teams that collaborate at a task level is much higher than with roles. Everyone needs constant updates regarding decisions and directions that affect the team. Teams that are remote or who work different schedules will suffer under this scheme.
Teams that collaborate through roles, however, can limit their communication to areas at the borders of their components. They only need negotiate their interfaces with other collaborators. This lessens the communications needs significantly.
Releasing Early and Often
There is a important point to be made about how often you can release software to production under either of these two schemes. While is may be tempting to think that tasks can be released more frequently, it turns out that either strategy can be leveraged for more frequent releases ( or less frequent if that is your goal). How often you release is more of a decision than a result of how you divide the work. The main difference between the two approaches is that in a task based collaboration scheme the team must be committed to releasing more frequently, while in a role base collaboration scheme an individual needs to make that commitment for their individual project. There is nothing that prevents an individual project owner from dividing their own work into smaller tasks and releasing when they are finished.
Likewise, my roommate could present his dishes as often as he wished, in courses or all at once. The same was true with my apartment friends. The issue of release frequency is orthogonal to how the work is divided.
A major benefit touted by proponents of task level collaboration is the ability to interchange people between different teams, and to suffer minimally when someone leaves. Because everything is divided into tasks, if an engineer leaves the organization, another engineer can take their place with minimal interruption.
While this is true, this arrangement can easily promote a factory mentality of scientific management and interchangeable parts. Any perceive benefit from interchangeability comes at the cost of employee engagement and productivity. Simply put, people that feel like cogs in a machine will participate minimally, and will in fact be more likely to leave. In software, scientific management is especially damaging. Decades of effort to turn software engineers into a commodity have failed time and time again.
Open Source, a hybrid approach
Some attempts at hybrid solutions between these two strategies have had considerable success. Perhaps the most impressive is open source software. With a clear owner/gatekeeper/benevolent dictator for each project, this system is naturally configured like an organization that assigns roles to individuals. How they develop a project is wholly in the owner’s control. However, many people contribute improvements through patches or pull requests. These outside contributions can be accepted or rejected, depending on their merit in the eyes of the owner. These types of contributions add the benefits of task level collaboration. In particular, they add opportunities for mentoring from the project owners. They also make succession planning easier, as the custom is to choose someone that has been a prolific contributor as the person to take over the project when the originator leaves or goes out of town. For more on this read: Three Ways Agile Has Gone Astray.
While it is most common today to divide the work into smaller tasks and put them into team global backlog, this has not always been the case. As recently as fifteen years ago, it was more likely that developers would give each other responsibility areas to own and maintain. When deciding how to manage your organization, an understanding outside of fads or traditions is the best path to organizing your work effectively and deciding between using roles or tasks is one of the most important decisions you’ll make as a leader.