6th of 12-Factor vs Stateful

The sixth of the 12-Factor (https://12factor.net/processes) says that Twelve-factor processes are stateless and all state must be stored in an external repository after the request has been processed. But the architecture of a system built using Akka (with features like Akka cluster) is considered stateful, since the actor is the owner of the information (with this state being persisted externally so the actor can be reconstructed if something fails). I understand this is the way it achieves low latency and high throughput.

I’d like to hear your opinions about relationship between the stateful architecture and this factor.


1 Like

Choosing whether to build a stateful of stateless application is a big architectural choice that I think should be made based on the domain of the application but is often made based on limitations of the tech stack used.

Akka Cluster with Cluster Sharding gives you the building blocks to make a stateful application deployable in a stateless environment e.g. Kubernetes. The blocks being:

  • transparent request routing so that no clever ingress is required
  • moving of the state as nodes go up and down
  • rehydration of the state using event sourcing principles with persistence

Without these building blocks, defaulting to a stateless application makes a lot of sense and works nicely until the bottleneck becomes either throughput to the database, often solved via sharding at the DB level, or latency to the database, often solved via a caching layer in front of the database.

That said I don’t think just because we have these building blocks we should default to building a stateful application in the same way much of the industry defaults to a stateless architecture without much thought.

We should look at the application domain and decide. Then even if our application domain fits a stateful approach it still needs to be weighed up against the additional technical complexities of running a stateful service.

Some examples from my experience.

  • If you’re building a thin facade over storage, e.g. a simple CRUD, where the entities in your domain don’t need to interact with each other then you can use any tech stack and architecture
  • Longer lived processes, e.g. a complex order that a user can keep coming back to to modify before completing live in a grey area where both approaches work well
  • Entities that interact, e.g. a chat application or an interactive game where users interact, long lived models that are updated from different sources are much easier to build statefully otherwise all interaction goes via a storage system which pollutes the domain and makes database admins very unhappy

And more tecnically motivated reasons for stateful with something like cluster shareding: