Besides being a software developer and photographer, I take a deep interest in spaceflight and love reading about the history and development of air- and spacecraft, with a special focus on early space program development.
A few books I've read in the past couple years have gone beyond being interesting just for their historic content—they gave me a lot of ideas to reflect on in relation to my approach to software development, especially what I'd term 'professional' software development (vs. hacking something together for fun, or churning out brochureware sites or cookie-cutter apps).
One book in particular, Failure is Not an Option (by Gene Kranz, famously known for his efforts as director of Mission Control during NASA's early days into the Apollo era), offered some great examples of how a high-performing team should operate, especially under pressure and with high stakes.
Most of the interesting and difficult software engineering that's happening today is on a scale the earliest software developers could only dream of. And yet, if we look at some of the greatest challenges the practitioners of this field encounter... it's not all that different from the past, or from other industries.
The power curve
I hope to explore some other topics in this area in future posts, but today I want to focus on one idea mentioned a few times in Kranz's book, the idea of the power curve.
I had no problems and felt comfortable with the mechanics. But I had a long way to go before I would have that sense of "being ahead of the airplane" or "ahead of the power curve" as pilots put it—having the experience to anticipate what could happen rather than just reacting to what was happening at the moment.
I liken it to the feeling a race car driver gets, knowing the limits of his own body, the machine he's in, the grip of the tires, the stickiness of the tarmac, and the precise power output of his engine—a true professional optimizes for all of these aspects and is able to keep control—but only just barely. He's riding the power curve right up to the edge, but not going too far, lest his race end in a crash.
One of the best modern illustrations of this is rally driver Ken Block. In his latest video, he can be seen playing with and continuously pushing the edge of the limits of his machine, the Hoonicorn V2:
Similarly, I remember the feeling of finally mastering the hockey stop after a hundred crashes into the the wall of an ice rink. Or being able to use countersteer with my dirt bike to perform fast-but-controlled turns with one wheel sliding out from behind. (Both skills, unfortuntely, have long since faded from muscle memory.)
Building software, I sometimes notice a similar feeling—that of being so attuned to a bug, to a new feature in development, or to some performance tuning parameters—that I can in a way anticipate what will happen. And just like with a pilot pulling off a spectacular maneuver at 9 Gs, I feel the adrenaline rush from being one step ahead of my code.
It's not just flow state, though flow state is a prerequisite to this feeling. It's when I hold a complete segment of code or an entire architecture in my internal 'state', and can feel out any of the logical progressions. Instead of having to adjust, run a build, adjust, run a build again, I can quickly explore many scenarios in my head. This is amped up to the extreme when I'm debugging a time-sensitive problem, like a performance issue or outage in production, or during a major load test, pentest, or cutover.
On a deeper level, it's being able to keep an even keel amidst a lot of projects, or amidst personal and work problems. I don't know if there are any genetic, biological, or even emotional reasons for it, but there are times when it's easier to jump in and out of tasks, or to manage multiple competing priorities with aplomb.
The power curve and software teams
The idea of the power curve can be applied to software development teams as well. I've seen development teams mired in a depressing spiral of broken builds, missed deadlines, and technical debt. And I've seen development teams who seem to see the world with rose-colored glasses, delivering on time, delighting stakeholders, under-promising and over-delivering. And they have a great time doing it!
These teams stay ahead of the power curve as a unit. There's a baseline requirement for technical competence in all the roles—project management, development, quality assurance. But you don't need a bunch of 10x developers to build a great team. And it has nothing to do with whether the team is in close physical proximity. I've seen these teams perform in situations where no two people are in the same timezone, and I've seen these teams working together in a cubicle farm.
What are some practical examples of a team that consistently pushes its power curve?
- They use a well-defined but flexible process (e.g. Agile + scrum + some bits of waterfall) to turn business requirements into shipping features, and then have a well-defined workflow for estimating, building, testing, and shipping the features.
- They do not allow work to enter their workflow unless it is part of the above process.
- The PM/architect-level team members act as real-world firewalls, blocking or redirecting requests from outside that don't fit into their project's scope.
- There is no hierarchy (at least, not in the traditional sense). Anyone can and does mention risks, anyone can speak directly with anyone else on the team at any time.
- Egos are (usually) checked at the door. Team members are both humble and open with respect to implementation ideas, delivery promises, and RCAs. (Though members of high-performing teams are usually pretty proud of their individual contributions, it isn't the same kind of stubborn pride that rejects healthy debate.)
- Technical debt is a well-managed asset; new features and optimizations which introduce tech debt are wisely chosen, and there is a plan for maintenance of the debt (rather than letting it spiral out of control).
- Team members don't think in terms of the next week or month, they think in a timeline of years. (This helps especially with tech debt management.)
- Team members don't waste time being architecturenauts—they build small and efficient, but with an eye towards the future. They use spikes or proof-of-concept implementations to tease out major features or changes to critical components before committing to a major body of work.
- They measure past performance and use it as a metric for future work, quickly rejecting requirements that cannot be reliably estimated. Software estimation is hard, but it is not impossible.
- They do not compare their performance metrics to other teams' metrics. They understand that every team is unique and there is no magical comparison metric that can measure inter-team performance (e.g. commit count, lines of code added, lines of code removed, unit or functional test coverage, or bugs reported vs. features added).
- They rarely think about any of the above—at least not consciously. These traits come naturally to the team.
When a team consistently delivers, it can be frustrating to outsiders who have trouble doing the same. Especially since, as a team becomes more cohesive, the power curve is continually stretched, so the team seems deliver better results, faster!
Aside: As someone who has worked with both agency-style short-lived teams and longer single-project teams, one downside to the agency style is that right after discovering their power curve, the team disbands and individuals form other teams. It's hard to strike a balance between breaking up cohesive teams and making individuals feel stuck in a particular project, but agencies have a hard time building high-performing teams when they think of work on a quarterly basis!
I'm not the first person to mention most of these ideas—or probably any of them—but I think the differentiation between professional and amateur/hobbyist developers is the ability to fly by the seat of their pants and push their work and their team right up to the edge of the power curve, but back off and push back on extra work or distractions before they're out of their depth.
Nothing above is meant to be disparaging—you can work as a professional (in the sense of knowing your power curve) for some projects, and a hobbyist for other projects. As an example, I don't often hit flow state or push my limits when I'm fixing bugs on my open source projects. A lot of time, you just have to push through mundane tasks. And even the most high-performing teams aren't always pushing the envelope (even Ken Block stopped at Pike Peak's summit for some R&R at the gift shop!); managing toil and technical debt is usually a challenge no matter what the project.
If you don't feel you've been 'ahead of the power curve', but instead a project is out of control and you're getting depressed about it, you might be aiming a little too high (your power curve might not be quite where you think it is!), or you might be taking on too much work. Just like when a pilot pushes experimental aircraft too high or too fast and loses control, you have to work within your limits, and know when to pull back on the throttle.