# Changefeeds

Replaying table changes over time with changefeeds and SHOW CHANGES - useful for sync, pipelines, and external systems.

Changefeeds are how you ask SurrealDB for a history of writes to a table (or database) so you can replay them elsewhere: search indexes, warehouses, cache warmers, or any system that needs to catch up after downtime.

You define how long changes are retained when you set up the feed by adding a duration like `3d` or `100h`. Changes are then read with the [`SHOW`](/docs/reference/query-language/statements/show.md) statement.

## What you need first

Before `SHOW CHANGES` returns anything useful, the table or database must opt in with a `CHANGEFEED` definition (duration, scope). Changefeeds are usually defined using a `DEFINE TABLE` statement, but can be defined on the entire database if desired via `DEFINE DATABASE`.

## Replaying from a point in time or a versionstamp

A typical flow is:

1. Note when you last processed changes (a datetime) or where you stopped (a versionstamp).
2. Ask for everything since that marker, optionally with a limit so you page through large backlogs.

The [`SHOW` statement reference](/docs/reference/query-language/statements/show.md) spells out the full syntax. In practice you are choosing: “give me the next batch of mutations after this cursor.”

```surql
-- Define the changefeed and its duration
DEFINE TABLE reading CHANGEFEED 3d;

-- Create some records in the reading table
CREATE reading SET story = "Once upon a time";
CREATE reading SET story = "there was a database";

-- Replay changes to the reading table since a date
SHOW CHANGES FOR TABLE reading SINCE d"2025-09-07T01:23:52Z" LIMIT 10;
-- Replay changes to the reading table since a versionstamp
SHOW CHANGES FOR TABLE reading SINCE 1 LIMIT 10;
```

If the datetime is after the changefeed was created and lines up with your retention window, you get a list of entries, each with `changes` and a `versionstamp` (where you are in the log). How each mutation is encoded depends on your [`DEFINE TABLE ... CHANGEFEED`](/docs/reference/query-language/statements/define/table.md#example-usage) options; when differences are stored (`INCLUDE ORIGINAL`), an update to an existing row carries a **reverse diff** from the current state to the state immediately before that write. The [`SHOW`](/docs/reference/query-language/statements/show.md) reference covers this in full. The following shape is representative:

```surql title="Response"
[
	{
		changes: [
			{
				define_table: {
					changefeed: {
						expiry: 3d,
						original: false
					},
					drop: false,
					id: 0,
					kind: {
						kind: 'ANY'
					},
					name: 'reading',
					permissions: {
						create: false,
						delete: false,
						select: false,
						update: false
					},
					schemafull: false
				}
			}
		],
		versionstamp: 116372747574247424
	},
	{
		changes: [
			{
				update: {
					id: reading:1up24usipwi7wjs4nbgk,
					story: 'Once upon a time'
				}
			}
		],
		versionstamp: 116372747574247425
	},
	{
		changes: [
			{
				update: {
					id: reading:6q3845opi3nikxr7jvgg,
					story: 'there was a database'
				}
			}
		],
		versionstamp: 116372747574312960
	}
]
```
