All rules Rule SR018 · LK
SurrealDB · beta
warning
LK · Locks & blocking
free in the CLI, --engine=surrealdb

Does DEFINE INDEX block in SurrealDB, and what does CONCURRENTLY do?

Index built on an existing table without CONCURRENTLY

Warning: the statement succeeds, then writes fail, access changes, or the table is held up.

What happens

DEFINE INDEX without CONCURRENTLY builds the index over every record already in the table inside the defining statement: the migration waits for the whole build, and the table's writes compete with it until it finishes. CONCURRENTLY builds it in the background, and the index serves queries once it has caught up.

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 INDEX purchase_customer ON TABLE purchase FIELDS customer;

The safe pattern

Add CONCURRENTLY for any index on a table that already holds records, and check INFO FOR INDEX for the build status before relying on it.

DEFINE INDEX purchase_customer ON TABLE purchase FIELDS customer CONCURRENTLY;

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)

index
DEFINE INDEX purchase_customer ON TABLE purchase FIELDS customer;
overwrite index
DEFINE INDEX OVERWRITE purchase_customer ON purchase COLUMNS customer, created_at;

Stays silent (2)

concurrently
DEFINE INDEX purchase_customer ON TABLE purchase FIELDS customer CONCURRENTLY;
new table
DEFINE TABLE purchase SCHEMAFULL;
DEFINE INDEX purchase_customer ON TABLE purchase FIELDS customer;

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