We were just days away from launching a web application that would allow people to put themselves on a waiting list for affordable housing. Hundreds of thousands of people were expected to visit the site over the course of 2 or 3 days. We'd been working for months on a highly available system and were ready to be done.
Have you ever worked on a product so long that pretty much you get to the point where you don't care about anything except getting done with it? Even if maybe you know there may be a place where maybe you should kind of sort of do something to protect people from a potential issue?
We were so close to done we could feel it. And then we realized that if a person came back and applied a second time, we'd have to stop them. And that meant we'd have to do some sort of round-trip to check for duplicates. But we'd worked to get rid of every round trip so that this app would perform flawlessly.
And neither of us wanted to do it. But we knew we had to.
But it was the right thing to do.
In retrospect it's clear there was no other answer. But let's be honest, between you and me, I could have justified why we didn't want the round trip call and told someone to look for duplicates in Excel later. Right? I could have pulled that off. I can be persuasive.
But the right answer was the right answer. So we created the feature. And that meant thinking about the best, most lightweight, fastest, most cacheable approach to checking for duplicates. And it added a few days of coding.
Right when we didn't want to do any more coding.
And then 80,000 people hit the site over a few days with hundreds (if not thousands) of duplicate efforts.
I've not always chosen well.
I wish I could tell you that I've always chosen correctly, but it's not true.
One time we knew we should probably build an API and then build our application on top of the API – that way others could use the API as well. It was clear as day. But there was no formal request for an API, so I did what you would likely never do. I just skipped it and we built the application without an API. And then later started getting the logical (and predictable) requests for one.
Which all comes down to one truth. One I spilled in the title of this post.
Don't take the easy road when building new products.
It's Minimal VIABLE Product
In our efforts to create the most minimal viable products, sometimes I watch people create minimal, non-viable, almost-products. And then spend more energy pitching, talking, and explaining (justifying) why it made sense to drop a core feature.
Alternatively, sometimes it's not a desire to skip a feature that drives the bad decision-making. Other times it's simply that between the choice to do something really awesome (but time-consuming) or something that's passable (and a heck of a lot easier), we choose easy.
No one will critique us. We can make the logical case for it. But we know better.
At least I do. I know when I've taken the easy road.
Building new products the right way
I'll end this post with a good happy ending – one I didn't really discover until today.
In looking over a few of our recent projects, I reviewed both costs and revenues. I looked at a project we did in 2011 that took all year. It was one of the most expensive products I imagined we'd built – because every time we had a choice, we took the harder path to really solve core issues. Instead of one project, it ended up being 4 or 5 modules. And my most expensive engineers had been on the project (for a whole year).
Well, today I did the review and the cost of development (because we stayed very focused and closely aligned with our clients in co-creating the solution they were looking for) was far less than I had imagined. And more importantly, we'd sold (in three years) three times the amount of money we'd invested to build the product.
When you take the hard road, solve real problems, and focus on what really defines a minimal, truly viable product, you'll often find yourself in a good place.