Backbone data & state
The backbone section sets the data-layer limits and declares the resources to create:
document collections, queues, secrets, and cache entries.
- Type
- size
- Default
- platform default
- Meaning
- Maximum size of a single blob (file). A free safety quota, not a price driver.
- Type
- integer
- Default
- platform default
- Meaning
- Maximum number of blobs the slice can store. A free safety quota, not a price driver.
- Type
- integer
- Default
- platform default
- Meaning
- Maximum messages in a single queue before producers are throttled.
- Type
- size
- Default
- platform default
- Meaning
- Maximum size of a single secret value (e.g.
4KB).
- Type
- integer
- Default
- platform default
- Meaning
- Maximum number of distributed locks held at once across the slice (the
drift.Backbone.Lockprimitive). Included and unpriced.
- Type
- integer
- Default
0(off)- Meaning
- Peak simultaneous live Realtime WebSocket connections across the slice, billed in blocks of 50. Omit or set
0to disable Realtime.
There is no slice-wide storage limit. Storage is declared, priced, and enforced per
item. Every nosql, sql, and blobs entry below
carries its own mandatory size, which is both what you're billed for (summed across every
item, charged per GiB) and the hard limit the platform enforces: a write past a given collection's,
database's, or bucket's own size is rejected with 413, independent of every
other item.
NoSQL collections
nosql is a list of maps, one per collection. size is
required: it's both the billing driver and the enforced limit for that collection, so
there's no default to silently fall back to. The long form also accepts a seed, a
JSONL file (one JSON document per line) that the deploy upserts by each document's _id,
and/or a ttl.
nosql:
- name: submissions
size: 200MB # empty collection
- name: permit-types
size: 20MB
seed: ./backbone/permit-types.jsonl # seeded from JSONL
- name: sessions
size: 20MB
ttl: 30d # reaped 30 days after last write# permit-types.jsonl: one JSON document per line, each with an _id
{"_id": "residential-extension", "name": "Residential extension"}
{"_id": "new-build-residential", "name": "New-build residential"}
Seeding is idempotent (re-deploying re-upserts changed rows) and
non-destructive (documents your app added at runtime are left alone, because their
_ids aren't in the seed file). Every line must be valid JSON with a non-empty
_id.
ttl (<int>s/m/h/d) deletes a document
once its last write is older than the TTL. The clock resets on every update, so only
genuinely stale, untouched documents are reaped. There's no undo: documents aren't soft-deleted or archived
anywhere. Omit it and documents are kept forever. Applies per-collection, not per-document.
SQL databases
sql is a list of per-slice SQLite databases, addressed by name. Each entry
materialises as one .db file and is reached from the SDK as drift.Backbone.SQL("name")
for relational queries and transactions. size is required, on the same reasoning as
nosql[].size: each database is billed and enforced on its own size, not against a shared
slice-wide budget. The long form also accepts a schema and/or a seed.
sql:
- name: app
size: 100MB
schema: ./backbone/app.sql # idempotent DDL, runs on every deploy
seed: ./backbone/app-seed.sql # runs only on the first deploy
schema is applied on every deploy, so keep it idempotent
(CREATE TABLE IF NOT EXISTS …). seed runs only when the database
has no user tables yet, which is the first deploy, so later deploys never re-run it, even
if you change the file. To re-run a seed, start from an empty database again: drop it with
drift backbone sql drop <name> and redeploy, and the deploy recreates the database
and re-applies the schema and seed. A database name is 1–64 characters
([a-z0-9], then [a-z0-9_-], then [a-z0-9]) and becomes both the
.db filename and the SDK lookup key.
- Type
- string
- Default
- required
- Meaning
- Database identifier and SDK lookup key, as in
drift.Backbone.SQL("name").
- Type
- size (
KB/MB/GB) - Default
- required
- Meaning
- This database's own storage quota: the billing driver and the enforced limit. A write past it is rejected with
413.
- Type
- path
- Default
- none
- Meaning
- SQL file of idempotent DDL, applied on every deploy.
- Type
- path
- Default
- none
- Meaning
- SQL file run only on the first deploy (when the database has no user tables yet).
Read the Backbone SQL guide → for querying and transactions from your functions.
Blob buckets
blobs is a list of named buckets in the per-slice blob store, each with its own required
size. Unlike nosql/sql, a bucket has no seed or schema. It
exists purely to name a bucket and give it a quota before the first upload. Code doesn't reach a bucket
through a handle the way SQL("name") does; drift.Backbone.Blob.Put/
.Get take one path-shaped name (e.g. "uploads/receipt-42.pdf"), where
everything before the first / is the bucket, and a name with no / goes to the
default bucket.
blobs:
- name: uploads
size: 500MB- Type
- string
- Default
- required
- Meaning
- Bucket name: the prefix before the
/in a blob's path-shaped name.
- Type
- size (
KB/MB/GB) - Default
- required
- Meaning
- This bucket's own storage quota: the billing driver and the enforced limit. A
putpast it is rejected with413.
An undeclared bucket prefix (including default) is unquota'd, the same fallback as an undeclared nosql/sql name.
Queues
A list of names. Queues can't be seeded, because seeding messages on every deploy would re-fire work.
There is no per-queue size: depth is bounded slice-wide by queue_max_depth.
queues:
- validate # bare name
- name: notify # long form: same thing, room to grow
The map form takes name and nothing else. It exists so per-queue options can arrive without
breaking manifests; until they do, any other key inside it is rejected rather than
ignored, so a typo fails the deploy instead of silently doing nothing.
Secrets
A map of KEY: value. A value of $NAME (unquoted) is a reference resolved when
drift project deploy runs. The literal never touches the Driftfile or the wire, only
the resolved string travels. Quote a value to force a literal that starts with $.
secrets:
MUNICIPALITY_NAME: "Amsterdam" # hardcoded literal
RESEND_API_KEY: $RESEND_API_KEY # resolved at deploy time
A $NAME reference (and any ${VAR} placeholder elsewhere in the Driftfile)
resolves through a variable origin hierarchy, highest precedence first:
- Hardcoded: a literal value written in the Driftfile. Absolute.
- Environment: a variable exported in your shell session.
- Override flags:
--secret KEY=value(repeatable), and--env <name>(same as the positional environment; also setsENV). An override yields to a variable the environment set; it beats the env files. .env.<env>file: when an environment is selected, the per-environment secrets file (e.g..env.staging) next to the Driftfile. Out-ranks the base.env..envfile: the baseKEY=valuefile next to the Driftfile, sourced automatically (lowest precedence; fills only what nothing above provided). Pass--no-env-fileto skip the env files.
So an exported DB_PASSWORD beats --secret DB_PASSWORD=…, which beats a
DB_PASSWORD line in .env.staging, which beats one in .env. A
deploy prints what it loaded from which env file, and what it ignored because the environment supplied
it, so the layering is never silent. Config dials that differ per environment belong in
environments:; only secrets belong in
.env.<env>.
Cache
A map from key to a value to pre-warm at deploy. The short form is a file path whose
contents become the cached value. The long form takes an inline value (or a
file) plus an optional ttl in seconds, after which the entry expires
and a Cache.Get returns empty until your code re-populates it. Omit ttl (or
set 0) for an entry that never expires.
cache:
menu: ./backbone/menu.json # short form: file contents become the value
banner: # long form: inline value with a TTL
value: "Closed for maintenance"
ttl: 3600 # seconds; 0 / omitted = never expires
pricelist: # long form: file + TTL
file: ./backbone/prices.json
ttl: 86400At runtime the cache is read/write from your functions, so these entries are just the initial warm set. Read the Backbone Cache guide →