This is an excerpt from The Art of Agile Development, Second Edition. Visit the Second Edition home page for additional excerpts and more!
This excerpt is copyright 2007, 2021 by James Shore and Shane Warden. Although you are welcome to share this link, do not distribute or republish the content without James Shore’s express written permission.
We deliver on our iteration commitments.
Imagine that the power cable for your workstation is just barely long enough to reach the wall receptacle. You can plug it in if you stretch it taught, but the slightest vibration will cause the plug to pop out of the wall and the power to go off. You’ll lose everything you were working on.
I can’t afford to have my computer losing power at the slightest provocation. My work’s too important for that. In this situation, I would move the computer closer to the outlet so that it could handle some minor bumps. (Then I would tape the cord to the floor so people couldn’t trip over it, install an uninterruptable power supply, and invest in a continuous backup solution.)
Your iteration plans are also too important to be disrupted by the slightest provocation. Like the power cord, they need slack.
How Much Slack?
The amount of slack you need doesn’t depend on the number of problems you face. It depends on the randomness of problems. If you always experience exactly 20 hours of problems in each iteration, your capacity will automatically compensate. However, if you experience between 20 and 30 hours of problems, your capacity will bounce up and down. You need 10 hours of slack to stabilize your capacity and to ensure that you’ll meet your commitments.
Remember that the team decides for itself what to commit to and whether those commitments are shared outside the team. See the “Making and Meeting Iteration Commitments” section for details.
These numbers are just for illustration. Instead of measuring the number of hours you spend on problems, take advantage of the capacity feedback loop, described in the “Stabilizing Capacity” section. If your capacity bounces around a lot, stop signing up for more stories than your capacity allows. This will cause your capacity to settle at a lower number that incorporates enough slack for your team. On the other hand, if you finish everything early, including time to clean up the things you touched, reduce your slack by committing to a small extra story in the next iteration.
How to Use Slack
Used correctly, the capacity feedback loop will automatically give your team the amount of slack it needs to reliably finish every story in every iteration. But how should you use that slack?
First, only the team’s constraint needs slack. There will be one type of work—typically programming—that is the bottleneck for your team. The team’s slack should be dedicated to relieving that constraint.
One way to do so would be to reserve the last part of your iteration for slack, and just go home early when your stories are done. That would be wasteful, of course. Another option would be to take on another story when everything is finished, but now you’re back to not having slack and just building as much as you can.
The best use of slack is to increase your ability to deliver.
No, the best use of slack is to increase your ability to deliver. The right way to do so depends on your constraint. Here are three good choices. Improving internal quality, in particular, is a must-have for nearly every team.
Improving internal quality
The team’s performance is directly tied to the quality of its code, tests, automation, and infrastructure. Together, they’re the software’s internal quality.
Even the best teams inadvertently accumulate internal quality problems. Although you should always make your software as clean as you can, even good work eventually gets out of sync with your needs.
- Reflective Design
If your constraint is programming, improving internal quality is a surefire way to increase your capacity. Every iteration, rather than doing the minimum necessary to create clean code, look for opportunities to make existing code better, too. Make it part of your moment-to-moment work. If you find yourself scratching your head over a variable or method name, change it. If you see code that’s no longer in use, delete it.
In addition to these small improvements, look for opportunities to make larger changes. Perhaps a module has too many responsibilities, a test fails randomly, or a build step is slow. When these problems affect your work, incrementally improve them.
Make improvements every day, throughout the iteration.
Don’t batch up your improvements. Make improvements every day, throughout the iteration: an hour encapsulating a structure here, two hours fixing a deploy script there. Each improvement should address a specific, relatively small problem. Sometimes you’ll only be able to fix part of a larger problem—that’s okay, as long as it makes the code better. You’ll have another chance to improve the next time you work on that part of the system.
- Task Planning
Before starting, take a look at the task board and compare it to the amount of time left in the iteration. Are there a lot of tasks done compared to the amount of time that’s elapsed? The team is ahead of schedule, so you can go ahead and clean things up. Does it instead seem like the team is falling behind? Shrug your shoulders and focus on your iteration commitment instead. You’ll have another opportunity next iteration. By varying the amount of time you spend on internal quality, you can ensure that most iterations come in exactly as planned.
Always leave your code and other systems a little bit better than you found them, no matter how much time you have. You’re not choosing between “sloppy” and “clean;” you’re choosing between “slightly cleaner” and “a lot cleaner.” Always make time to do good work. Messy work will cost you more time than it saves.
Focus your improvements on the code, tests, and other systems that you’re actually working on. If you do, the things you work with most will see the most changes. It’s a simple feedback loop that magically directs your cleanup efforts right where they’ll do the most good.
Develop customer skills
- Whole Team
Although Agile teams should be whole, cross-functional teams, a lot of organizations skimp on people with customer skills. If your team is constrained by lack of knowledge about customers, users, and business needs, use your slack to learn more. Study the domain. Join your product manager in meetings. Interview users and talk to stakeholders.
As with improving internal quality, spread this time throughout the iteration and use your team’s progress to judge how much time you can spend.
Dedicate time to exploration and experimentation
Developers tend to be naturally curious and must continually improve their skills. Given time to indulge their curiousity, they will often learn things that enhance their work on the team.
Dedicated time for exploration and experimentation, also called research time, is an excellent way to encourage learning while adding slack into your iterations. Unlike the other techniques, it’s a half-day chunk set aside at the end of the iteration. If you end up running late, you can eat into the research time to meet your commitments.
Research time gives you a buffer, but it shouldn’t be something you rely on.
If you use research time, calculate your capacity based on the stories that are finished when research time is scheduled to start, not when the iteration is scheduled to end. That way, if you do end up eating into your research time, your capacity will automatically decrease so you don’t need to do so next iteration. Research time gives you a buffer, but it shouldn’t be something you rely on.
Each team member uses the research time block to conduct self-directed exploration into a topic of their choice. It can be research into a new technology, studying an obscure section of the code, trying a new practice, exploring a new product idea, or anything else that interests them. There’s only one rule: don’t work on any stories or commit any production code.
If you’re concerned about people goofing off, provide lunch the next day and ask that people share what they’ve learned through informal peer discussion. This is a great way to cross-pollinate ideas anyway.
I’ve introduced research time to several teams, and it’s paid dividends each time. Two weeks after introducing research time at one organization, the product manager told me that research time was the most valuable time the team spent and suggested we double it.
Team members, for research time to be effective, you must focus and treat it as real work. Half a day can go by very quickly. It’s easy to think of research time as a catch-all for postponed meetings. Be strict about avoiding interruptions. Ignore your email, turn off text messages, block the time on your calendar, and restrict your web browsing to your actual research.
When you first adopt research time, you might have trouble deciding what to work on. Think about what’s puzzled you recently. Would you like to learn more about the details of your UI framework or code? Is there a programming language you’ve wanted to try, but your organization doesn’t use? Has real-time networking always fascinated you?
- Spike Solutions
As you do your research, create spike solutions—small, standalone programs—that demonstrate what you’ve learned. If you’re experimenting with the production code, create a throwaway branch. Don’t try to make anything that’s generally useful; that will reduce the amount of time available to pursue core ideas. Just do enough to prove the concept, then move on to your next subject.
The role of overtime
- Energized Work
Overtime doesn’t come from the capacity feedback loop, but it is a source of slack. Use it with caution. If you want to voluntarily work a bit extra to finish up some story or task, that’s okay. Don’t make a habit of it, though, and don’t work more than an hour or so extra on any given day. You need time to recharge if you’re going to be productive the next day. Pay attention to your energy and never use overtime as an excuse to lower your team’s standards.
If our commitment is at risk, shouldn’t we temporarily stop pair programming, refactoring, test-driven development, etc.? Meeting our commitment is most important, right?
With experience, these practices should speed you up, not slow you down, but they do have a learning curve. It’s true that setting them aside might make it easier for you to meet your commitments early on.
But you still shouldn’t use them as a source of slack. These practices maintain your capability to deliver high-quality code. If you don’t do them, the resulting decrease in internal quality will immediately slow you down. You may meet this iteration’s commitments, but you’ll do so at the expense of the next iteration.
- Pair Programming
- Mob Programming
If you don’t have enough slack to meet your commitments, don’t lower your standards. Modify your plans instead, as discussed in the “Making and Meeting Iteration Commitments” section.
Should we pair or mob during research time?
Mobbing is typically overkill. Pairing can be nice, if you want to collaborate on a topic, but it isn’t necessary.
How does slack relate to clean-up stories?
Clean-up stories are special stories just for improving internal quality (see the “Clean-Up Stories” section). To be honest, they’re kind of a mistake. The team should use its slack to constantly improve its code and other systems. Clean-up stories shouldn’t be needed.
But sometimes you inherit software that would get a speed-boost from extra cleanup. In those cases, on-site customers might choose to prioritize a clean-up story. But they should never be mandatory. They’re always at the discretion of the on-site customers, who trade off the benefits of extra cleanup with the benefits of other work the team can do. This is in contrast to cleanup performed using slack, which is at the discretion of the developers.
The risk of slack is that it can lead people to think that activities such as improving internal quality and developing customer skills aren’t important. They’re actually vital, and a team that doesn’t do them will slow down over time. They’re just not time-critical like your iteration commitment is. Make sure you have enough slack to steadily improve. If you don’t, reduce your capacity a bit so that you do.
In addition, never do sloppy work in the name of slack. If you can’t meet your iteration commitments while following your chosen process, revise the iteration plan instead.
When your team incorporates slack into your iterations:
The team consistently meets its iteration commitments.
Team members rarely, if ever, need overtime.
The team's internal quality steadily improves, making work easier and faster.
Alternatives and Experiments
On its face, slack appears to be about meeting commitments, and that is an important part of it. But the real innovation is using slack to fix the problems that caused the need for slack in the first place. Together with capacity, this forms a clever little feedback loop that uses teams’ weaknesses to make them stronger.
Many organizations are so stressed about productivity that they pressure their teams to maximize their capacity number. Their teams push to increase their capacity in every iteration, so they don’t introduce slack. Ironically, this prevents them from improving their actual capacity, and it makes it difficult for them to meet their commitments...which in turn leads to increased pressure, not to mention a lot of unpleasant thrashing around.
As you experiment with slack, keep the clever little feedback loop in mind. Don’t just look for ways to add slack; look for ways to use that slack in a way that improves your team’s capability.
Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency [DeMarco2002] provides a compelling case for providing slack throughout the organization.
The Goal [Goldratt1992] and Critical Chain [Goldratt1997] are two business novels that make the case for using slack (or “buffers”), instead of padding estimates, to protect commitments and increase throughput.