# Database changes

Listen for inserts, updates, and deletes.

## Subscribe to changes


```ts
const channel = db
  .channel("pending-todos")
  .on("nostr_changes", {
    table: "todos",
    event: "*",
    author: pubkey,
    filter: "done=eq.false",
  }, ({ eventType, new: next, old: previous }) => {
    console.log(eventType, next, previous);
  })
  .subscribe((status, error) => {
    if (error) console.error(status, error);
  });

await db.removeChannel(channel);
```

`postgres_changes` is an alias for the same event type. Payloads contain `INSERT`, `UPDATE`, or `DELETE`, the new and old rows, and the signed event. Initial cached or relay records arrive as `INSERT`. Duplicate and stale versions are ignored. For filtered updates, a callback runs when either the old or new row matches. This lets an app remove a row that leaves its filter.

`SUBSCRIBED` means local handlers are installed. It is not a relay readiness or replay-completion signal. Reconnects use Applesauce's retry policy. A terminal relay error emits `CHANNEL_ERROR`; call `.subscribe()` again to retry. Channels read kind-5 deletion events to accept deletion requests from other Nostr clients. For large deployments, use author filters and a relay with suitable retention and limits.
