Skip to content

DynamoDB (native.db)

A small shared key-value store for state that doesn't belong in an S3 object. It is also what callbacks are built on.

Script API: native.db

Function Result
get(pk, sk?) the stored value, or nil if missing or expired.
put(pk, sk?, value) stores any JSON-serializable value.
put_if_absent(pk, sk?, value) stores the value only if the key holds no live item; returns true if it wrote. An expired item counts as absent.
add(pk, sk?, delta?) atomic counter: adds delta (default 1, may be negative) and returns the new value. A missing or expired counter starts from 0.
delete(pk, sk?) removes an item.
query(pk, opts?) rows { sk, value } under pk, in sort-key order. opts.sk_prefix filters, opts.limit caps (at most 100).

sk defaults to the empty string. Values are stored as JSON, at most 64 KB each. Every write sets a one week expiry, so this is for short-lived state; use native.bucket for anything that must stay. Calls count against max_data_ops.

native.db.put("session", "u42", { step = 2 })
local s = native.db.get("session", "u42")
for _, row in native.db.query("session", { sk_prefix = "u" }) do
  native.log("info", row.sk)
end

put_if_absent and add are the building blocks for idempotency and for counting work across invocations: claim a key to run something once, or count finished pieces and act on the one that completes the set (see Scatter and gather). Use keys that only add writes: get reads a counter back as a number, and a later put replaces it. Both calls count against max_data_ops.

if native.db.put_if_absent("seen", ev.id, true) then   -- true only for the first delivery
  process(ev)
end
local n = native.db.add("progress", job)               -- 1, 2, 3, ...

Isolation is enforced by the host: your pk is stored as TEN#<tenant>#<pk>, so a script cannot address another tenant's rows.

Deployment

Set db.table in the global config. The table needs:

  • string partition key pk and string sort key sk;
  • TTL enabled on the attribute ttl;
  • items hold the value in v.

All tenants share the table; isolation comes from the enforced TEN#<tenant># partition key prefix.

IAM: dynamodb:GetItem, PutItem, UpdateItem, DeleteItem (conditional writes included) and Query on the table. Locks use the same actions.