100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What is the Database-per-Service Pattern?

Learn the database-per-service pattern: private databases per microservice, polyglot persistence, and cross-service transaction trade-offs.

mediumQ203 of 224 in System Design Est. time: 5 minsLast updated:
Open Code Lab

Expected Interview Answer

The database-per-service pattern means each microservice owns and exclusively accesses its own private database, so no other service can read or write its data directly, forcing all cross-service data access to go through the owning service’s API.

In a monolith, a single shared database is common, but as a system decomposes into microservices, letting multiple services read and write the same tables recreates tight coupling at the data layer even after the code has been split apart, since a schema change in one service can silently break another. The database-per-service pattern enforces that each service’s data is truly private: other services must call its API to get or modify that data, never query its tables directly. This lets each service choose the database technology best suited to its needs (polyglot persistence), evolve its schema independently, and scale its storage separately from every other service. The trade-off is that operations spanning multiple services, like a transaction touching orders and inventory, can no longer use a simple local database transaction and instead require patterns like sagas or eventual consistency through events.

  • Enforces true service autonomy: a service’s schema can change without breaking other services
  • Allows polyglot persistence, choosing the best database technology per service’s workload
  • Enables independent scaling of storage per service based on its own load
  • Prevents accidental tight coupling at the data layer that undermines microservice boundaries

AI Mentor Explanation

The database-per-service pattern is like each franchise keeping its own private player fitness records that no other franchise can query directly, only request through an official medical liaison. If a rival franchise wants injury history on a player, they cannot pull the records themselves; they must ask through the liaison, who decides what to share. This keeps each franchise free to reorganize its own record-keeping however it likes without breaking anyone else’s systems. That strict data ownership, with access only through an official channel, is exactly what the database-per-service pattern enforces between microservices.

Step-by-Step Explanation

  1. Step 1

    Assign data ownership per service

    Each microservice is designated the sole owner of a specific set of tables or a dedicated database instance.

  2. Step 2

    Block direct cross-service access

    No other service is granted credentials or network access to query the owning service’s database directly.

  3. Step 3

    Expose data via API

    Any service needing that data must call the owning service’s API, which enforces its own validation and business rules.

  4. Step 4

    Handle cross-service consistency separately

    Multi-service operations use sagas, events, or eventual consistency instead of a shared local database transaction.

What Interviewer Expects

  • States clearly that direct cross-service database access is forbidden, only APIs are allowed
  • Mentions polyglot persistence as a benefit (each service picks its own database technology)
  • Acknowledges the trade-off: cross-service transactions require sagas or eventual consistency
  • Distinguishes this from a shared database, which recreates coupling even after code is split into services

Common Mistakes

  • Assuming microservices automatically implies separate databases without stating it must be deliberately enforced
  • Not mentioning the loss of easy multi-table ACID transactions across services
  • Forgetting to mention the saga pattern or eventual consistency as the resulting trade-off
  • Confusing “separate schema in the same database instance” with true logical/physical isolation

Best Answer (HR Friendly)

The database-per-service pattern means each microservice has its own database that no other service is allowed to touch directly. If another service needs that data, it has to ask through an API instead of querying the database itself. This keeps services truly independent, so one team can change their database schema without breaking anyone else’s code, though it does mean transactions spanning multiple services need a different approach than a simple database transaction.

Code Example

Cross-service data access via API, not direct database query
# WRONG: order-service directly querying inventory-service's database
# cursor.execute("SELECT stock FROM inventory.products WHERE id = %s", [product_id])

# RIGHT: order-service calls inventory-service's API instead
import requests

def check_stock(product_id: str) -> int:
    response = requests.get(
        f"https://inventory-service.internal/api/products/{product_id}/stock"
    )
    response.raise_for_status()
    return response.json()["availableStock"]

def place_order(product_id: str, quantity: int):
    stock = check_stock(product_id)  # data crosses the boundary via API only
    if stock < quantity:
        raise ValueError("Insufficient stock")
    # order-service writes only to its own private orders database
    orders_db.insert_order(product_id, quantity)

Follow-up Questions

  • How do you implement a transaction that spans two services when each owns its own database?
  • What is the saga pattern and how does it relate to database-per-service?
  • What are the trade-offs of polyglot persistence when each service picks a different database technology?
  • How would you migrate a shared monolith database into per-service databases incrementally?

MCQ Practice

1. Under the database-per-service pattern, how must another service access a service’s data?

The pattern strictly requires that other services go through the owning service’s API, never query its database directly, to preserve true autonomy.

2. What is a key trade-off introduced by the database-per-service pattern?

Because each service’s data lives in a separate database, multi-service operations cannot rely on a single local transaction and instead need sagas or eventual consistency.

3. What benefit does database-per-service enable that a shared database does not?

Since each service owns its database independently, teams are free to pick the database technology, SQL, document, graph, best suited to that service’s workload.

Flash Cards

What is the database-per-service pattern?Each microservice owns a private database; other services access its data only through its API, never directly.

Why does a shared database undermine microservices?It recreates tight coupling at the data layer, so one service’s schema change can silently break another.

What trade-off does this pattern introduce?Cross-service transactions need sagas or eventual consistency instead of a simple local database transaction.

What does “polyglot persistence” mean here?Each service can independently choose the database technology best suited to its own workload.

1 / 4

Continue Learning