Courseiva
PCDChapter 2 of 15Objective 2.2

Microservices Architecture and Decomposition

How do you build an application that can handle millions of users without falling over, and that you can update without taking the whole system offline? That is the core problem microservices architecture solves, and it is a central topic in the Google Professional Cloud Developer exam. For anyone studying for PCD, understanding how to design applications as small, independent services is critical because Google Cloud provides dozens of tools (like Google Kubernetes Engine and Cloud Run) that are purpose-built to run this style of architecture.

12 min read
Intermediate
Updated Jul 23, 2026
Reviewed by Johnson Ajibi· Senior Network & Security Engineer · MSc IT Security

A simple way to picture Microservices Architecture and Decomposition

The Restaurant Kitchen Analogy

Have you ever been to a restaurant where one chef tries to do everything at once, and the food takes forever to arrive? That single, overloaded chef is like a 'monolithic' application — one huge program where every task (taking orders, cooking pasta, grilling steak, washing dishes) is handled in a single, tangled piece of code. If that chef gets sick, the whole kitchen shuts down. If the restaurant gets busy, the chef can't just add more hands easily. Now imagine a different kitchen: a 'microservices' kitchen. Here, there is a dedicated team for starters (the salad station), another for mains (the grill station), another for desserts, and another just for managing online orders. Each station has its own small menu, its own equipment, and its own chef. If the grill station breaks down, the salad station keeps working — you just can't serve steak that night. If the restaurant suddenly gets popular for desserts, you can hire two more pastry chefs without re-training the grill chef. Each team communicates by passing tickets (events) through a shared board (message queue). This modular kitchen is the perfect analogy for microservices architecture: small, independent services that each own a single business capability and run in their own process, communicating over a network.

In the real world of Google Cloud, this means instead of one giant application that you must deploy and scale as a whole, you break it into small services — like an 'order service', a 'payment service', and a 'user service'. Each can be developed, deployed, and scaled independently. If the payment service gets overloaded during a sale, you can add more copies of just that service without touching the others. This is the essence of microservices decomposition: taking a monolith and chopping it into manageable, independent pieces.

How It Actually Works

Let us start with the problem that microservices solves. Before microservices became popular, most applications were built as a 'monolith'. A monolith is a single, large computer program where all the code — for the user interface, business logic, data access — is bundled together and deployed as one unit. Imagine a big, heavy block of marble. If you want to change one small feature, you have to edit the whole block, recompile it, and deploy the entire thing again. If one part of the monolith has a memory leak (a bug that slowly uses up all the computer's memory), the whole application crashes. Scaling a monolith is inefficient: you have to make the whole thing bigger (vertical scaling), even if only one part of the application is actually busy.

Microservices architecture is the opposite. The word 'micro' means small, and 'service' means a self-contained unit that does one thing. In this architecture, you break your application into many small, independent services. Each service runs its own process and exposes a well-defined 'API' (Application Programming Interface) — a contract that other services use to talk to it. For example, a typical e-commerce application might have these microservices: a 'User Service' (handles login and user profiles), a 'Product Catalogue Service' (lists items for sale), a 'Shopping Cart Service' (tracks what the user wants to buy), an 'Order Service' (processes the order), and a 'Payment Service' (handles credit card transactions).

The key term here is 'decomposition' — breaking a large problem into smaller pieces. When you design a microservices architecture, you are essentially decomposing a business domain into bounded contexts (a term from Domain-Driven Design). Each service owns its own data and business logic. For instance, the 'Payment Service' might store credit card tokens in its own database, and never let the 'Shopping Cart Service' touch that database directly. This independence is crucial for resilience: if the 'Payment Service' goes down, users can still browse products and add items to their cart. They just cannot check out until payment is restored.

Communication between microservices happens over a network, typically using lightweight protocols like HTTP/REST or gRPC. They often use asynchronous messaging (for example, with a message queue like Pub/Sub) to avoid blocking each other. This is different from a monolith, where functions communicate by calling each other directly in the same process, which is much faster but creates tight coupling (they cannot be separated).

Why does this matter for the Google Professional Cloud Developer exam? Because Google Cloud provides specific services to run microservices effectively. You need to understand concepts like:

'Containerisation': packaging each microservice with its dependencies into a lightweight, portable unit called a container (like a Docker container).

'Orchestration': using a platform like Google Kubernetes Engine (GKE) to automatically deploy, scale, and manage your containers.

'Service Discovery': how services find each other's network addresses (since containers can be created and destroyed dynamically).

'API Gateway': a single entry point that routes requests from clients (like a mobile app) to the correct microservice.

'Resilience patterns': techniques like circuit breakers (preventing a failing service from causing cascading failures) and retries (automatically retrying a failed request).

The exam tests your ability to design these architectures. For example, you might be given a scenario about a monolithic application that is struggling with slow deployments and frequent outages. The correct answer would involve decomposing it into microservices, using containers, and deploying them on GKE. You must know when a monolith is still appropriate (e.g., for simple applications with few users). The PCD exam loves to test the trade-offs: microservices give you scalability and resilience but introduce complexity in networking, data consistency, and debugging.

A microservices architecture for an e-commerce app: client requests go through an API Gateway, which routes to independent services, each with its own database. Asynchronous events flow via Pub/Sub for tasks like sending emails.

Walk-Through

1

Identify Business Capabilities

List all distinct functions your application performs (e.g., user management, order processing, inventory, notifications). Each function is a candidate for a separate microservice. This is the decomposition step driven by the business domain.

2

Define Service Boundaries and APIs

For each candidate service, define its responsibility, the data it owns, and the API it exposes to other services. An API is a set of endpoints (like HTTP URLs) that other services call. This step creates the contract between services.

3

Choose Communication Pattern

Decide whether services will talk synchronously (HTTP request/response) or asynchronously (sending events via a message queue like Google Cloud Pub/Sub). Use async for non-critical paths (like notifications) to avoid making the whole system slow due to a slow service.

4

Containerise Each Service

Package each microservice with its code and dependencies into a Docker container. This ensures it runs the same way in development, testing, and production. Write a Dockerfile that specifies the base image (e.g., Python or Java) and how to start the service.

5

Deploy and Orchestrate on GKE

Use Google Kubernetes Engine to automatically deploy, scale, and manage your containers. Write Kubernetes manifests that define how many copies (replicas) of each service to run, and how to restart them if they fail. This is what provides resilience.

6

Set Up Observability

Configure logging (Google Cloud Logging), metrics (Google Cloud Monitoring), and tracing (Cloud Trace) for each service. Without observability, debugging a microservices system is nearly impossible. You need to see which service is failing and why.

What This Looks Like on the Job

Imagine you work for a company called 'RetailSphere' that runs an online shop. Initially, they built a monolith — one Ruby on Rails application that handles everything: listing products, managing user accounts, processing payments, and sending confirmation emails. Over time, the codebase grew to over a million lines of code. Deploying a new version takes three hours, and a single bug in the payment logic can bring down the entire website. The company decides to migrate to microservices on Google Cloud.

Here is what an IT professional actually does in this scenario:

1.

Identify bounded contexts: They sit down with the business team and list the distinct capabilities of the application: product management, user accounts, shopping cart, order processing, payment, email notifications, and inventory tracking. Each becomes a candidate microservice.

2.

Decompose the database: Instead of one giant database, they split it. They create a separate database schema (or even a separate database instance) for each service. For example, the Product Service only accesses the products database. The User Service has its own user database. This prevents one service from accidentally corrupting another's data.

3.

Define APIs: For each service, they design a RESTful API (a set of URL endpoints that accept HTTP requests). For example, the Order Service might have an endpoint like 'POST /orders' to create a new order. They document these APIs so that other services know how to interact.

4.

Containerise using Docker: They create a Dockerfile for each service, specifying the runtime environment (e.g., Python 3.9) and the service's code. This makes each service portable and repeatable.

5.

Deploy on Google Kubernetes Engine (GKE): They create a Kubernetes cluster — a group of virtual machines that run containers. They write Kubernetes manifests that define how many copies (replicas) of each service should run, how to expose them to network traffic, and how to perform health checks.

6.

Set up a message queue: For asynchronous tasks, they use Google Cloud Pub/Sub. For example, when an order is placed, the Order Service publishes a message to a 'new-order' topic. The Email Service subscribes to that topic and sends a confirmation email. This decouples the services: even if the Email Service is slow, the Order Service does not wait for it.

7.

Implement an API Gateway: They deploy a Google Cloud API Gateway (Apigee or a simple load balancer) as the single entry point for client applications. The gateway routes requests to the correct service based on the URL path. This also handles authentication, rate limiting, and logging.

8.

Monitor and observe: They set up Google Cloud Monitoring and Logging to see metrics like request latency and error rates for each individual service. If the Payment Service becomes slow, they can see it immediately and scale it up without touching the Product Service.

In this real-world scenario, the professional's primary job is about 'decomposition' and 'infrastructure as code'. They write configuration files that describe the desired state of the system (e.g., 'I want three replicas of the Order Service'). The cloud platform handles the rest. The exam tests your ability to make the same architectural decisions on paper.

How PCD Actually Tests This

The Google Professional Cloud Developer exam tests 'Microservices Architecture and Decomposition' under objective 2.2, which focuses on designing for scalability and resilience. The exam is scenario-based: you read a business requirement and choose the best technical solution. Here is exactly what you need to know for the exam.

First, the exam loves to test the concept of 'bounded contexts' and 'domain-driven design'. They will describe an application (often an e-commerce or media platform) and ask you to identify which pieces belong in separate microservices. The trap is that they will include services that are too fine-grained (like a service for just one field) or too coarse (like keeping two unrelated functions together). The correct pattern is a service that owns a single business capability and its data.

Second, they test 'decomposition strategies' commonly asked exam topics:

Decompose by business capability (e.g., order management, user management).

Decompose by subdomain (e.g., shipping, billing).

Decompose by transaction boundaries (what operations need to be atomic? If two operations must succeed or fail together, they probably belong in the same service, or you need a saga pattern).

The exam also heavily tests 'when NOT to use microservices'. Common traps include:

Assuming microservices are always better. They are not. For a small team with a simple application, a monolith with a single database is simpler and faster to develop. Microservices introduce network latency, distributed transaction complexity, and operational overhead.

Believing that microservices must always communicate synchronously (i.e., making an HTTP request and waiting for a reply). The exam often expects you to use asynchronous communication (like Pub/Sub or a task queue) for long-running or non-critical operations.

Key definitions you must memorise:

'Service': A small, independently deployable unit that performs one function.

'Decomposition': The process of breaking a system into smaller, manageable parts.

'Coupling': How much services depend on each other. Low coupling is good.

'Cohesion': How closely related the functions within a service are. High cohesion is good.

'API Gateway': A reverse proxy that routes client requests to the appropriate service.

'Service Mesh': A dedicated infrastructure layer for managing service-to-service communication (e.g., Istio on GKE).

'Circuit Breaker': A pattern that prevents a service from calling a failing service repeatedly, giving it time to recover.

'Saga Pattern': A sequence of local transactions where each transaction publishes an event that triggers the next step. It handles distributed transactions across services without locking.

Third, the exam tests 'how to handle state and data'. Traps include:

Trying to use a single database across multiple services (violates independence).

Assuming that services can share database tables directly (they should not).

Not considering data duplication — each service may need its own copy of some data for speed.

Fourth, they love to ask about 'deployment and scaling'. Know that:

You can scale each microservice independently using 'horizontal scaling' (adding more container replicas).

'Google Kubernetes Engine' (GKE) is the go-to service for orchestrating microservices.

'Cloud Run' is a simpler option for stateless microservices that auto-scales to zero.

The exam will present a scenario with a bottlenecked monolith and ask which service to extract first. The correct answer is usually the service that is most resource-intensive or changes most frequently. There is always an option that is too radical (e.g., splitting into 50 services immediately) which is wrong. The pattern is 'strangler fig' — gradually replace pieces of the monolith.

Key Takeaways

Microservices architecture decomposes an application into small, independent services, each owning a single business capability and its data.

The main benefits of microservices are independent scalability, independent deployability, and fault isolation — one service crashing does not bring down the whole system.

Communication between microservices should ideally be asynchronous using message queues to reduce coupling and improve resilience.

Each microservice must have its own database schema (or table) to prevent tight coupling; sharing a database between services breaks the architecture.

The 'strangler fig' pattern is the recommended approach for migrating a monolith to microservices — gradually replacing pieces instead of a big-bang rewrite.

For the PCD exam, remember that deciding between synchronous and asynchronous communication is a frequent exam trap — always favour async for long-running or loosely coupled tasks.

Use Google Kubernetes Engine (GKE) or Cloud Run to deploy and manage microservices at scale on Google Cloud.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Monolith

Single codebase all in one deployable unit

Scaling requires scaling the entire application

A single bug can crash the whole application

Microservices

Multiple small, independent deployable units

Each service can be scaled independently

Fault isolation: one service failure does not affect others

Synchronous Communication (HTTP)

Caller waits for a response before continuing

Tightly couples the caller and responder

Simple to implement for request-reply patterns

Asynchronous Communication (Pub/Sub)

Caller sends a message and continues immediately

Loosely couples services (they do not need to be running at same time)

Better for long-running or fire-and-forget tasks

Shared Database (anti-pattern)

Multiple services read/write the same tables

Any service change can break others' data

Creates tight coupling at the data layer

Database per Service

Each service has exclusive access to its tables

Service can change schema independently

Enforces true separation and independence

Vertical Scaling

Add more power (CPU/RAM) to the same machine

Has an upper limit (single machine size)

Often involves downtime during upgrade

Horizontal Scaling

Add more instances of a service (e.g., more containers)

Theoretically unlimited scaling (just add servers)

Works best with stateless services and load balancers

Strangler Fig Pattern

Gradually replace pieces of the monolith over time

Less risky; system stays operational during migration

Allows incremental testing and feedback

Big Bang Rewrite

Rewrite the entire system from scratch in microservices

High risk; can lead to long delays or project failure

Difficult to validate until the full system is ready

Watch Out for These

Mistake

Microservices must be very small — like a few lines of code each.

Correct

Microservices should be sized around a single business capability. 'Small' is relative; a service can be hundreds or thousands of lines of code as long as it does one cohesive job.

The word 'micro' is misleading. Beginners think it means 'tiny', but the real goal is 'independent and focused', not 'as short as possible'.

Mistake

Microservices always communicate via HTTP/REST.

Correct

While HTTP is common, asynchronous messaging (like Pub/Sub or a message queue) is often better for resilience and decoupling.

Many beginners only know HTTP from web development, so they assume it is the only way. The exam heavily tests the trade-off between synchronous and asynchronous communication.

Mistake

Each microservice must have its own separate database server/instance.

Correct

Each service should own its data schema, but multiple services can share the same database server as long as they access only their own tables. The key is logical separation, not necessarily physical isolation.

Beginners hear 'own database' and think of separate server clusters, which is expensive and over-engineered. The principle is data ownership, not hardware.

Mistake

Microservices fix all performance problems automatically.

Correct

Microservices add network latency and complexity. They improve scalability and fault isolation, but they can make performance worse if not designed carefully (e.g., chatty service calls).

People assume that adding more servers always makes things faster. In reality, microservices introduce overhead that must be managed with patterns like caching and bulkheading.

Mistake

If you containerise your monolithic app, it becomes a microservices architecture.

Correct

Containerising a monolith just gives you a containerised monolith. Microservices require decomposing the application into independently deployable units.

Beginners confuse the technology (containers) with the architecture (microservices). You can run a monolith in a container, but it is still a monolith.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

How small should a microservice be?

A microservice should be just large enough to own one business capability and its data. It could be 200 lines or 2,000 lines — the key is that it does one thing well and can be deployed independently.

Can two microservices share the same database?

They should not share the same database schema. Each service must own its data to remain independent. They can still use the same database server (e.g., the same MySQL instance) as long as they access only their own tables.

What is the difference between microservices and a service-oriented architecture (SOA)?

SOA was an earlier approach where services were often large and shared a common communication bus (like an ESB). Microservices are smaller, independently deployable, and prefer lightweight communication (HTTP/gRPC) over a heavy bus.

When should I NOT use microservices?

For simple applications, early-stage startups, or small teams with limited operational experience, a monolith is usually better. Microservices add complexity in networking, data management, and debugging that is not worth it for a small system.

What does 'stateless' mean in microservices?

A stateless service does not store any user session data between requests. Any state (like shopping cart contents) is stored in an external database or cache. Stateless services are easier to scale because any instance can handle any request.

What is a sidecar pattern in microservices?

A sidecar is a helper container that runs alongside your main service container in the same pod (on Kubernetes). It handles cross-cutting concerns like logging, monitoring, or network routing, so your main service code stays clean and focused on business logic.

Terms Worth Knowing

Keep going

You've finished Microservices Architecture and Decomposition. Continue through the PCD study guide to build a complete picture of the exam.

Done with this chapter?