Photo by the author

tl;dr – Work on tasks that will eliminate risk and reduce unknowns first.

Software development is a complex and unpredictable activity. Because there are a lot of moving parts, big problems may not present themselves immediately. Many technical challenges often don’t come up until other supporting work is done first. Usability issues may remain unforeseen until the bulk of an app has been written. These challenges can affect the schedule of the project if not tackled early as they can cause unnecessary re-work to be done.

Many of these challenges remain unknown simply because they are needlessly prioritized behind other work. Endeavor to constantly reduce risk by finding and completing high-risk work items first.

When breaking down your work into bigger pieces, assess the risk of each piece. Figure out what has the highest risk. These are the things that you understand the least. Ask yourself how much you know about the problem space. How many assumptions are you making? Are they valid? Are there a lot of moving parts? If so, can those parts work well together?

After coming up with a risk assessment, prioritize the highest risk items first. The goal in attacking the high risk tasks first is to learn and gather more information and then adjust your schedule, your designs, and your product goals as necessary.

Likely the biggest risk most products will have is the usefulness of the product itself. Is it something people actually want? How do you know? One way startups mitigate this huge unknown is to build a prototype (with a limited feature set and with basic UI) as soon as possible. Get it in your hands and potential customers’ hands early. You’ll likely find issues right away that you couldn’t see with static design mockups.

Another big risk is architecture. How should the product be built? If you aren’t familiar with the technical space, prototype using components as soon as possible. The goal is not to come up with a pristine architecture, but to just understand the problem space and see what is even possible with the tools and components available. Find out what the tolerances of each component are. Will it be enough for your goals? If you were planning on using open source components, do you have everything you need? The worst thing you can do here is to design at too high a level with limited knowledge of the space. Don’t commit to big decisions based on missing information.

In my experience, getting an end-to-end scenario working reveals so much. Plumbing, i.e. getting data from one place to another, is one of those things that is hard to theorize about and is only really knowable by writing code. Once you get a basic end-to-end scenario that uses most of the pieces of the stack you expect (even with prototype pieces in the middle), you will find out what components you’ll need and how to difficult or easy it is to connect them together. This will reveal more than a theoretical design ever could.

High risk work has a greater impact on the success of a product than anything else. It also means it’s harder to reverse these decisions, so it’s important to get them right earlier than later. As you complete more and more high risk work, the stability of your completion date should improve. How the final product and final software design will look should stabilize as well. Don’t let high risk and difficult-to-reverse decisions be made late in the project. Get those out of the way early!

In summary, map out what you need to do to complete your project. Figure out where the big unknowns (and big risk!) are and then prioritize those items first. Prototype as necessary to help validate your hypotheses, learn, and adjust your plan as you learn more. Repeat until you are done. Good luck!

These thoughts come from my own work experience, but many of the ideas weren’t obvious to me until I read Lean Software Development, so please read that for a more information.