Data
A service that declares a database gets its own SQLite file, migrated at deploy, and every call to it runs as one transaction.
The database
- A deployed service has one database and keyspace shared by every caller.
--caller,caller()anduser()do not create separate stores. For private per-user data, include the authenticated caller or the user's issuer and subject in every key and SQL ownership condition; see Callers and users.client()rotates daily and is not a durable user identifier. Local caller identities are unchecked. - A service declares its database with
[database] migrations = "migrations"in itscrab.toml, a directory of.sqlfiles applied in name order at deploy. - A deploy whose migrations do not begin with the ones already applied is refused. A migration that fails refuses the deploy, and the running version keeps serving.
- Tables named
_berm_*are reserved.
Statements
let titles = berm_lang::rows::<(String,)>("SELECT title FROM items WHERE id = ?", &(42,))?;
let found = berm_lang::sql("SELECT title FROM items WHERE id = ?", "[42]")?;-
rows::<T>(statement, params)runs one statement,paramsa tuple bound to its?s in order, and answers its rows, each a tuple of its columns in order. -
sql(statement, params)takes the parameters as a JSON array and answers{"columns": [..], "rows": [[..]], "read": n, "written": n}. For per-call usage and estimates, see Cost of a call. -
Every statement of one call runs in one transaction, committed when the tool returns
Ok. -
BEGIN,COMMITand other transaction statements are refused. -
A
#[tool(query)]tool cannot write. -
One statement answers at most 4 MiB.
Use the counters from representative queries and writes when evaluating an index. The worked index-cost example separates assumed counters, marginal row rates, and remaining plan allowances.
Values by key
let seen = berm_lang::get("last-run")?.unwrap_or_default();
berm_lang::set("last-run", &now.to_le_bytes())?;
let config: Config = berm_lang::get_json("config")?.unwrap_or_default();
berm_lang::set_json("config", &config)?;- Any service keeps values by key with
get,set,get_jsonandset_json, database or not. A service with a database keeps them in it. - They read and write the service's own keys. Another service's keys cannot be named.
getanswersNonefor a key never written.- Writes are committed when the call returns
Ok.setis refused in aquerytool.
Storage
A service's database holds at most the size set in [database] of its crab.toml: 1 GiB unless set, at most 10 GiB. A write past it fails. Your services reserve at most your plan's storage together, and a deploy past it is refused; see Plans.
Seeds
A service can start from a database you filled locally: name it as seed in [database] of its crab.toml, relative to the file. On the service's first source deployment, the CLI uploads a copy and the service's database starts as it. Use crab deploy --build when its manifest declares image.
- The seed is held to the image's migrations: those it records applied must be the image's first, unchanged. The rest are applied on top.
- A seed holds at most 5 GiB, and no more than the service's
size. - A service that has a database takes no seed. Later deploys leave it out.