Building software is not a job scheduling optimization problem
by Richard Marmorstein - March 28, 2020
am skeptical of team traditions like “prioritizing the backlog”, “estimating story points”, “ending the sprint”, “prioritizing the roadmap” and such. I am happy to fully commit these rituals when they’re in place – but I’ve always been quite skeptical that any of them actually make software teams more effective. It is important, of course, that teammates to talk to each other and to other teams about the work they are planning and doing, but in almost every case I believe it is better for this to be organic and freeform. My favorite sort of team meeting has an agenda anybody can add items to, and a note-taker transforms the agenda into meeting minutes as each item is discussed.
What are the arguments in favor of these rituals? In the past, I’ve gently challenged colleagues who seem fonder of these rituals than I am, and they provide thesis statements of arguments: “it will help us make sure the right work is prioritized”, “it will help us make our output more predictable”, “it will help us coordinate with stakeholders”; but I have never pressed much further, since I don’t believe protracted, philosophical debates are good for the productivity of software teams either.
Most of the writing I find about the subject is heavy on claims, low on arguments, too. So I’ll use a bit of creativity and try to imagine what good arguments in support these thesis statements would be. This means I may be constructing a bit of a straw man, but at least I’m being forthright about it!
For the sake of this post, let’s call these rituals capital P “Process”.
The “right” work
My straw man first defends Process like this: “it will help us make sure the right work is prioritized”. In my imagination, somebody who makes this argument is probably making two assumptions about software teams:
Building software is like a job scheduling optimization problem. If you have a bunch of homogenous workers taking tasks from a priority queue, you optimize this system if you assign the highest priorities to the tasks with the highest expected net value. A software team can be similarly optimized.
Teams are meaningfully more likely to choose work with higher expected net value when they are looking at a list of tasks, discussing it and tweaking it during a team meeting, organizing it into sprints, epochs, assigning estimates, etc. etc.
In my experience, most of the time when the backlog must be prioritized, every developer – every senior developer anyway – goes into the meeting with a general sense of what they’d like to work on next and inevitably they argue for that work to be prioritized near the top, and it is quite rare for anybody to dissent. This means that Process – grooming the backlog, estimating tasks, etc. is a noop. It has no effect on the work that the team actually ends up executing. There are some scenarios where a developer comes out of a team meeting with a different plan than when they entered it, but almost always this is a consequence of the act of meeting, not of Process per se. For instance, a developer may discover a teammate is stuck and needs a hand, or if there is some urgent task they didn’t already know about that needs to be handled soon, or become convinced by their teammates that they are lost in the weeds and need to abandon their current line of work. But it is rare that these judgements are made on the basis of the order of things in the backlog, or on the number of “story points” that have been assigned to a task, or on any artifact of Process.
If you are a junior developer, or new to the team, you might go into a meeting without a clear sense of what you believe you should do next. But process doesn’t help you here either. If the backlog is prioritized, presumably it is done according to expected net value of the tasks themselves. But you shouldn’t pick tasks according to their objective expected net value – you should pick tasks according to whether or not they are approachable or good learning opportunities for you. When I was joining my latest team, a teammate had put together a list of “good spin-up tasks”, and that is what I tackled. So when choosing my work, I was basically encouraged to ignore the artifacts of my team’s Process until I got spun up.
My thesis here is that a team’s process is largely window dressing. Your backlog, story points, and sprints are mostly just a poor encoding of what the developers on the team were planning on doing anyway. But even if, to some extent, a team’s process does cause it to undertake different work – why should we believe that this difference is an improvement?
The difference between two tasks in terms of expected net value, I claim, is either blatantly obvious, or impossibly hard to determine. It’s clear, for instance, that fixing something that regularly causes complete outages is probably more important than fixing a UI glitch, or that fixing a glitch in the part of the product that the CEO is about to demo is more important than fixing a glitch in the view that only two people use per year. But how do you compare the expected net value of fixing a UI glitch versus working on, say, a project to attribute server costs? Presumably the UI glitch carries some probability that somebody on the margin will see it and this will push them over the edge into a bad enough mood that they will switch to your competitor. And there’s some probability they’ll mock your product on Twitter or something, which might detract even more users. But do you know what those probabilities are, or can you realistically estimate the size of these costs? Almost certainly not. Likewise, how can you judge the importance of the project to attribute server costs? There’s some probability that it will lead to some sort of cost saving down the line, but do you know that probability before you have done the attribution? Can you predict the magnitude of the possible cost savings? Again, almost certainly not.
When the discrepency between the value of tasks is blatantly obvious, as with outages vs glitches, this is when the ordering of tasks as a result of ‘process’ is least likely to diverge from the ordering of tasks that would result from simply meeting. Process is only likely to have an effect when the difference in expected net value of various tasks is the least obvious – that is, it is essentially unknowable, as with server cost attribution vs fixing glitches. And in these cases, any ordering between tasks is a complete guess. And there is simply no reason to believe that a complete guess according to a process, with an ordered backlog, point estimates, sprints, and such, is going to be any better than a complete guess done based on freeform discussion or raw intuition. A complete guess is a complete guess.
So the analogy between a software team and a job engine is a poor one, I think. It is true that a software team executes tasks, and it is true that it executes these tasks in a particular sequence. But it just doesn’t seem likely to me that spending time and attention fiddling with the details of this sequence is a very promising way of becoming more effective as a team.
So what aspects of a team can be meaningfully improved, if not the sequence of tasks that it executes? Things like morale, motivation, momentum, vulnerability, technical ability, familiarity with the codebase. These more human aspects of teamwork have no analogs in the “software team as job engine” metaphor, and it is unlikely that practices like assigning story points, rearranging tasks, taking tasks into and out of sprints, etc. really benefit them.
I’m willing to go much further and suggest that the rituals of Process are actively harmful to the humanity of the team. There will inevitably arise some conflict between what you think you ought to be doing and what your project tracker or Process says you should be doing. Maybe you forgot to ticket something important. Maybe you wanted to fix an additional couple of extra things before you switch out of the context of your previous project. Maybe you were hoping to explore some sort of inkling that isn’t concrete enough yet to be summarized in a ticket. Maybe a question came in from somebody on another team, and that reminded you of something you had intended to do and you want to do it now while that is fresh in your mind and there is immediate motivation. Maybe you’re just not in the right headspace for whatever the tracker says that you should be doing. Maybe you need to adjust for a spotty internet connection, or a broken CI system. Maybe you’ve just had a crazy idea that could change everything, and want to put together a quick proof of concept while you are excited about it. This is the reality of being human – our motivation and our momentum don’t always follow the project tracker.
I’m not suggesting that software developers should follow every whim. That is no way to ship software. Your team has commitments, you have commitments to your team. But motivation comes in waves, and it is good to be able to ride those waves from time to time, instead of constantly swimming against them. An effective team takes advantage of this, by building flexibility into its plans. The humans on your team understand when you ride a wave of motivation and deliver something that is valuable, but wasn’t in the sprint. They might even encourage you and share the excitement about the work that you did. Your Process on the other hand, understands nothing of the sort. The only thing your project tracker gets excited about is if you managed to deliver more “story points” from the sprint than usual.
On a team that emphasizes process, when your judgement of what you ought to do conflicts with the process, you have three choices:
- Obey the process. Want to fix your colleague’s problem now? Nope. Tell them to ticket it. Just had a brilliant idea you want to prove out now? Nope. Ticket it.
This is clearly the correct choice when you’re working on something that is particularly urgent or you know is more important, but to work this way all the time, and constantly be struggling against the flow of your natural curiosity, your inclination to help when asked, etc., all for the sake of sticking to a sequence of tasks that is essentially a complete guess, is a sure recipe for burnout.
Ignore the process. Cast care to the wind. Do what brings you joy. If you’re a bad boy like me, you might even get an extra thrill through doing something you’re not technically “supposed” to be doing. More likely though, what you’ll end up with is a nagging feeling of guilt. Come team meeting time, you’ll feel like you need to apologize or justify yourself, which is not a great mindset for building vulnerability, team spirit, etc.
Manipulate the process. With this approach, whenever you want to do something that disagrees with the project tracker, you simply change the ticket, or add a new ticket to the sprint. This isn’t really materially any different from ignoring the process, but it underscores how, as I claimed earlier, typically a team’s Process is mostly just window dressing – process does not cause teams to operate any better, it is simply a poor encoding of whatever the teammates were planning on doing anyway, with some extra hassle and feelings of guilt added in.
Another defense of process is the claim that it helps make a team’s output predictable. Predictability can apply at either a rough or fine level of granularity, so let’s consider both.
At a rough level of granularity, you might want to be able to approximately predict when your team can finish an ongoing or potential project.
It’s worth asking: what is the value of predictability? Predicting when a project will ship is only valuable sometimes, e.g. when other teams are planning projects that will build upon your project, or if you’re shipping something high profile that will involve marketing and such, or if sales people would like to promise customers that you will deliver something by a certain date. Much of the time – particularly when, in good “agile” fashion, you are shipping small incremental changes to existing products – predicting the ship date has little value. So to the extent you buy in to the agile ideology where projects should be incremental, dependencies between teams should be minimized, and so forth, you should view Process and the necessity of predictability at best as a necessary evil, and should be working to eliminate it.
But does process actually help you predict when projects will finish? Process’s answer to estimating a project is “story points”. Enumerate all the behaviors that must be changed. Break it into small units. Determine how many “story points” each unit of work is. Calculate the “velocity” of the team working on the project. Divide the total number of story points by the velocity. Add a bunch of padding, because otherwise your prediction will never, ever be correct. And then you have your estimate.
There are some good things about this. Enumerating all the behaviors that must change forces you to really think through the project, come up with an implementation plan, and consider threats to the project. This has a couple of problems, though:
“Story points” force you to pretend to be certain how long a task will take and mask the reality that you can be highly uncertain. The single best thing you can do to help your project become predictable is to “derisk” it by frontloading the tasks that are the most uncertain, or tasks that will make them less uncertain. “Story points” are not flexible enough to permit this sort of reasoning, and displace the sort of critical thinking that could take place in say, a freeform text document.
“Story points” commit you to the initial decomposition of the project. You learn a lot once you are a couple of weeks into a project. In my experience, it’s pretty rare to go back through all the stories, fundamentally change them based on what you’ve learned, and give them new estimates. There is much less friction to changing a free-form document, and you are much more likely to revisit your assumptions.
Predicting the whole team
The full vision of “story points” though isn’t just to help you produce better guesses about when a particular project will land. The full vision is that everything your team does will be captured and assigned points. That way, when a new task is imagined, or comes in from an external source, you can quantitatively see how committing to that new task trades off against pending project deadlines.
This vision makes sense if you view software teams as a job scheduling system that can be optimized by choosing the right sequence of tasks. But in reality, as I argued before, whether or not that new task is more important than your ongoing project work is either blatantly obvious or completely unknowable. “The project tracker says doing the security hardening now will delay the project by three weeks, but our team’s judgement is that it’s only worth a delay of two weeks,” said nobody with a straight face.
This vision, where every unit of work a team considers, even exploratory work and research, must be ticketed and assigned an estimate, where developers are asked to justify essentially every moment of their day, is the most confining from the human perspective.
“Coordinate with stakeholders”
The last defense of process I’ve heard is that it helps the team and the team’s leaders better coordinate with stakeholders. I don’t have much new to say here. in addition to my previous analysis about this particular defense, but I will note that stakeholders probably care mostly about the high level of what your team is doing, and that the artifacts of process are probably not optimized for communicating what a team is up to at a high level. It is almost certainly better to communicate this via free-form documents.
Second, as I said when discussing estimating project ship dates – structured coordination with stakeholders matters less when, in good “agile” fashion, you are shipping things in small increments. Stakeholders should be able to talk to your team and give feedback about your product directly and organically. Process is a buffer, here, that should be seen at best as a necessary evil.
Doing planning. Doing project research. Writing documents. Updating people. Constantly rethinking your plans and commitments. These activities are important, but it is critical not to conflate these things with Process. Process, in my experience at least, tends to displace these activities, not encourage them. Every moment you spend worrying about whether you are following the correct process is a moment that you haven’t spent worrying about whether your idea actually makes sense. For that reason, I tend to advocate for lightweight, freeform, unstructured process wherever possible.
You might be interested in my next post, "software culture as proof strategies".
Are you happiest when forward chaining or backward chaining?
Check out the previous post, "beware middleware".
"Use the tools. Don't let the tools use you."