n8n-io/n8n · error · LockAcquireTimeoutError

Timeout waiting for lock SqliteWriteConnectionMutex to becom

Error message

Timeout waiting for lock SqliteWriteConnectionMutex to become available

What it means

Thrown by SqliteWriteConnection when its single-writer async-mutex cannot be acquired within the configured acquireTimeout (set from the pool's acquireTimeout option). SQLite permits only one writer at a time; n8n's pooled driver serializes writes behind this mutex. The underlying async-mutex returns the E_TIMEOUT sentinel, which the driver rewrites into LockAcquireTimeoutError and attaches as the cause. The message names the specific lock ('SqliteWriteConnectionMutex').

Source

Thrown at packages/@n8n/typeorm/src/driver/sqlite-pooled/SqliteWriteConnection.ts:186

	private assertNotReleased() {
		if (this.isReleased) {
			throw new DriverAlreadyReleasedError();
		}
	}

	private captureInvariantViolated(extra: Record<string, string | boolean>) {
		const error = new InvariantViolatedError();
		console.error(
			'Invariant violated:',
			Object.keys(extra)
				.map((key) => `${key}=${extra[key]}`)
				.join(', '),
		);
		console.error(error);
	}

	private throwLockTimeoutError(cause: Error) {
		throw new LockAcquireTimeoutError('SqliteWriteConnectionMutex', {
			cause,
		});
	}
}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Raise the pool acquireTimeout in the datasource config (DB_SQLITE_POOL_ACQUIRE_TIMEOUT or the relevant @n8n/typeorm sqlite pool option) so the longest legitimate write finishes inside the window.
  2. Find the slow writer: enable DB query logging or DB profiling and look for the write/migration that exceeds the timeout; add missing indexes or batch the operation.
  3. Ensure only one n8n process uses the SQLite file (SQLite is single-writer by design); move to PostgreSQL for multi-instance or high-write deployments.
  4. If running on a network/shared filesystem, move the sqlite file to local disk, or switch to Postgres.
  5. Confirm the write transaction is being committed/released (no leaked runExclusive callbacks, no un-awaited transactions).

Example fix

// before - default timeout too short for large migrations
const ds = new DataSource({
  type: 'sqlite',
  database: 'n8n.sqlite',
  // pool acquireTimeout defaulting to ~5s, large writes time out
});

// after - raise the SQLite pool acquire timeout
const ds = new DataSource({
  type: 'sqlite',
  database: 'n8n.sqlite',
  poolSize: 1,
  acquireTimeout: 60_000, // 60s window for the longest write
});
Defensive patterns

Strategy: retry

Validate before calling

// Before issuing the write, confirm no other long writer is in flight
// by checking process state; raise acquireTimeout to a safe bound.
const acquireTimeout = Math.max(
  config.DB_SQLITE_POOL_ACQUIRE_TIMEOUT ?? 5_000,
  estimatedLongestWriteMs * 2,
);
const ds = new DataSource({ type: 'sqlite', database, acquireTimeout });

Type guard

function isLockAcquireTimeoutError(e: unknown): e is import('@n8n/typeorm/error/LockAcquireTimeoutError').LockAcquireTimeoutError {
  return e instanceof Error && /Timeout waiting for lock SqliteWriteConnectionMutex/.test(e.message);
}

Try / catch

try {
  await writeRepo.save(batch);
} catch (e) {
  if (isLockAcquireTimeoutError(e)) {
    // transient contention — back off and retry, then surface if still failing
    await backoffRetry(() => writeRepo.save(batch), { retries: 3, baseMs: 200 });
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling any write path (INSERT/UPDATE/DELETE, migrations, schema changes) on the SQLite pooled driver while a previous write holds the mutex longer than acquireTimeout. Concretely: a long-running migration, a multi-thousand-row transaction, a query that scans a large table without an index, or a deadlock between an unfinished runExclusive callback and the pool's acquire timeout. Also fires when close() races with an in-flight write and cancel() rejects waiters.

Common situations: Default SQLite deployments of n8n (small/self-hosted) under load spikes; a manual migration on a large database; a workflow that fires many concurrent executions; another process holding the DB file lock (e.g. two n8n instances pointed at the same sqlite file, or an external sqlite3 session in WAL-interactive mode); slow disk/FS (NFS, network volumes) inflating write latency.

Understand the failure class

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/a65fa2d4267c29fc. Report an issue: GitHub.