MicroservicePatterns.com
Decomposition · Advanced

Self-Contained Service

The Self-Contained Service pattern lets a service answer requests without synchronous calls to other services, by keeping a local copy of the data it needs, updated from their events.

Last updated

What is the Self-Contained Service pattern?

A self-contained service can handle a synchronous request without making synchronous calls to other services. It keeps a local, read-only copy of other services' data, updated from the events they publish, and it hands off any follow-up work by sending messages. To its caller it behaves like one reliable component.

What problem does the Self-Contained Service pattern solve?

If answering a request needs four other services to be up, your availability is the product of theirs and your latency is the sum. Taking those calls out of the request path means a slow or failed upstream does not stop you from answering.

How do you implement the Self-Contained Service pattern?

  1. List the synchronous calls a request makes today and the data each one returns.
  2. Subscribe to events from the services that own that data and store what you need locally.
  3. Answer requests from the local store. Send any work that can happen later as commands or events.
  4. Decide how stale each piece of data may be, and show freshness to users where it matters.
  5. Provide a way to rebuild the local copy from scratch, such as a replay or a bulk sync.

When should you use it?

  • A customer-facing endpoint needs high availability and low latency.
  • The data it needs from other services can be a few seconds out of date.

When should you avoid it?

  • The answer must reflect the latest committed state, such as an account balance before a withdrawal.
  • The upstream data is too large or changes too often to copy.

What do you gain?

  • Availability no longer depends on upstream services
  • Low, predictable latency
  • Upstream outages degrade freshness, not service

What does it cost?

  • Data is eventually consistent
  • Extra storage and event handling code
  • Upstream events become a contract you depend on

What are common mistakes with the Self-Contained Service pattern?

  • Copying entire upstream databases instead of the few fields you need.
  • No way to rebuild the local copy after a bug corrupts it.
  • Quietly falling back to synchronous calls when the copy is missing data.

Self-Contained Service in practice

Illustrative scenario · fictional company

Fernhill Apparel

Rendering a product page called pricing, stock, catalog and brand services synchronously. During sales, any one of them slowing down made product pages time out.

The product page service now keeps a local read model built from events those services publish. It answers from its own store, so it stays up when an upstream service is slow, at the cost of data that can be a few seconds stale.

Example decision record
Context
Customer-facing pages depend on synchronous chains of calls, which add latency and spread failures.
Decision
Build customer-facing query services as self-contained services that answer from local read models fed by events.
Consequences
  • Pages stay available when upstream services are slow or down.
  • Teams must design for read models that are briefly out of date.