tl;dr: Stop overengineering, think of the first iteration of a feature, build it, ship it, get feedback, and improve it.
Building a software product isn't always straightforward. You might have a vision of how you want your product to look like, having thought of well-designed features that your users will love. Looking at features the competition offers makes you wonder how you could get to this point.
With this point of view, you start at the final feature and try to reverse-engineer your way to that. What you might not think of, however, is that your ideal vision might require dozens of iterations, taking in user feedback, adjusting, improving, and repeating this process. Building a completely polished feature from the get-go could require more effort than you can allocate.
And then, there's a level of uncertainty, still. You might not be completely sure whether your users would enjoy your exact idea, or if you should take another approach altogether. Investing a huge amount of time building something that you didn't validate with your customer is a huge risk, even more so, if you're in the early stage of your business.
To operate efficiently and build the right things, you have to achieve the highest possible velocity. Not only does this help you to build what really matters, but you can also adjust what should be built relatively quickly. In contrast, setting a goal of working on one specific feature for weeks without guaranteed returns would be madness.
Achieving velocity can only succeed when you build the first iteration of any feature you touch.
The First Iteration
Ambitious ideas are great, but building features often requires a couple of questions that need to be solved: What does the user really want, and what's the most straightforward way to solve it? You want to get meaningful results while spending as little time as possible, so you keep up the velocity.
This doesn't mean sacrificing quality, but concepts should be kept simple so you can interchange and alter internals quickly, instead of being held back by complex architecture or workflows.
Prioritizing high leverage tickets that take little time and yield high satisfaction is great, but sometimes you might not know what the user wants, so you need to experiment. Often, experimenting is all that it needs, so once again, velocity is crucial.
Instead of thinking "what is the final result I want to see", ask yourself "what does the user want, and what is the easiest way to get there?". Too often we try to tell ourselves that we might run into scaling issues, or that there's an edge case we should handle. We want to build testable software, that just works. But debating an unlimited backlog of questions that come up in terms of decisions just leads to no work being shipped.
And shipping is the most important thing we need to do, so we want to ship often.
Let's say we want users to upload an image for their profile picture. We could think of complicated distributed systems, image processing queues preparing the image in different sizes, CDN layers to handle caching, but in the end, we just want to take in an image file, store it, and access it. In S3 terms, PUT, GET.
Of course, this is somewhat simplified, but the full solution doesn't look much different. Thinking about the first iteration is harder than we think because we've come to expect polished systems that never fail, handle all use cases, and satisfy users. What we fail to see is the hard work teams had to put in to get to this point.
If we're just starting out, we need to work on the game from the start, instead of thinking about how we'll look once we reach the finish line.
Simple, Functional, Ready to Ship
Building the first iteration of any feature has another set of benefits: It's easily understandable, can be swapped out for more complex situations if it proves to be the right track, and leads to a unit of work that can be shipped in hours or days rather than weeks or months of extensive planning, testing, building, and QA.
You can spend efforts on improving and polishing once you're certain that it will lead to the desired outcome (user satisfaction, higher retention, etc.). Until that point is reached, do yourself a favor and commit less to quality and perfection, rather focus on quantity.
Testing multiple attempts with a strong foundation allows you to settle on a couple of approaches you want to keep, that can be extended to full-fledged features.
Putting it all back together, it's honestly rather straightforward: If you think you need a specific feature, find the most straightforward version of it, the first iteration, build it, ship it, get feedback, and see whether you were right. If that's the case, congratulations, you can now build the complete feature. Otherwise, you merely spent a couple of hours or days and can still change the plan.