Skip to content

Batch and transactions

Network round-trips dominate latency for chained queries. batch sends many statements in a single HTTP call.

const results = await db.batch([
{ sql: "INSERT INTO orders (id, total) VALUES (?, ?)", params: ["o-1", 99.5] },
{ sql: "INSERT INTO orders (id, total) VALUES (?, ?)", params: ["o-2", 12.0] },
{ sql: "SELECT COUNT(*) AS n FROM orders" },
]);
console.log(results[2].data); // [{ n: 2 }]

Up to 100 statements per call.

Wrap the same call in a transaction — failures roll back every statement in the batch:

try {
await db.transaction([
{ sql: "INSERT INTO accounts (id, balance) VALUES (?, ?)", params: ["a-1", 100] },
{ sql: "INSERT INTO accounts (id, balance) VALUES (?, ?)", params: ["a-1", 0] },
]);
} catch (e) {
// Both inserts rolled back — `a-1` was inserted then the duplicate failed.
}

db.transaction(stmts) is sugar for db.batch(stmts, { transaction: true }).

  • query — single statement, simplest path.
  • batch — independent inserts/updates that should commit individually.
  • transaction — multi-step operations that must succeed atomically.