# Read, branch, compare and restore a past moment

> Work with a Stolon database's history: read a table at a past moment with FOR SYSTEM_TIME AS OF, branch from that moment, compare it with now using COMPARE DATABASE, and restore a branch to it while keeping the present as a branch.

Source: https://stolondb.com/guides/history/ · Page title: Read, branch, compare and restore a past moment — Stolon

Read a past moment, compare it with now, branch from it, and go back to it while keeping the present.

## 0. A table, a moment, and some changes

```sh
psql "postgresql://app:<password>@db.stolondb.com/acme.main"
```

```sql
CREATE TABLE customers (id int PRIMARY KEY, name text, plan text, credit numeric(10,2));
INSERT INTO customers VALUES (1, 'ada', 'pro', 120.00), (2, 'grace', 'free', 0.00), (3, 'linus', 'pro', 80.50);
```

Note the moment:

```sh
date -u '+%Y-%m-%d %H:%M:%S+00'
```

```text
2026-09-28 20:07:25+00
```

Then change things, the way an agent or a bad migration would:

```sql
UPDATE customers SET credit = 175.00 WHERE id = 1;
UPDATE customers SET plan = 'pro' WHERE id = 2;
DELETE FROM customers WHERE id = 3;
INSERT INTO customers VALUES (4, 'barbara', 'free', 10.00);
```

## 1. Read the past moment

```sql
SELECT * FROM customers FOR SYSTEM_TIME AS OF '2026-09-28 20:07:25+00' ORDER BY id;
```

```text
 id | name  | plan | credit
----+-------+------+--------
  1 | ada   | pro  | 120.00
  2 | grace | free |   0.00
  3 | linus | pro  |  80.50
(3 rows)
```

Any table, any branch. The console's Time Machine scrolls a table back the same way.

## 2. Compare it with now

```sql
COMPARE DATABASE main AS OF '2026-09-28 20:07:25+00' WITH main CELLS;
```

```text
 section |   table   |         item          |  change  | added | removed | modified | cells |   a    |                   b                    |                   cursor
---------+-----------+-----------------------+----------+-------+---------+----------+-------+--------+----------------------------------------+---------------------------------------------
 cell    | customers | id=1: credit          | modified |       |         |          |       | 120.00 | 175.00                                 | 2-6.0.637573746f6d657273.018000000000000001
 cell    | customers | id=2: plan            | modified |       |         |          |       | free   | pro                                    | 2-6.0.637573746f6d657273.018000000000000002
```

`a` is the value then, `b` the value now. Drop `CELLS` for counts per table, or use `ROWS`. Either side can be a branch, a moment (`AS OF`) or a commit (`AT DEPTH n`); `TABLE t` narrows it. The console's Compare page and the MCP `compare` tool give the same answer.

## 3. Branch from the moment

In the console's Time Machine, choose *Branch from this moment*, here named `before-cleanup`, and connect to it:

```sh
psql "postgresql://app:<password>@db.stolondb.com/acme.before-cleanup" -c 'SELECT * FROM customers ORDER BY id'
```

```text
 id | name  | plan | credit
----+-------+------+--------
  1 | ada   | pro  | 120.00
  2 | grace | free |   0.00
  3 | linus | pro  |  80.50
(3 rows)
```

## 4. Go back, and keep the present

In Time Machine, choose **Restore** at the moment. The console keeps the present as a branch (`main-before-restore-<stamp>`), then puts `main` back:

```sql
SELECT * FROM customers ORDER BY id;
```

```text
 id | name  | plan | credit
----+-------+------+--------
  1 | ada   | pro  | 120.00
  2 | grace | free |   0.00
  3 | linus | pro  |  80.50
(3 rows)
```

The present is on the kept branch:

```text
 id |  name   | plan | credit
----+---------+------+--------
  1 | ada     | pro  | 175.00
  2 | grace   | pro  |   0.00
  4 | barbara | free |  10.00
(3 rows)
```

To undo the restore, the console merges the kept branch back into `main` (`MERGE DATABASE`).
