Skip to content

Uber: organizing 2,200 microservices into domains

Organization Uber
Period Described in 2020
Problem About 2,200 critical microservices with tangled dependencies
Architecture Domain-Oriented Microservice Architecture (DOMA): domains, layers, gateways and extensions
Patterns Microservices, domain-driven design, API gateways

Uber’s move to microservices let teams work independently, but with around 2,200 critical services new problems appeared:

  • Finding the cause of an incident could mean working through about 50 services owned by 12 teams.
  • Call chains ran many layers deep, so a slowdown far away could spread upward.
  • A simple feature often needed changes in several teams’ services; one complex integration needed ten.
  • Teams changed each other’s services and data models, creating groups of services that had to be deployed together: a distributed monolith.
  • Services changed quickly (Uber estimated a service’s half-life at about 18 months), so the services calling them kept having to migrate.

Uber kept microservices but added structure above them:

  • Domains. Related services are grouped into a domain around one area of the business. A domain might hold one service or dozens.
  • Layers. Domains sit in five layers: infrastructure, business, product, presentation and edge. A domain may only depend on layers below it, and lower layers are more general.
  • Gateways. Each domain has one entry point. Other domains call the gateway, never the services, data or pipelines behind it.
  • Extensions. Teams add behaviour to another domain through defined extension points, such as plug-in logic or extra data attached to requests, instead of editing its code.
flowchart TB
    edge[Edge layer] --> pres[Presentation layer]
    pres --> prod[Product layer]
    prod --> gw1[[Gateway: Rides domain]]
    prod --> gw2[[Gateway: Maps domain]]
    subgraph rides [Rides domain]
        gw1 --> r1[Service] & r2[Service]
    end
    subgraph maps [Maps domain]
        gw2 --> m1[Service] & m2[Service]
    end
    r1 --> infra[Infrastructure layer]
    m1 --> infra

Uber grouped its 2,200 services into 70 domains, about half of which had been implemented when it wrote about DOMA. It reported:

  • 25% to 50% less time for product teams to integrate with a platform, because they call one gateway instead of many services.
  • One feature integration falling from three days to three hours using extensions.
  • Platform support costs often dropping by an order of magnitude.
  • Two large platform rewrites done behind gateways without migrating hundreds of calling services.
  • More structure and governance. Someone has to define domains and layers and keep dependencies pointing the right way.
  • Gateways are extra hops and must be designed as stable, versioned APIs.
  • It suits large organizations. With a few dozen services, the overhead may outweigh the benefit.
  • Hide groups of services behind one stable interface, so internal changes don’t ripple outward.
  • Define allowed dependency directions and enforce them.
  • Offer extension points instead of letting other teams edit your services.

Written and edited by Abhinav Taduka, enterprise software architect.