So You Want to Build Microservices? Here’s Where to Begin

In my previous blog, I shared a simple way to understand the difference between monolithic and microservices architecture. I used the idea of a toy castle to show how everything in a monolithic setup is tightly packed, and if you touch one part, the whole thing can get affected.

We saw how breaking it into smaller, independent parts, just like separate rooms in a castle, can help teams build faster, scale better, and avoid unnecessary chaos when systems grow.

If you haven’t read it yet, feel free to check it out here:
Microservices Architecture: Transforming Scalability and Flexibility Beyond Monolithic Systems

Now, the natural next question is, how do we actually design a microservices system from scratch?

Let’s walk through that step by step.


Don’t Start With Microservices

I know this might sound strange, but microservices are not always the right starting point. Just because something is trending doesn’t mean it’s the best fit for every project.

In the early stages of a product, a simple monolith is often easier to work with. You have:

  • One codebase

  • Less complexity

  • Easier debugging

  • Fewer moving parts

Once the system starts growing and it becomes harder to manage or scale, that’s when microservices make sense. Focus on solving the actual problem first. You don’t need ten separate services on day one.


Step 1: Understand the Business First

Before writing code or thinking about services, pause and understand what the system actually needs to do.

For example, in an e-commerce app, you may have:

  • Users

  • Products

  • Orders

  • Payments

  • Notifications

Each of these areas is a part of your business domain. These are usually the building blocks for your services. Think of them as logical boundaries, and they should work independently.


Step 2: Break It Down the Right Way

Let’s break it down properly.

A microservice should be loosely connected to others, not tied at the hip. Let’s take a few examples:

  • UserService: handles login, signup, and profile

  • ProductService: takes care of product listing and search

  • OrderService: manages cart, checkout, and order history

  • PaymentService: connects to payment gateways like Razorpay or Stripe

A good microservice should have these 3 key qualities:

1. Does One Main Job

Each microservice should be responsible for one clear piece of functionality.

For example:

  • A UserService should only handle user-related work like signup, login, and profile.

  • A PaymentService should only deal with payment processing and nothing else.

If your service is doing too many things, it becomes harder to maintain, test, and change. Keeping it focused makes life easier.

2. Can Work on Its Own

A good microservice should not go down just because another service is down.

For example:

  • Your ProductService should be able to serve product details even if the ReviewServiceis having issues.

  • Your OrderService shouldn’t crash just because the notification system is slow.

This is where design really matters. Avoid hard dependencies unless absolutely needed. Use fallback responses, timeouts, or async queues when services need to talk to each other.

The key idea is to keep services focused and decoupled. If two services always need to talk to each other just to get basic work done, maybe the boundary isn’t right.


Step 3: Define Services Communications well

Microservices often need to talk to each other to get things done. There are two common ways to handle this:

1. Synchronous (real-time)

This is the usual API call, like REST or gRPC. One service calls another and waits for the response.

Example:
The OrderService asks the UserService for a delivery address before placing the order.

This works well when you need immediate data and the other service is reliable. But if the other service is slow or down, your request gets stuck too.

2. Asynchronous (event-driven)

Here, services send messages through tools like AWS SNS/SQS, or Kafka.

Example:
After a payment is successful, PaymentService sends out a “PaymentSuccess” event. OrderService and NotificationService listen to it and act on it.

This setup is more resilient, and services don’t have to wait on each other. It's better when tasks can run in the background.

What to use?

Start with REST if you're early in the build. It's simple and easier to manage.
Move to events when you want more flexibility and loose coupling.

Most real systems use a mix of both, based on the situation.


Step 4: One Service, One Database

This is important. Each service should own its data.

That means,

  • UserService has its own database

  • OrderService has a separate one

  • PaymentService maintains its own

Don’t make the mistake of sharing one big database across services. That creates dependency. Yes, some data might be repeated between services, but that’s okay. It gives each service full control and avoids surprises when one service changes something.


Step 5: Deployment Doesn’t Have to Be Fancy Initially

Don’t overthink DevOps from day one. Keep it simple.

Use Docker to containerize your services. Set up a basic CI/CD pipeline using whatever you're comfortable with: GitHub Actions, GitLab, or AWS CodePipeline.

You don’t have to deploy every service separately in the beginning. What matters is that you design them in a way where that separation is possible later.

Start with what works. You can always evolve it.


Common Mistakes to Watch Out For

Here are some things I’ve seen (and made) mistakes in the past:

  • Breaking the system into microservices too early

  • Making services talk too much to each other

  • Using a shared database across services

  • Ignoring logs and monitoring

  • Making breaking changes to APIs without versioning

If you can avoid even half of these, you’ll be in a much better place.


Quick Recap

  • Don’t jump to microservices unless the system really needs it.

  • Break your system by business domains, not by technical layers.

  • Keep each service focused and independent.

  • Use REST or messaging, depending on your need.

  • Give each service its own database.

  • Don’t overcomplicate deployments in the beginning.


Final Thought

Microservices are not about being fancy. They’re about managing complexity as systems grow.

They’re powerful, but only when done thoughtfully.

Start small. Keep things clean. And design with real use cases in mind.

0
Subscribe to my newsletter

Read articles from Syeda Rukhaiya Kulsum Ganihar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Syeda Rukhaiya Kulsum Ganihar
Syeda Rukhaiya Kulsum Ganihar