Microservices are a good solution to a specific set of problems: large engineering teams working on shared systems that need to deploy independently, different parts of a system with genuinely different scaling requirements, organizational boundaries that map cleanly to service boundaries. None of those problems exist in an MVP.
What microservices actually require
To run multiple services, you need something to route traffic between them. You need each service to be able to find the others. You need a way to trace a request that touches three services, because when something breaks you need to know which service caused it. You need a deployment system that can coordinate multiple independent deployments. You need a local development environment that can spin up all the services at once.
Each of those is a real engineering problem. Not an insurmountable one, but a problem you have to solve before you can build anything the users will actually use. You're paying infrastructure complexity tax before you have product complexity to justify it.
What a monolith actually gives you
One codebase. One deployment. One database. One set of logs to look at when something breaks. One local development command. When you want to understand how the system works, you read one codebase, and the relationships between different parts of it are visible in the code rather than inferred from network traffic.
When something breaks at 3am, a monolith is much easier to debug than a distributed system. The failure mode is simpler. The recovery path is clearer.
The scaling objection
The standard objection is: "but what about when we need to scale?" Two things.
First, most MVPs never reach the scale where a monolith becomes the actual bottleneck. A well-configured Postgres instance handles a lot. A single well-sized server handles a lot. The scale problem is a good problem to have because it means the product worked. Most products don't get there, and the ones that do usually have months of runway to address it before it becomes critical.
Second, if you do reach that scale, you have a very different set of resources available to you than you had when you started. You have real traffic data, which tells you which parts of the system actually need to scale. You have engineers who know the codebase. You have revenue to pay for the migration. Splitting the monolith when you have a specific reason is a much better trade than building distributed infrastructure when you're guessing about what will need to scale.
The modular monolith
The answer is not a big ball of mud. Write your monolith as if the modules are separate concerns: user management in one directory, billing in another, notifications in another. Keep the boundaries clean. Don't let one module reach into another module's internals directly. Use the module's public interface.
This gives you most of the maintainability benefits of microservices without the operational overhead. If you ever have a concrete reason to extract a service, the seams are already there. The extraction is a refactor, not a rewrite.
Companies that build microservices from day one almost always consolidate within 18 months. They pay the complexity cost building it, then pay it again tearing it back down. The modular monolith is not the exciting choice. It's the one you won't regret.