Battles and Wars

In software there are battles and there are wars. The battles are the day-to-day—dealing with tech debt, buggy code, flakey build systems, inadequate testing, unreliable stakeholders, vague and changing requirements, overbearing processes, the usual stuff. The wars are the bigger picture—hitting a deadline, delivering a big project, developing strong relationships, shipping product.

There is an infinite stream of battles. Regardless of whether you win, lose or surrender, there will always be more battles to fill your day-to-day. Battles come and go all the time, and they’re always changing. Wars, on the other hand, play out over a much longer timeframe—it takes time for the tides of war to change, and you can’t always choose the wars you fight in.

Teams can win every single battle they face but still lose the war, if they’re fighting the wrong battles. It’s incredibly frustrating, because it feels like you’re kicking arse. You’re hitting all your targets and deadlines, performance reviews are great, the day-to-day is great, but over time it feels like your work doesn’t matter.

It’s worse when you aren’t even winning the battles. A common trap that I see teams fall into is to become swamped by the desire to win all of their current battles, which can actually just force them permamently into defence. Every little piece of tech debt or code smell needs to be fixed, every manual process needs to be automated, every minor issue needs a proper fix instead of a reasonable workaround. As I said, there is an infinite stream of battles, and as soon as one is over there’ll just be more. If you try to fight your way out of every single battle you often just wear yourself out, giving you a perpetual feeling of exhaustion. The same thing can happen if you try to fight too many battles at the same time. You stretch yourself too thin and end up losing everything—the divide-and-conquer defeat.

But you can use the infinite stream of battles to your advantage, because it means there are plenty to choose from. Look for the strategic battles, the high-value problems that give you real leverage, and focus all of your attention on winning those even if it means surrendering other battles. If you win a few of the right battles you can start to shift the momentum of bigger wars, and everything will start to feel easier. The high-value problems are the constraints of the theory of constraints, which when lifted will increase the throughput of the system—in a development team, the throughput is your velocity, or the rate at which work gets completed. Winning battles which aren’t constraints won’t increase throughput, or at least not considerably.

And if you notice yourself getting overly emotional about your work—the exhilarating highs when you get on a roll of productivity, and the crushing lows when you’re ten rabbit holes deep and you seem to only be getting further away from your goal—you’re probably too invested in the battles. Take a step back and make sure you’re winning the war, which is what really matters.