The Developer Feedback Loop
Editorial Note: I originally wrote this post for the SubMain blog. You can check out the original here, at their site. While you’re there, check out some of the products that they offer, including GhostDoc and CodeIt.Right.
If you write software, the term “feedback loop” might have made its way into your vocabulary. It charts a slightly indirect route from its conception and into the developer lexicon, though, so let’s start with the term’s origin. A feedback loop in general systems uses its output as one of its inputs.
Kind of vague, huh? I’ll clarify with an example. I’m actually writing this post from a hotel room, so I can see the air conditioner from my seat. Charlotte, North Carolina, my temporary home, boasts some pretty steamy weather this time of year, so I’m giving the machine a workout. Its LED display reads 70 Fahrenheit and it’s cranking to make that happen.
When the AC unit hits exactly 70 degrees, as measured by its thermostat, it will take a break. But as soon as the thermostat starts inching toward 71, it will turn itself back on and start working again. Such is the Sisyphean struggle of climate control.
Important for us here, though, is the mechanics of this system. The AC unit alters the temperature in the room (its output). But it also uses the temperature in the room as input (if < 71, do nothing, else cool the room). Climate control in buildings operates via feedback loop.
Appropriating the Term for Software Development
It takes a bit of a cognitive leap to think of your own tradecraft in terms of feedback loops. Most likely this happens because you become part of the system. Most people find it harder to reason about things from within.
In software development, you complete the loop. You write code, the compiler builds it, the OS runs it, you observe the result, and decide what to do to the code next. The output of that system becomes the input to drive the next round.
If you have heard the term before, you’ve probably also heard the term “tightening the feedback loop.” Whether or not you’ve heard it, what people mean by this is reducing the cycle time of the aforementioned system. People throwing that term around look to streamline the write->build->run->write again process.
A History of Developer Feedback Loops
At the risk of sounding like a grizzled old codger, let me digress for a moment to talk about feedback loop history. Long before my time came the punched card era. Without belaboring the point, I’ll say that this feedback loop would astound you, the modern software developer.
Programmers would sit at key punch “kiosks”, used to physically perforate forms (one mistake, and you’d start over). They would then take these forms and have operators turn them into cards, stacks of which they would hold onto. Next, they’d wait in line to feed these cards into the machines, which acted as a runtime interpreter. Often, they would have to wait up to 24 hours to see the output of what they had done.
Can you imagine? Write a bit of code, then wait for 24 hours to see if it worked. With a feedback loop this loose, you can bet that checking and re-checking steps received hyper-optimization.
When I went to college and started my programming career, these days had long passed. But that doesn’t mean my early days didn’t involve a good bit of downtime. I can recall modifying C files in projects I worked, and then waiting up to an hour for the code to build and run, depending what I had changed. xkcd immortalized this issue nearly 10 years ago, in one of its most popular comics.
Today, you don’t see this as much, though certainly you could find some legacy codebases or juggernauts that took a while to build. Tooling, technique, modern hardware, and architectural approaches all combine to minimize this problem via tighter feedback loops.
The Worst Feedback Loop
I have a hypothesis. I believe that a specific amount of time exists for each person that represents the absolute, least-optimal amount of time for work feedback. For me, it’s about 40 seconds.
If I make some changes to something and see immediate results, then great. Beyond immediacy, my impatience kicks in. I stare at the thing, I tap impatiently, I might even hit it a little, knowing no good will come. But after about 40 seconds, I simply switch my attention elsewhere.
Now, if I know the wait time will be longer than 40 seconds, I may develop some plan. I might pipeline my work, or carve out some other tasks with which I can be productive while waiting. If, for instance, I can get feedback on something every 10 minutes, I’ll kick it off, do some household chores, periodically checking on it.
But, at 40 seconds, it resides in some kind of middle limbo, preventing any semblance of productivity. I kick it off and check twitter. 40 seconds turns into 5 minutes, when someone posts a link to some cool astronomy site. I check back, forget what I did, and then remember. I try again, and wait 40 seconds. This time I look at a Buzzfeed article and waste 10 minutes as that turns into 4 Buzzfeed articles. I then hate myself.
The Importance of Tightening
Why do I offer this story about my most sub-optimal feedback period? To demonstrate the importance of diligence in tightening the loop. Wasting a few seconds while waiting hinders you. But waiting enough seconds to distract you with other things slaughters your productivity.
With software development, you can get into a state of what I’ve heard described as “flow”. In a state of flow, the feedback loop creates harmony in what you’re doing. You make adjustments, get quick feedback, feel encouraged and productive, which promotes more concentration, more feedback, and more productivity. You discover a virtuous circle.
But just the slightest dropoff in the loop pops that bubble. And, another dropoff from there (e.g. to 40 seconds for me) can render you borderline-useless. So much of your professional performance rides on keeping the loop tight.
Tighten Your Loop Further
Modern tooling offers so many options for you. Many IDEs will perform speculative compilation or interpretation as you code, making builds much faster. GUI components can be rendered as you work, allowing you to see changes in real time as you alter the markup. Unit tests slice your code into discrete, separately evaluated components, and continuous testing tools provide pass/fail feedback as you type. Static code analysis tools offer you code review as you work, rather than at some code review days later. I could go on.
The general idea here, is that you should constantly seek ways to tune your day to day work. Keep your eyes out for tools that speed up your feedback loop. Read blogs and go to user groups. Watch your coworkers for tips and tricks. Claw, scratch, and grapple your way to shaving time off of your feedback loop.
We’ve come a long way from punch cards and sword fights while code compiles. But, in 10 or 30 years, we’ll look back in amazement at how archaic our current techniques seem. Put yourself at the forefront of that curve, and you’ll distinguish yourself as a developer.