Here's a common discussion between a business stakeholder and an engineering leader. Why aren't we hitting our deadlines? Or the alternative, why aren't you able to give me accurate timelines. The engineering leader sucks in a deep breath. Then they begin a tirade on how impossible it is to know how long engineering work will take. Or the engineering leader will agree to put a date on work they know won't get completed in time. This situation plays out week after week. The business person loses confidence in the engineer. The engineer loses the motivation to even try communicating anymore. The relationship turns toxic and everyone is unhappy. The real kicker is that both of them are smart, ambitious, and want the best for the team.
So how did we get here?
This is a startup. At any given moment, there are a dozen experiments we need to launch. We're always in danger of running out of money. Founders are pushing hard towards the goals the company needs to hit to survive. And at the center of it all is the engineering team which builds the thing that all this hoopla is about.
Most startups don't plan years ahead. A few people have an idea and they build the smallest product they can in the jankiest hackiest way. The few companies that survive this stage don't have time to go back and start over with good technology. So they forge ahead and hire an engineering team. That first engineering team does its best to make good decisions but they are only a handful of people. The stresses of everyday work usually get the better of them. They make more decisions we'll have to fix later.
So here we are a few years later. The engineering team is several dozen people, broken out into a handful of teams. Everyone knows the foundation is shaky but we continue to add on new layers. Work takes longer than it would in ideal conditions. Hidden mines are lying in wait, soon to become the next urgent incident. Documentation is non-existent. Engineers need to find a person who knows the thing. It takes time. Memories are fallible. Planning tickets is either straightforward or complete guesswork. Most engineers complain about legacy code. They would prefer to refactor rather than understand the existing systems. Testing isn't part of the culture yet ("takes too long") so bugs run rampant. You can't be expected to deliver on time with all this mess.
Now what? How do you manage expectations when you know the situation is unforgiving? When you can't predict what's around the corner or even know exactly what you're building. Here are a few suggestions. They seem obvious but you have to practice each one until it becomes a reflex.
First, be honest with your stakeholder. Set the expectation that you and the team will do your best but sometimes you're going to miss and that's ok. Promise that you'll always be open and transparent about why. Communicate early. As soon as you identify new information that changes the timeline, let them know. Communicate with detail. Take this example:
"We won't make the Friday launch because the code turned out to be more complicated than we expected"
Now read this one:
"We won't make the Friday launch. The model we're building only expects one widget per person. We need to change the model to allow for many widgets per person. To do this we have to run a migration on the database. This is risky because it could delete every person with a widget. We want the other team to review it and they can only do that the day after next. We also need to test it against real data which will take an extra three days of setup. The new timeline is the following Wednesday."
Which one of these explanations inspires more confidence? Sure, some stakeholders will still get upset but most will understand. You've communicated the reason for the delay and a new deadline. You've also allowed the stakeholder the opportunity to decrease scope. They can come back and say "I'm willing to take that risk" or "Let's ignore everyone with a widget for the first version". You gave them the tools to make a more informed decision. Now you are partners in the timeline instead of the stakeholder being a passive observer.
When you're working on a project, you have two levers to play with. Time and Scope. (Burning out your engineers by having them work more hours is a third but let's pretend we're good leaders).
So many folks have talked about this already that I won't go too far down this path. I do want to add one point I don't see as often. If you're asked to commit to a firm deadline, take care to talk in specifics about scope cuts. Don't agree to loose generalities. Make sure your business stakeholder understands what they aren't getting in this version. Repeat it often. Write it down. Don't assume the absence of scope means everyone is aware. Your stakeholder might assume it's an implicit criterion and expects it done anyway.
When new scope gets added ad-hoc, be firm about the tradeoff between new work and the deadline. Too often I see someone ask an engineer to add one thing. And then another thing. A month later, you're at a retro discussing why the thing shipped late. No one mentions the small ticket or the extra success criteria. But that work adds up. The add-in ticket is the morning ice-coffee of productivity. There's nothing wrong with buying an ice-coffee every morning. But very few people realize how much money that adds up to. Imagine every morning before you bought your coffee, you had someone show you the cost. You might make a different decision. The same rule applies here. It's not bad to add more scope. Make sure the tradeoff is explicit. Convey that doing the extra thing comes at the expense of time or scope. We're not doing an extra thing. We're doing an "instead of" thing.
Make Actual Progress
You're kicking off a project due in a month. At the outset, you get to decide between two paths forward.
In the first path, we create a bunch of tickets that are more or less the bullets from a planning meeting. The ticket can spend weeks in-progress. Engineers are coming up for air to ask their peers to review thousands of lines of code at once. We defer QA to the end of the project. The engineer might have understood the requirements. But we won't know for a while. When the time comes to merge in big chunks of the project, there are conflicts to resolve. You're now dependent on other teams that you didn't expect. We've created many more days of work than we accounted for in planning. The deadline is coming closer so we start getting "scrappier". We turn the feature on and hope that we did enough testing at the finish line. It's time to pray. And prepare for the incident post-mortem.
In the other path, you create small bite-sized tickets. Every ticket is only marked as completed when it's shipped to production and live on your site. Pull requests are small and manageable for engineers to review. QA (whether design or product) happens as work is ready. Engineers ask more questions because each ticket has more specific criteria. Other teams merging code must ensure it works with yours because yours was in first. As you're nearing the deadline, there is no panic to start QA-ing everything. Most of the code is already merged. You don't need to resolve a ton of merge conflicts. You're able to turn on the feature and sit back and enjoy it. You might even have the opportunity to soft-launch and have resolved some bugs. The rollout is smooth and your team celebrated as heroes.
Did I need to ask which path you prefer? So here's the obvious insight. Create smaller work. Ship often. QA often. It feels so much harder but it's not. It's a habit that your team builds. Sometimes we mistake "Done Thinking About This" for "Done". Then we actually have to go back and redo something. Again this is un-accounted for work.
Shipping often also helps you narrow the window you can miss on a timeline. If a certain ticket should take a day or two then missing by 50% is another day. If we allow a ticket to take weeks then missing by 50% can be a week or more. We also won't seek to understand risks or complications until the ticket is in danger. If we expect a ticket to take weeks then we will wait for weeks to probe the engineer for more information.
The good cycle
In my experience, no one ever talks about the tickets that finish ahead of schedule. At most, we give the engineer a pat on the back and move on. Tickets that take far too long get retrospectives and action items. We change the process for tickets that take too long. We rehash them over and over. It's not a bad thing to learn from mistakes. But when we don't follow through too often, it becomes a matter of blame. The goal isn't to get to perfect timelines. It's to instill better habits so that we create the conditions for misses to happen less often.
If you miss less often, the times you do miss won't be as big of a deal. Your stakeholders will take your word more often when you explain delays. In fact, they will start to recognize the same patterns and appreciate them. Your team will be happier and act with urgency (not pressure). And with all the spare time from not chasing impossible deadlines, you can work on planning for tech debt. Improvements to productivity mean less uncertainty. Less uncertainty gains you more credibility. Now you can sell more code improvement projects to stakeholders. The improvements create even more predictability. It's a beautiful cycle.