5.16.2008

Do Less With More (So More Gets Done)

Looking like things might be late? Did that Big Bad 'premature optimization is the root of all evil' thingy just nip you again? What's a poor soul to do? There is an answer . . . .

Okay, so there's a staff of developers busily being busy, with other folks awaiting new features. Bugs and distractions inhibit progress. Some sales guy snickered at a demo. Expectations were hyped. People are getting hyper. Things are becoming a flurry. When a contract looks like it might run late, a trade show looms, or market opportunities tick loudly, the situation can quickly get prickly. Used to be that everything else was a priority that interrupted this project; now it seems that this project is about to interrupt everyone else. What an exalted state!

The project's status and progress become the focus of attention. More and more conversations are about progress, people, and dates, driving out topics of performance, abstraction, or architecture. Such conversations tend towards the ineffectual, like idle chatter regarding schedules. That won't work, never does, except in an industry that's irrelevant to high-tech. Coercion and threats won't speed things up, most likely the developers are already working at their personal capacity. Plus, it's never a good idea to bully someone, especially in places like Silicon Valley, where any accomplished developer can find a new job in the time it takes to fill out a web form. Finally, or so it seems, Someone In Authority proclaims: "add more people to the project and get it done." Aside from what appears to be a Blinding Flash of the Obvious, adding additional staffing late in a project is renown for pushing releases even later.

Fred Brooks warned us more than thirty years ago about the calamitous burden of adding people late to a project. Nonetheless, many software managers ignore his sage advice. Business "as usual", driven by glacial forces of habit and ritual, is how employee activity typically becomes planned, then communicated. Often, it presumes people are as predictable as machines. We're not. We're not going to be in the foreseeable future. Nor can people just "switch on" as machines do. Too bad people can't download context and operating procedures as quickly as a computer which only needs to boot up, or a lathe that just needs to be switched on. But we can't: this is the workplace, not The Matrix.

Imagine a perfect world, where every company has a ready pool of developers just sitting on the bench just waiting to fill in. Add to that a magical circumstance where any developer can interchangeably step in for another and be up to speed in moments, disrupting nothing else underway. Reality delivers bad news on both fronts: projects are usually understaffed to begin with; and, developers are not fungible. Software developers have highly-honed, hard to acquire skills. It is a mindset of exactitude that few disciplines ever encounter. Developers are not interchangeable; moreover they're hard to replace. And even if a few devs with appropriate skills can be found, they may not have the personality or traits that would enable them to be effective on a software development team.

Software development is so complicated and detailed that even a brief vacation can leave a developer needing a few days to spin-up, after only being away for a week or two
. After just a matter of days, important project details and techniques start fading to the background. And, over the intervening days, situations have likely changed in the company or project. Even in the best of circumstances, re-entry is a jarring situation. And hiring? Then there's the entire adaptation to the how the new company operates, the normative forces, to say nothing of the unique build and testing tools at the new employer. Vacations are bad enough; hiring promises large diversions of otherwise productive time for the project.

So, why do projects so often go awry?

Let's back up to the beginning. Somebody got an idea. Perhaps someone "blessed" with an overabundance of fast-twitch fibers got spooked by a competitor's FUD or became blinded by deal lust. S
uperiors called forth for The Plan. Ritual reigned as the manager scoped the work, wrote a project staffing plan, derived a schedule, and then, in the manner of many companies, wasted umpteen hours preparing a presentation, only to go forth and swear myriad oaths on broad altars promising to deliver a feature-complete, on-time, and within budget result.

Sadly, l
urking within, is a noxious notion regarding "delivering on time" -- in other words, "by a date." On time means the work got done, which entailed productive time from developers. If developers are always available and fungible, then a simple quotient of total estimated days divided by count of available developers yields an expected date. By doing this, managers are presuming that the team's capacity for developing software for the project is constant, thus predictable. It is neither. Typically, projects start off understaffed, then people come and go, resource contention follows, progress slows down. People are added and the project slows yet more.

A project can only be "late" in reference to a date. Two evident factors are: (1) the progress of the project; and, (2)
the correctness of that date. Conversation often focuses on the progress, but the likely culprit is more often the correctness of the date. Or, more precisely, the expectations, allocations, and, promises bound to that date -- which reflect an assumption of constant development capacity dedicated to the project. Irrespective of the cause, any change in project staffing has an immediate impact on any date, and recovery to a new equilibrium comes slowly, particularly if it requires hiring. Scope is hope; human factors are the reality.

Many managers think in expansive detail about the features to be built, their dependencies and commonalities. But any project's primary dependency is on the capacity and the timing of developer engagement.
Effective developer staffing is the fundamental requirement for success for a project or for a company. Whenever a project staffing plan presumes development capacity is constant, and that recovery (if needed) would be quick, jeopardy is evident. Date and staff co-vary, though neither linearly nor directly. To just mindlessly pad the schedule is to miss the fundamental point -- software development is a complex, not linear, system based on the human vagaries of developers.

All staffing changes are disruptive. On a day to day basis, the actual time that developers are task-focused per project rises or falls as everyday events shape everyone's attendance and attention. Capacity is likewise reduced by other ever-present workplace duties, as well as other projects vying for attention. The development capacity available to all projects likewise rises and falls. This becomes especially problematic when key features or refactorings are underway by individuals.

If a feature only has one person working on it, it follows that when the person isn't working on it, then no progress is occurring. For the single-person feature, it is either getting worked on or it isn't. This isn't a slowdown, it's a stall.
If a task is important, it's wise to staff it such that progress doesn't stall. Every task underway by an individual has a high risk of stalling. Thus, never have a critical task underway by a individual. Ensure that at least two developers are committed to the success of every key task.

Did the project actually go awry?

Against what measure does progress appear thwarted? Did expectations reflect a likely outcome or instead a hopeful outcome -- best guess or heart's desire? Developer time is not available at a constant rate. Simple summed estimates of "developer days" (regardless of padding) only suggest at best how long the tasks will take -- the sum of their time, but not when they will be done due to the influence of human factors. People get interrupted, become distracted, sometimes fall ill, or go on vacation. Sometimes someone new joins up. Developer capacity varies. Project allocations vary. Straight-line time is a fantasy. Any date derived in such a way is a heart's desire.

The generative point from which things often go awry is in planning the staffing pattern within the project. A problem arises from the practice of assigning critical chain tasks to individuals -- any individual -- then predicting dates based on constant capacity. Superstars are irrelevant if they're not available. If the show must go on, a backup, a substitute, an understudy, or the like must always be at the ready -- that's the cost of living in a situation where "the show must go on." This concept appears elusive to many software managers and many allied practitioners. Nonetheless, this solution has been in place across diverse professions ranging from the court to the classroom, from the theater to the baseball diamond, from the fire brigade to the emergency room. Where a human is required, at least two must be at the ready.

Software systems are arcane and intricate. They're among the most complex artifacts ever created. Complex systems give rise to emergent phenomena that aren't predictable. Developers participate inventively, today impacts tomorrow, and so on through a chain of circumstances. Full system comprehension is beyond the grasp of an individual, and its myriad parts are a chore to remember, let alone learn. Programmers are individuals, that's true. Yet software is done by groups, or better yet, teams. The whole can be greater than the sum of the parts, depending on how those "parts" are choreographed. When working together, progress continues irrespective of individual factors. If developer activities are constrained to collegial parallel-play with code, then every time any developer becomes unavailable, project progress slows because that developer's task just stalled.

Do less with more . . .

The solution is to ensure that no critical process depends upon any individual. For the manager, this suggests identifying the task, then ensuring at least two developers share the responsibility for its successful completion. Do less with more, thus ensuring continual forward progress on the critical chain. Staff smartly at the outset, being ever mindful of the surprising nature of human factors. People have lives and their futures are unforeseeable. If a task must be done, human vagaries require more than a single individual be committed to its completion. (XP's pair programming takes this in stride.) Individuals don't belong in the critical chain.

Common practice, though, is to assign tasks to individuals. If there's 10 small features and ten developers, often the accounting rules or company mores lead managers to implement a "single feature per single developer" assignment mechanism. Such assignments take on a life of their own as other developers quickly set filters that reduce prominence of anything for which they're not responsible. In our email maelstrom, it's easy for things to vanish. They don't get lost; but they do vanish. Things can be going awry for a while before drawing attention.

As a corollary, "one-per" reveals the belief that monitoring individuals trumps monitoring tasks: it is a mindset framed primarily by accounting for developer's time. Many managers assign a task to a person, invoking a premise that responsibility is best designated to an individual. In contrast, a progress mindset ensures tasks get done by staffing to avoid stalls. What's evident here are contrasting mindsets regarding the first principle management practice: accountability vs. progress.

And it's also true that many developers prefer to work alone for myriad personal and social factors. In any workplace, a plethora of mother-tongue challenges impedes communication, personal chemistry is a known operative force, and all developers have highly idiosyncratic ways of configuring their working environment. It's a natural characteristic of those who take to a career in software development to often wish to stay to themselves. Individuals are programmers, in a group they're software developers, but when they're a team magic can happen -- as many, many developers in Silicon Valley know in their bones. Good progress makes good teams, but this doesn't occur spontaneously. For starters, it means accepting that in effective software development, developers work together.

So, take the test of five things: if you have five features to be coded and five developers at hand, is it one each? On the other hand, perhaps as a team you'll list the features, factor that which is common, and prioritize the rest. Then ask the five developers to take it upon themselves the get first two features done before moving on to others. If someone becomes unavailable, progress continues. And peer review is a magical thing in itself.

The future of every software project is murky. A manager is wise to be ever mindful of capacity and flow, avoiding stalls, and thus avoiding adding people late to a project. It's easy to avoid, but it requires staffing in a more modern, less industrial-age, manner. Some suggestions:
  • Enable continual forward progress by disallowing individuals in the critical chain
  • Ensure everyone has someone to talk with so there's always someone else up to speed on the task
  • As a measure of progress, employ "features released" by staff, instead of accounting for developer hours, per individual. It's a useful proxy for progress, at least to begin with.
Then, tasks on the critical chain don't stall, things get done. Steep learning curves are flattened. Chaos is constrained. Stalls are avoided. Progress continues. The whole can be greater than the sum of the parts. Choreography counts. The buddy system has served us well over the ages.

Recalling Knuth, echoing Hoare: "Premature optimization is the root of all evil." Don't locally optimize for developers' time through accounting, optimize for progress through task completion. Don't be evil.

Interesting reading