System Design Space
Knowledge graphSettings

Updated: March 5, 2026 at 9:19 PM

Introducing Domain-Oriented Microservice Architecture

mid

Uber's 2020 architecture redesign: transition from monolith/distributed monolith to DOMA with domain boundaries, layered dependencies, gateway contracts and extension points.

Primary source

Uber Engineering, 2020

Original Adam Gluck article about Uber's architecture redesign and transition to DOMA.

Open source

DOMA (Domain-Oriented Microservice Architecture) is Uber's approach to operating a very large microservice ecosystem. The core idea is to design not a flat set of independent services but domain-oriented service collections with strict contracts, dependency layers, and explicit extension points.

Conceptually, this combines ideas from DDD and modular architecture, but applies them at the scale of thousands of engineers and services.

Uber architecture evolution

2012-2013

Monolithic architecture

Uber was operating two large services. As the organization grew from dozens to hundreds of engineers, availability risks, deployment risk, and change cost grew quickly.

  • Availability risk: failure in a large component affected a large share of the product.
  • Risky deployments with a large blast radius.
  • Weak separation of concerns across business capabilities.
  • Slow execution of business-logic changes.
2014-2017

Transition to microservices

The move improved reliability, ownership, and development speed at first. But at thousands of engineers, Uber faced a distributed monolith with high coupling.

  • Too many cross-service dependencies.
  • Difficult incident analysis across many teams.
  • Unclear ownership boundaries and data models.
  • Higher cognitive load for developers.
2018+

DOMA (Domain-Oriented Microservice Architecture)

Uber reframed its microservice system as one large distributed application and applied domain boundaries, layered dependency rules, explicit contracts, and extension mechanisms.

  • Design focus moved from single services to domains as design units.
  • Dependencies became controlled via layered design.
  • External interactions moved to gateway contracts.
  • Cross-domain integrations used extension points instead of tight direct coupling.

DOMA principles

Design around domains, not individual services

The primary design unit is a domain-level collection of services that delivers business value end-to-end. This simplifies ownership and roadmap planning.

Domains are grouped into layers

Upper layers may depend only on lower layers. This dependency rule limits cycles and reduces blast radius during changes.

Each domain exposes a clean interface via gateway

The gateway is the single entry point into the domain, stabilizing external contracts while allowing internal service evolution.

No direct cross-domain dependencies

No shared code and no shared data model between domains. Controlled extension points handle custom integrations.

DOMA layers at Uber

LayerPurposeExamples
Infrastructure layerCore capabilities needed in any engineering organization: storage, networking, observability, and platform primitives.Storage APIs, network primitives, infra identity, runtime tooling
Business layerShared business capabilities Uber needs as an organization, not tied to one specific LOB.Payment policies, fraud signals, user profile capabilities
Product layerCapabilities tied to a product line but not to one consumer-facing app instance.Ride request lifecycle, dispatch policies, driver supply logic
Presentation layerFunctionality directly tied to mobile/web user-facing features.App-specific flow orchestration and UX-specific business behavior
Edge layerSafe external exposure and client-aware adaptation of Uber services.Edge gateways, auth policies, API composition, request shaping

Core rule: services in upper layers may depend only on lower-layer services.

Contracts

Interservice communication patterns

Gateways and extension points only work when contract boundaries between teams are explicit and stable.

Open chapter

Gateway and extension points

Logic extension via plugins

Services inside a domain define plugin interfaces. Teams can add domain-specific checks without forking the core service flow.

Data extension via optional attributes

Core models can be enriched with domain-specific options to avoid direct schema coupling between domains.

Team-owned local extension points

Teams can define additional extension points inside their own domains while preserving contract control and lifecycle governance.

Practical gateway impact: a domain can evolve internal services without breaking consumers, as long as the external contract remains stable.

Outcomes at scale

  • Lower complexity by organizing around ~70 domains instead of managing 2200 services as flat units.
  • More predictable dependencies through layered design and strict dependency direction.
  • Easier domain migrations and independent releases thanks to stable gateways.
  • Lower developer cognitive load and faster incident localization.

When to choose monolith, microservices, and DOMA

Organization sizeDefault fitWhy
StartupMonolith / modular monolithLowest operational complexity, faster product-market fit iterations, lower change cost.
Mid-size companyClassic microservicesIndependent delivery for multiple teams and better isolation of technical risks by subsystem.
Large organizationDOMA-style architectureNeeds scalable governance for thousands of engineers, domain ownership boundaries, and lower systemic coupling.

Common DOMA adoption mistakes

Calling any random group of services a domain without clear business boundary and ownership model.

Building a gateway as a thin proxy without contract discipline, versioning, and SLA commitments.

Keeping shared database/shared schema between domains while labeling it as DOMA.

Defining layers formally but violating dependency direction (upper layers calling peers/upper layers).

Related materials

Enable tracking in Settings

System Design Space

© 2026 Alexander Polomodov