My most frequent mistake in the last three years was separating services too early. Be it in the context of applications or even modules/packages in code bases. Most of the architectural mistakes I made were in pursuit of trying to anticipate a change in requirements or scale instead of trying to solve the problem at hand. This applies to both infrastructure and code bases.

Enterprises, including small startups, are complex and often behave like ecosystems. If your company has a digital product and you need to start a new project as a new application, think carefully about why you are doing that instead of just adding a module to an existing project/monolith. Every layer of separation between systems is costly, be it on developer experience (DX), ease of deployment (managing multiple app versions), schema migrations, or communication between systems; these problems emerge when separating applications.

How systems communicate, keeping their data in sync, and sharing code between apps are all concerns that, if not addressed immediately or even if you think those cases are not going to happen, will cause issues. The day someone asks for a dashboard with data from both applications, you will have to engineer a way to aggregate all of that data and behaviors into a single place.

So, to avoid these pains, avoid separating services early; in fact, you should only separate them when you have to.