Skip to content

Per-agent sandbox

The wedge: every Claude / GPT / custom-agent run gets its own database or its own branch. Idempotent on a ref, auto-deleting on a TTL, no per-branch fee.

import { PerSQL } from "@persql/sdk";
import { randomUUID } from "node:crypto";
const persql = new PerSQL({ token: process.env.PERSQL_TOKEN! });
const db = persql.database("acme/orders");
// Idempotent — call as many times as you like with the same ref.
const branchRef = `run-${randomUUID()}`;
await db.branches.upsert(branchRef, {
expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // auto-clean in 24h
});
const branch = persql.database("acme", `orders.${branchRef}`);
await branch.query("INSERT INTO scratchpad (note) VALUES (?)", ["hello"]);

No request or row charges until the agent issues its first query. Storage is metered from the moment data lands — a fresh database created with databases.create() starts empty, so a CI pipeline that spins up run-${uuid} and never writes to it pays nothing for the empty ones. A branch is a full copy of its parent, so a branch of a populated production DB inherits the parent’s size at $0.40/GB-month, prorated for its lifetime; the auto-delete TTL keeps that bill bounded. No per-branch fee, no plan-tier gate.

Once your agent has scratch space, point it at the schema with db.describe() — one round-trip and the LLM has every table, column, FK, and stored description it needs to write SQL.

const schema = await branch.describe();
// → { databaseDescription, tables: [{ table, columns, foreignKeys, ... }] }