Scope of this article

The 3 things almost every team does to meet deadlines that make things worse:
1. Hire more developers
2. Cut corners
3. Work long hours
Jason Gorman

I must admit, my deadline-missing expertise is fairly wide-ranging. But this piece is specifically about deadlines that arise when we undertake to develop software, and how you can do your level best to miss them.

Set deadlines

Don’t think too hard about whether they’re needed. When in doubt, set one.

Set deadlines unilaterally

Avoid taking input from the customer who depends on the outcome or the team trying to deliver it. Take your best guess and call it good.

Disagree on “deadline”

Some possible meanings of the word “deadline”:

  • If we miss, we go out of business
  • If we miss, our customer goes out of business
  • If we miss, my manager will blame me and/or I’ll be fired
  • If we miss, I’ll blame you and/or you’ll be fired
  • I don’t think you’ve been working hard enough lately

These meanings aren’t mutually exclusive. Several may be in play. To maximize the impact on nervousness and perceived pressure of these implied threats, your best move here is to keep things vague.

Disagree on “done”

”Done” is about completion. “Off my plate” is about avoidance.
Tim Ottinger

Some possible meanings of the word “done”:

  • Our customers have had it for weeks and haven’t noticed anything needing changing
  • Our customers just got it this second
  • Our customers could get it if they wanted
  • Our QA team is testing it
  • The code is feature-complete on a branch
  • It’s out of our hands
  • Nobody can blame us

Time wasted shuttling between various kinds of “done” is key. Avoid disambiguating. Use “done” to mean whatever’s convenient for it to mean right now.

Disagree on scope

Preconceive your own notions of what needs doing. Again, avoid taking input from your customer and your development team. Also, avoid letting them take input from each other. If they talk to each other regularly, you’ve got two problems:

  1. They might more directly understand each other’s needs
  2. They might find creative ways to meet their needs in less time

It’s mainly (2) you’re worried about here, for which (1) will put you at risk if you let it. Don’t let it. Get shallow agreement on a list of work items and don’t let anyone make you deviate from it.

Don’t have a customer (sort of)

If there’s definitively no customer, you’ve got big problems. Since nobody’ll be affected, there’s no harm in shipping whatever you’ve got right now.

Let me restate: With no customer, there’s nothing standing between you and deployment.

This constitutes an enormous impediment to your goal. What you need instead is a feeling of certainty that your customers exist, plus a lack of connection to any of them. Now you know there’s someone out there who’s supposed to be able to judge whether today’s product is better or worse for them than last week’s, and who can remind you every now and then why what you’re doing matters. Furthermore, your team knows that they can’t get direct answers to the most fundamental questions about their work, and that they can’t determine whether they’re doing anyone any good.

Well done! You’ve severed the most important feedback loop in their work.

Rate-limit deployments

If you’ve got customers and you talk to them — or, worse, the team is talking to them — all is not lost. You’ve got lots of options for making it difficult to get new code deployed:

  • Name an environment “production” without discussing uptime, reliability, or other aspects of service
  • Limit who has access to “production” systems (this also helps later, to complexicate debugging!)
  • Require several signoffs for each deployment
  • Provide as little information as possible to those responsible for signing off, so they waver, sometimes ask for more information, and occasionally exercise their veto powers
  • Make it just as difficult to roll back, which helps justify the elaborate signoff procedure

Now you’re considerably more likely to miss your deadline. If the team somehow manages to produce exactly what customers need, it’s going to take a while before they can get it. And otherwise, look how long it’ll take before customers can identify new needs, before the team can possibly hear about them, and before any work to address these needs can even begin!

Separate QA from Development

As part of your overall strategy, you need “QA” to be its own team and problem-identifying to be its own phase.

You want “Dev” working on their own, assuming QA will catch whatever they missed. You want QA working on their own, assuming Dev is following the most expedient path to claiming they’re done.

You want even the best-intentioned developer to say “done” as soon as possible and feel free of responsibility when it turns out not to be deployable. You want even the best-intentioned QA member to say “good enough” as soon as possible while finding a few unimportant bugs. You want Dev to be annoyed with QA when they find important problems, and you want QA to be annoyed with Dev when they repeatedly let important problems through.

This part of your strategy is very important. You slow down the work today by splitting it up, you slow down the work indefinitely by incentivizing placing blame over delivering value, and you make it very difficult to make predictable progress against the plan. At any given moment, it might look like you’re on target for a deadline when you’re really not. Perfect!

Separate Development from decision-making

If you’ve managed to keep your team from talking to the customer, good: they don’t know what you know about the business situation, so nobody but you is in a position to decide how the team should do its work.

You’ve heard Test-Driven Development takes longer because developers are also writing tests, and you’ve heard Pair Programming basically takes twice as long because two people are doing one person’s work, but you have the sneaking suspicion that pairing and TDD would save time by producing work output that’s frequently deployment-ready to begin with.

Can’t have that. What would happen to your standalone QA phase? What would happen if people’s attention were suddenly focused on your lengthy deployment signoff process?

Don’t let them pair or test-drive; above all, don’t let them make these choices themselves. Not on your watch. You’ve got deadlines to miss.

Keep code brittle

the only time we don’t change code is when there’s no existing code, a starting state that lasts about 10 minutes.
Michael D. “GeePaw” Hill

As a codebase grows, it tends to get harder to change. Because this stems from the number of components in interaction, the difficulty grows much faster than, say, lines of code. Great news! The odds are already stacked in your favor.

You still need to be careful. Besides Pair Programming and Test-Driven Development, you need to keep an eye out for the other Extreme Programming technical disciplines. Beware Refactoring, Continuous Integration, Collective Code Ownership, and the like. They tend to have the effect of greatly reducing the risk of changing code. That’s why the decisions to use these practices belong with you, so you can veto them. You need code-change risk as uncontrolled as possible.

Scope creep of this article

I said this article would only be about missing software deadlines. It seems like it could pretty easily be about a lot more. Also, if you’re a developer, I could give you lots more specific ideas for making deadlines whoosh by. But I’ve already missed my self-imposed Wednesday deadline for this week’s blog post. Like I said, I’m an expert on this topic.

This list is far from exhaustive, but I hope — from the bottom of my backlog — that I’ve helped you get started on more reliably missing your deadlines.