> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How Atoti manages data versioning

> How Atoti manages data versioning for the database and the cube using versions, epochs, and branches in the in-memory datastore, and how DirectQuery versioning depends on external database time-travel support and manual refresh.

## What is a version?

A version represents a snapshot of the available data at a specific point in time.
Versions allow data from different points in time to be accessed.
And therefore helps manage multiple states of data for comparison and simulation.

## How are versions created?

Versions are created automatically by Atoti. There is a latest version for the database and a version for the latest version of a cube.

* For a **database**: The database stores data. Every time data is loaded, inserted, or deleted, a new version is created.
* For a **cube**: The cube queries a set of data in the database. Every time that data is updated, a new version is created.

For example; a database contains 10 columns of data. A cube queries only 5 of those columns. When the database is updated, the cube version is updated only if the update affects the 5 columns that the cube queries.

Therefore:

* When a cube queries all the columns in the database, the cube version is identical to the database version.
* When a cube queries only a subset of the columns in the database, the cube version may differ from the database version.
* When a database is queried by more than one cube, each cube may have a different version of the database, depending on which columns the cubes query.

## How are different versions of data queried in the cube?

Every cube has a dimension that allows users to select the version of data they want to query. This dimension is called the **epoch dimension**.

The default value for this dimension is the latest version of the data. Users can select a previous version of the data to query by selecting a different value in the epoch dimension.

Atoti allows users to configure the number of versions to keep in the cube. When the maximum number of versions is reached, the oldest version is deleted when a new version is created.

### How can versions be used for simulations?

Versions can be used to perform simulations by creating branches of the data. A branch is a copy of a version that can be modified independently of the original version. This allows users to test different scenarios without affecting the original data.

Branches are useful for performing simulations:

* Testing changes without impacting the original version.
* Creating alternative scenarios.

## How are different versions of data managed in the database?

Data versioning is implemented differently depending on whether you use the Atoti datastore or access an external database using DirectQuery.

* Atoti in-memory datastore natively manages data versioning
* With DirectQuery, data versioning is dependent on the external database's native support.

### Versioning in the Atoti datastore

When data resides in the Atoti Datastore, versioning is provided natively by Atoti.

* Each committed transaction creates a new version of the datastore. The new version can be queried using the epoch dimension.
* Epochs allow for auditing and rollback.
* Branches are fully supported and provide an isolated workspace for simulations without affecting the main data.
* Branches can be compared directly with the base version or with other branches to evaluate the impact of changes, forming the basis of Atoti’s what‑if analysis.

### Versioning with DirectQuery

With DirectQuery, Atoti reads data directly from an external database and maintains internal snapshots to support hierarchies and aggregates. Versioning capabilities depend on the external system:

* If the external database supports native time travel, Atoti can query historical snapshots.
* If the external database does not support native time travel, only the latest snapshot is available.

External databases cannot push change events to Atoti, so users must explicitly trigger refreshes. This is managed by the DirectQuery connector.

* If the external database supports native time travel: Atoti can query consistent historical snapshots directly, so cube components stay in sync between refreshes.
* If the external database does not support native time travel: Atoti relies on its own internal snapshot, so cube components (hierarchies, aggregate providers) can become temporarily out of sync until a refresh is performed.

### Further reading

Find out more about data versioning:

* [Atoti Java SDK](/engine/java-sdk/latest/concepts/data_versioning)
* For an introduction to [DirectQuery](../load-data/DirectQuery.md) read this page.

Keep DirectQuery data up to date using Atoti Java SDK:

* **Incremental refresh**: A specific scope of data is updated.
* **Full refresh**: All the data from the external database is updated.

DirectQuery does not support branches. Any simulations that require branches must use the Datastore.

## Summary: Datastore vs. DirectQuery

| Capability                       | Datastore                                 | DirectQuery                                                            |
| -------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------- |
| Historical versions available    | ✔️ Natively provides consistent snapshots | ✔️ Only if external DB supports time travel; otherwise latest snapshot |
| Epochs within versions           | ✔️ Fully supported                        | ⚠️ Behavior depends on external DB’s capabilities                      |
| Branches for simulations         | ✔️ Fully supported                        | ❌ Not supported                                                        |
| How changes are ingested         | Automatic via transactions                | User‑triggered Incremental or full refresh                             |
| Cube availability during updates | ✔️ Yes                                    | ✔️ Yes (during both incremental and full refresh)                      |
| Risk of desynchronization        | Low                                       | Medium for non‑time‑travel databases until refresh completes           |
