Self-Contained Systems
To improve the reliability and resilience of our platform, we advocate for the Self-Contained System (SCS) architectural paradigm. A self-contained system is an independently deployable and operable unit that includes its own UI, logic, and data. You can read more about it here on Wikipedia.
In previous architecture setups, Statista experienced critical outages due to the tight coupling between services—if one core service failed, it could cascade and bring down the entire platform.
With the introduction of the 4.0 architecture, we aim to prevent such systemic failures by ensuring that applications are decoupled and do not rely synchronously on services managed by other teams. While complete decoupling may not always be feasible, it should be pursued wherever possible.
If a team identifies a use case that requires an exception to this principle, they must document it in an Architectural Decision Record (ADR) for review and approval.
Core Requirements
-
Autonomy:
Your system must be able to deliver its functionality (especially data to the user) without depending on other systems at runtime. -
Data Ownership:
If your system consumes data from another system, that data becomes private to your system. It must not be shared further. If another system needs the same data, it must retrieve it from the original source of truth. -
Data Modification:
Any updates to data must go through the source of truth. Never send updates via intermediate or third-party services.
Why Synchronous Dependencies Are Harmful
sequenceDiagram
actor User
participant UI
participant Data
User-->>+UI: open page
break when the API is offline
UI->>+Data: GET Data for Display
Data->>+UI: Data to Display
end
UI-->>+User: render
User-->>+UI: submit form
break when the API is offline
UI->>+Data: POST Data for update
Data->>+UI: success/failure
end
UI-->>+User: display new state
In the example above, the availability of the UI service is tightly coupled with the availability of the Data service. If the Data service is down—even temporarily—the UI becomes unusable.
If multiple services are involved, the probability of system failure increases. Even one unavailable service can render the entire application non-functional.
How Self-Contained Systems Mitigate These Risks
By embracing the SCS paradigm, we decouple UI and data layers to increase fault tolerance. Here’s how: The UI service fetches data asynchronously from the Data service and stores a local copy. The UI can then render views independently, even if the Data service is temporarily offline.
Two Options for Data Updates
-
Synchronous Updates The UI service calls the Data service directly and, on success, updates its local copy. If the call fails, the system is degraded—inform the user about the failure or disable the feature temporarily.
-
Asynchronous Updates (Eventual Consistency) The UI queues the update and sends it to the Data service later. This enables offline support or deferred writes but comes with challenges: Users may not see their updates immediately. Conflicts may arise if multiple updates happen concurrently. Additional logic is required to reconcile differences.
Summary
Adopting the Self-Contained System architecture leads to:
- Higher system resilience and uptime
- Clear ownership of services and data
- Better scalability and maintainability
- Reduced risk of cascading failures Whenever feasible, design your applications as self-contained, and avoid introducing runtime dependencies on external services.