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:
- They might more directly understand each other’s needs
- 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.
Well said, and … such acid! Do I detect maybe a recent stinky event, or maybe an accumulation of same (i.e. most or all the tactics mentioned)?
Empathy is tough. When people resort to fall-back behaviors, it almost always stinks because it’s almost always driven by fear. Fear of loss (I’m no longer important), of the unknown (Will I be let go?), or of doubt (This can’t possibly work, can it?)
Liked the post. Hope you’re good.
Not to worry! Some folks seem to like posts that are shaped like advice, but I’m somewhat uncomfortable giving unrequested advice out of context, so instead of listing a bunch of things readers should do, I listed a bunch of things they probably shouldn’t do. Taking this approach put a grin on my face, and I hope readers will read it with grins on theirs. (P.S. I’ve tried to outgrow sarcasm, but it seems it has grown with me.)
I’m not sure whether this sort of missive (under my name or anyone else’s) would’ve helped me in any of the situations I’ve found myself in. It was fun for me to write, at least, and I’m glad you appreciated reading it. If you’re interested, my best efforts at helping folks start conversations that lead to mutual understanding — besides this blog, which isn’t always so snarky! — are published each week at Agile in 3 Minutes.