A common cycle that products go through is:
- Someone builds an easy to use, slightly opinionated product.
- It gains adoption because it perfectly solves a problem for a set of users.
- As it grows, to gain even more adoption, it must support more use cases.
- Additional features are added and the product becomes more complex.
- Eventually, it becomes so complex that others see opportunity in making a simpler version of it.
- A new, easy to use product is created and starts to gain adoption.
- Go back to step 2
You can see this with a product like AWS, which first started with just S3 and EC2. And now…
…let’s just say it’s more complicated. It took me almost 20 seconds to scroll through just the services they provide.
On the other hand, newer products like fly.io and Vercel deliver a significantly simplified experience for a few specific use cases while providing features they deem as most valuable, like global deployment. It’s possible to do that in AWS, but it’s nowhere near as straightforward.
In fact, one of your first steps to do this in AWS is deciding which AWS service to use. If you wanted to understand how AWS EC2 differed from the competition, you might be surprised that 8 out of the 10 top searches for “aws ec2 vs” are other AWS products.
Avoiding complexity at all costs
The challenge for these newer companies is now maintaining this simplicity as they grow. It makes sense to start with something as simple as, “Give me a Next.js app and we can deploy it globally” but you can imagine all the different complex feature requests people will have over time. Maybe someone wants preview deployments only visible from their VPN. Then another person wants a solution for storing data, but also needs full control over what country the data is stored in. And the product still needs to be fast!
One way to avoid becoming a giant, bloated product is to decide what your core competencies are and stick to them. Vercel’s guide to file storage is a great demonstration of that. It acknowledges that it’s a common workflow that users will care about. However, it doesn’t link to a way to store data within Vercel. Instead, it tells you to get an external provider, here are some examples, best of luck, you got this.
Sure, it might not be too challenging for Vercel to add support for storing files. They can probably get away with just wrapping an underlying provider, like S3, to store files on behalf of their customers. Vercel could even charge a small premium on top of the cost and when they get enough customers and data to qualify for a volume discount, make even more money.
The problem, though, is that once you add this feature, you may be stuck supporting it forever. While it may be easy to add, it actually takes a lot of organizational effort to remove. Referring back to the data storage example, if Vercel decided to remove it, they would first need to coordinate with their customers to move their data to a new location. They would also need to communicate the end of life timeline way in advance and send reminders to their users. A nice touch would be to provide examples of how to store data in both the old and new store temporarily for zero-downtime switching. And their customer success teams would need to deal with angry people upset at the extra work they would now have to do.
These are just some of expected costs of removing a feature. Plus, in an environment where adding new features is generally considered a sign of progress, it can be difficult to defend a plan where you spend dev time removing them.
The cost of accumulated complexity
Ok, but what’s so bad about supporting a feature like data storage forever? People and prospective customers want it, right? The problem is that every feature comes with a maintenance cost and overhead. Want to roll out a free plan or deal for startups? Don’t forget about the storage cost. Can you give that away for free or do you need to gate it by a paid plan?
And the complexity isn’t just internal, it’s also visible to your users. Users who don’t care about storage will now see it as an option, adding noise to their user experience. This isn’t bad when it’s just one feature, but if we look back at AWS’s console we can see the long term consequences. When a product becomes too complex to use, your users might start to look for a simpler experience, and you just may become the example product everyone’s looking for an alternative to.
This isn’t to say you should never add new features. It will be necessary to change, update, and adapt your product if you want to continue to grow. However, the takeaway is to think critically about each feature proposal. Does it match the company mission and add value to your product or will it distract from it? Will you be able to sustainably support it over time or does it only provide a temporary benefit? So, the next time you are about to rush out a new feature because a VIP customer says they absolutely have to have it—take a step back, decide if it’s really something you want to support forever, and don’t be afraid to say no.