Skip to main content

Stateless Design

Context

Microservices are being adopted. There is a microservice in place that makes use of states (e.g. caching, sessions, etc.)

Problem

  • Scaling the microservices by simple replication leads to inconsistencies between instances since the state is not shared.
  • At failure, the state of the microservice instance is lost and cannot be recovered leading to inconsistencies with clients.
  • Sharing state lead to cascading failures between the instances of the microservices since the shared state can be polluted.

Solution

Design the microservices in a stateless way to avoid sharing state between its instances.

Being stateless means not saving a state in-memory, nor on a local storage like on disk since both are ephemeral in a containerized environment. Sessions with communication partners should be avoided as they implicate maintaining a state.

If the microservice has to manage the data it is responsible for, this data is maintained in a microservice-specific database that is shared between the microservice instances. In other words, the "state" is pushed to the database level or to some other external component.

In some cases, the state can also be pushed to the consumer, meaning that client requests have to contain the context information in order fulfill the request.

Not relying on a state will make the microservice instances interchangeable for interactions. This simplifies load balancing between instances and improves the fault tolerance of the microservice. Not sharing state means that instances cannot influence each other and prevents error cascading by a polluted state (except the one written to the database).

Maturity

Proposed, requires evaluation.

Sources of Evidence

L5:

  • 12-factor and cloud native designs demand statelessness as best practice for microservices

L9:

  • State either on disk or in memory
  • Fault tolerance and scaling => mechanism to allow replication of application state
  • If Stateful: complex
    • Containers don't allow yet sharing memory =>
      • (1) use disk to store state: shared storage, disk colume migration, application-level data replication
      • (2) rely on clients to tolerate loss or inconsistency of state of failed services
  • Statelessness has clear benefits (in OpenStack), easier

L14:

  • Microservices at Otto.de; more Self-contained systems
  • "Shared nothing" principle: no shared state, no infrastructure components besides the two proxies, no database, or other shared resources.
  • No HTTP sessions, shared caches
  • Only limited amount of client-side state (cookies, local storage) as sharing between systems => esp. for auth
  • (+) excellent horizontal scalability
  • (+) improved fault tolerance: not sharing => no impact on each other

L17:

  • Stateless architecture is common for microservices

L22:

  • Standards for services, usually stateless, message-oriented, and hypermedia-driven

L25:

  • statelessness => easy restarting service => failure safety

L46:

  • same as SOA: stateless services

L61:

  • pushing as much as possible towards stateless microservices as means of fault tolerance

LN42:

  • challenges and disadvantages of microservices
    • among others: state management
  • migration poses challenges regarding statefulness (among others)

LN44:

  • situation-dependent attributes of microservices
    • self-contained, coarse-grained, visible/discoverable, stateless, idempotent, reusable, composable, vendor-diverse

Interview A:

  • did 12-Factor App, cloud native => includes stateless
  • statelessness => each service have own database