What happens to an application on prorm when the database moves underneath it,
and what to configure so it survives.What actually happens#
A failover — a managed service promoting a standby, a proxy switching backends,
a container restarting — breaks every open connection. In-flight queries fail.
Pooled connections become stale but are not automatically discarded, so the
first query on each one fails before the pool replaces it.So the visible symptom is a burst of connection errors lasting as long as the
promotion, then recovery. If errors continue well past that, it is not the
failover any more — go to Connection failures.const db = new Prorm({
/* … */
retry: { max: 5, timeout: 1000, backoff: true, backoffMax: 10000 },
pool: { max: 20, acquire: 30000, idle: 10000, evict: 1000, handleDisconnects: true },
});
handleDisconnects lets the pool discard a dead connection rather than hand
it out again.
evict decides how often idle connections are checked, which bounds how long
a stale one can linger.
Retries with backoff cover the promotion window. A 60-second failover needs
more than three attempts a second apart.
Transactions do not survive it#
[!WARNING]
A transaction open across a failover is gone — the server that held it no
longer exists. There is no way to resume it, and prorm will not retry it
for you, because it cannot know whether the commit landed.
Write for that: make the work idempotent, or record enough to determine
afterwards whether it happened.// Safe to run twice
await Order.upsert({ id: orderId, status: 'paid' });
// Not safe to run twice
await Account.increment('balance', { by: 100, where: { id } });
Reads during a failover#
If reads go to replicas, a primary failover need not take reads down with it:const db = new Prorm({
replication: {
read: [{ host: 'replica-1' }, { host: 'replica-2' }],
write: { host: 'primary' },
},
});
Replicas lag. A read immediately after a write may not see it — route
read-after-write to the primary.Afterwards#
Confirm recovery#
Use db.authenticate() from each instance rather than watching logs: a
quiet log is also what a stuck instance looks like.Replay what failed mid-transaction#
Anything that threw a ConnectionError inside a transaction during the
window either committed or did not, and nothing in the error says which.
Check the rows before replaying, or replay only work you made idempotent.Suspect the pool holding stale connections: verify handleDisconnects is
on, and that evict is short enough to find them. Modified at 2026-10-04 00:40:16