All rules Rule SR024 · TS
SurrealDB · beta
note
TS · Table settings
free in the CLI, --engine=surrealdb

Does a SurrealDB event run on every write?

Event with no WHEN condition

Note: this works, but it is a documented trap or a cost the author may not have meant.

What happens

An event without WHEN (or with WHEN true) runs its THEN block on every CREATE, UPDATE and DELETE of the table, inside the write. Work meant for one kind of change is paid on all of them, and each write waits for it.

Why it is dangerous on a populated table

SurrealDB checks a schema change against new writes, not the records already stored, so an empty table hides it: on a populated one every old record is a write waiting to fail, and whole-table work runs for the length of the table in one transaction.

Fires on

DEFINE EVENT user_audit ON TABLE user THEN (CREATE audit SET user = $value.id, at = time::now());

The safe pattern

Say which changes the event is for with WHEN $event = 'CREATE' (or 'UPDATE', 'DELETE'), and compare $before and $after to skip writes that did not change what the event cares about. An ASYNC event runs after the write, and the rule stays silent on it.

DEFINE EVENT user_email_changed ON TABLE user WHEN $event = 'UPDATE' AND $before.email != $after.email THEN (CREATE audit SET user = $value.id, at = time::now());

Fixtures

The rule ships with these files and the test suite runs them on every change: the first set must fire, the second must stay silent.

Fires (2)

no when
DEFINE EVENT user_audit ON TABLE user THEN (CREATE audit SET user = $value.id, at = time::now());
when true
DEFINE EVENT user_audit ON TABLE user WHEN true THEN { CREATE audit SET user = $value.id };

Stays silent (2)

async
DEFINE EVENT user_audit ON TABLE user ASYNC THEN { CREATE audit SET user = $value.id };
when condition
DEFINE EVENT user_email_changed ON TABLE user WHEN $event = 'UPDATE' AND $before.email != $after.email THEN (CREATE audit SET user = $value.id, at = time::now());

How to check locally

Catch this before it ships

SurrealDB support is in beta: this rule runs locally in the free CLI over .surql migrations, static only, and not in the hosted service yet. No install, nothing leaves your machine:

npx bolvrk check migration.surql --engine=surrealdb