drift Docs
Start
What is Drift?
The tour, if you are new here.
Why Drift?
The case for a smaller cloud.
Getting started
Nothing to deployed, in one command.
Architecture
How a slice is put together.
What it costs
The free grant, five unit prices, two rules.
Build
Canvas
Static sites, same origin as your API.
Tools
Operate
Auth
Accounts, tokens and scopes.
Security
Boundaries, sandboxing and hardening.

Backbone

Backbone is your slice's encrypted data layer. Your functions reach it through the SDK with a single call: no connection strings, no ORM, no migrations. Collections, queues, buckets and the rest spring into existence the first time you use them, and you can seed and inspect them from the CLI.

The primitives

Each primitive has a drift backbone <name> command group of its own, and the whole surface is in the CLI reference. Inspect your slice's data and usage any time with drift backbone status.

Calling Backbone from a function

Each SDK spells the namespace the way its language does. The same insert, six ways:

Language Call
Godrift.Backbone.NoSQL.Collection("users").Insert(doc)
Pythondrift.backbone.nosql.collection("users").insert(doc)
Nodeawait drift.backbone.nosql.collection("users").insert(doc)
RubyDrift::Backbone::Nosql.collection("users").insert(doc)
PHP\Drift\Backbone\Nosql::collection("users")->insert($doc)
Rustdrift::backbone::nosql::collection("users").insert(json)

Every Node Backbone call returns a promise, so await it. The examples on each primitive's page are Go; the table above translates them.

Limits you cannot declare

The quotas you buy and declare in your Driftfile (collection and bucket sizes, queue depth, realtime connections) run inside a set of fixed caps built into the slice. These are the same on every tier and there is no key for them.

Primitive Fixed cap
Cache1 MiB per value · 10,000 entries · 64 MiB of total value bytes
NoSQLlist returns 100 by default, 1,000 maximum
SQL64 KiB per statement · a transaction idle for 30 s is rolled back
Realtime512 KiB per message · 128 connections per channel · 2,048 channels per slice
Queue triggerspolled every 500 ms · 3 attempts, then <queue>-dlq

Names are validated on the way in, and the charset differs by what the name becomes:

Name Charset
Collection, queue, bucket, NoSQL _keyFirst character alphanumeric, then alphanumerics . _ -, up to 255 bytes.
Blob keyThe same plus /, up to 513 bytes, no ...
Indexed field name and valueFirst character alphanumeric or _, then alphanumerics . _ -, up to 255 bytes, no ...
Realtime channelAlphanumerics and : . _ ~ -, up to 256 bytes.
LockAny non-empty string.

Status codes

The primitives share one status contract, so a code tells you what went wrong without reading the message. The SDKs carry it into the error they return; the CLI prints it.

Code Meaning
200Done. A read carries the value; queue push carries the message id.
204Nothing to return: an empty queue on pop or peek, a successful NoSQL delete, a successful SQL commit or rollback.
400Bad request: malformed JSON, a missing parameter, a name outside its charset, an unindexable filter, an unknown transaction token, or an error from SQLite.
401The route is internal. A function reaching for a secret it did not declare, or calling Secret.Set, lands here.
404No such key, blob, queue or lock.
409The lock is held by someone else.
413Over a quota you declared: a collection or bucket at its size, or a SQL statement over 64 KiB.
429Over a platform cap: cache full, queue at queue_max_depth, blob count cap, concurrent-lock cap.
503The slice is at its realtime connection cap, or draining.

Backbone under drift atomic run

Local dev has no slice behind it. Every SDK answers Backbone calls from an in-memory store inside your own process, which behaves differently from a deployed slice in ways worth knowing before you trust a green local run:

Local Deployed
State lives in the process and is lost on exit. Nothing is encrypted.Encrypted at rest with the slice's own key, and durable.
Insert returns a key.Insert returns an empty string.
No quotas, no TTL expiry, none of the caps above.All of them enforced.
Secrets are read from the environment; the CLI loads .env from your source directory.Declared secrets arrive as DRIFT_SECRET_<NAME> and in req.secrets.
SQL has no local implementation.SQLite per database, encrypted at rest.
Blobs live in a per-SDK scratch map, and Go's Blob.Put stores nothing at all.Stores the bytes, encrypted.
No realtime hub: Publish and Presence report 0.Fans out to live subscribers.

Anything that depends on those differences needs a deployed slice to test against.

What a snapshot captures

drift slice snapshot create archives secrets, NoSQL collections, blobs, queues and SQL databases. Cache and locks are not in the archive, because both hold data that is recomputable or short-lived by design, so restoring a snapshot gives you a cold cache and no held locks.

Blobs are captured from the same top-level bucket listing the CLI uses, so a key containing a slash is absent from the archive as well as from blob list.