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)
DEFINE EVENT user_audit ON TABLE user THEN (CREATE audit SET user = $value.id, at = time::now());DEFINE EVENT user_audit ON TABLE user WHEN true THEN { CREATE audit SET user = $value.id };Stays silent (2)
DEFINE EVENT user_audit ON TABLE user ASYNC THEN { CREATE audit SET user = $value.id };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
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