Explainer Technical

How to Ship a Software Project

I’ve spent the last 14 years building software, off and on. Over that period I’ve been on the hook for dozens of ship dates. Some I missed. Many I hit.

Through all those adventures, I’ve settled on a basic process I think anyone can use to get from deep-in-the-weeds to a triumphant ship. None of this is especially innovative. Plenty of people likely ship using some variation of this exact procedure. But I wanted to write it up in case it was useful.

1. Pick a ship date—but don’t get attached to it

Start by choosing a date on which it would be nice to have shipped your project. Any criteria is valid here. Business needs, deadlines imposed by programs to which you want to apply, even press strategy.

But don’t get too attached to this ship date. You have no idea if you can make it. At this point it’s an experimental constraint, which will guide the rest of your planning process.

2. Determine the minimally viable feature set your project needs for a successful ship

What does the audience of your project need to be better off than if you’d never shipped the project at all? What is the simplest feature set you can deliver to make an impact?

by Henrik Crisp

You’re reading this because, presumably, you would like to ship. So it’s essential you understand that you can’t immediately ship everything your mind imagines. You can’t ship perfection. Perfection and shipping hate one another, so you have to pick one. I suggest picking ship, but that’s up to you.

Shipping requires hard choices. The more things you try to bundle into a shipping project, the more risk you incur. The risk multiplies invisibly, as it’s impossible to know ahead of time about complex interactions that produce bugs, reduce performance, or otherwise introduce surprises.

The fewer things you try to ship at once, the less risk you incur. So when you make the list of things you want to see in your first ship, do everything you can to keep it as short as possible.

3. List all of the dependencies that must be satisfied for your minimally viable feature set

What needs to exist for these features to work? How much already exists? Get your mind around all the dependent tasks, from things that need to be built, to things that must be bought, to things that must be designed, in order for these features to be ready for public consumption. With luck, you’ve already got some of these dependencies handled.

Can you license or purchase things instead of building them yourself? Can you leverage open source software rather than rolling your own solutions? Think through how many off-the-shelf opportunities exist to satisfy your dependencies. But also remember there’s no free lunch: integrating outside resources can still be costly.

4. Estimate how much time it will take to satisfy your dependencies—then multiply

Software development time estimates are comically error-prone. But if you price the estimation risk into your estimate, you can earn yourself some breathing room. There will be bugs that keep coming back. There will be surprises as you integrate third-party tools and content. There will be tasks that seemed easy at the outset, but whose implementation reveals a raft of additional complexity.

That’s life in the software business.

As you create an inventory of your dependencies and the time you estimate they’ll need to cook, multiply by 2.5.

Maybe that seems excessive. But it’s a concession to the fact that our frail meat brains are bad at storing and modeling the total complexity of a software system. When you made your initial guess, you were quite possibly ignoring more than half the picture. Price that limited perspective into your final guess.

Or don’t. It’s your ship. You can use whatever multiple you feel comfortable with here. Long experience tells me that for my estimates, though, I usually want 2.5x.

Don’t forget time for testing your project ahead of ship. I can’t tell you how long this will take, since different environments have different constraints. If you’re shipping native code for approval in the iOS App Store, for example, you’ll want to do much more thorough testing than if you’re shipping a web app you can update at-will.

You’ll also want to budget time to make fixes based on what you learn in the QA process.

5. Add up your time estimates and compare the timeline to your ship date

If you’re very lucky, your time estimates and your ship date mesh perfectly.

But you’re probably not lucky. You’re working with software, and software delights in thwarting our optimism. What if your requirements push far past the ship date?

You’re going to be tempted to manipulate the estimates. Don’t do this. There’s a reason we estimate in pieces and add things up, instead of working backwards from the ship date.

In this process, here are all the things we’ve considered in order from most real to least real:

  1. The dependencies for our desired features
  2. The minimally viable feature set
  3. The time estimates
  4. The ship date

The ship date is the least real thing we’re dealing with! Don’t let it drive.

That said, if you absolutely must treat the ship date as a hard constraint, you have options. None of them include goosing the estimates.

6. Make hard choices: trim scope or move the ship date

I know. You want a pony.


But now you know what the pony costs.

You’re going to ship the pony 18 months later than you would have liked. Are you going to have enough money to survive for that extra 18 months? Will you give up an important competitive advantage by taking that extra 18 months? Are you OK waiting 18 extra months before getting feedback from customers about whether you’re even on the right track?

Maybe you’re fine moving the ship date. Sometimes that’s the right call.

But often, this is the point in the exercise where you take out your knife and start trimming scope. Maybe you’re not going to ship a pony. Maybe it’s time to ship a bicycle instead. With the knowledge of the time and financial cost of your minimally viable feature set, maybe you can find inspiration to pare down even more.

Trim scope until your estimates for the remaining work—which you have not goosed—give you a few days of margin under your ship date.

Now you can get to work, having a clear idea of what’s worth prioritizing and what can wait. You can repeat this process whenever you feel your project getting off track or losing steam. It helps me to track my requirements and dependencies on something tactile, like notecards or sticky notes, but you can document the process you’ve gone through using whatever systems make sense for you and your team.

But, Danilo, this isn’t the agile/scrum/[cargo cult methodology] way!

Whatever, man. I’m sure it isn’t. This is the way I know to get a project out the door on a date agreed upon by all parties, with scope documented for all parties, with trade-offs understood by all parties.

Within that, I’ve seen it work alongside tools like sprints, planning meetings, stand-ups, and retrospectives. I really like doing all of those. If you have existing systems you like to use to communicate and collaborate, you can keep them.

But you need a way to understand the relationship between costs, scope and outcomes, and to communicate those constraints across all functions. This is the basic approach I’ve long used for that. I hope it’s helpful in your adventures.

Further reading:

1.0 by Rands: “Shipping a 1.0 product isn’t going to kill you, but it will try.”