Skip to content

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

  1. Autonomy:
    Your system must be able to deliver its functionality (especially data to the user) without depending on other systems at runtime.

  2. 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.

  3. 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

  1. 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.

  2. 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.