Skip to content

Cache (ctx.cache) ​

ctx.cache stores values between script runs. Keys are scoped to the tenant automatically, so two tenants never see each other's entries. Values are serialised for you: a table goes in and a table comes back.

FunctionReturns
ctx.cache.get(key)(ok, value); value is nil on a miss
ctx.cache.set({ key = …, value = …, ttl = … })(ok, nil)
ctx.cache.delete(key)(ok, nil)

set takes one table, not positional arguments. ttl is in whole seconds and optional: without it an entry lives for one hour, and any TTL is capped at seven days (604800 seconds). A fractional TTL is truncated. The value's JSON encoding can be at most 4 KB; a larger value raises an error.

Example: read through the cache ​

lua
local CACHE_KEY = "device:line-1:counters"

local ok, cached = ctx.cache.get(CACHE_KEY)
if not ok then error(cached) end

local reading = cached
if reading == nil then
  local reached, response = ctx.device.http("line-1-controller", {
    method = "GET",
    path = "/api/v1/counters",
  })
  if not reached then error(response) end

  reading = { status = response.status, readAt = ctx.time.nowIso() }

  local stored, err = ctx.cache.set({ key = CACHE_KEY, value = reading, ttl = 30 })
  if not stored then error(err) end
end

return { reading = reading, servedFromCache = cached ~= nil }

Behaviour to know ​

  • A miss is a success: ok is true and the value is nil. Test the value, not the flag, to detect a miss.
  • Storing nil cannot be told apart from a miss. Do not store it.
  • Deleting a key that does not exist is not an error.
  • An empty key, or a failure of the cache backend, raises an error instead of returning false.

In integrations ​

Integration scripts can use ctx.cache (tenant-scoped) and also ctx.integration.cacheGet(key), ctx.integration.cacheSet({ key, value, ttl }) and ctx.integration.cacheDelete(key), which are scoped to the integration instance.

Connect machines, automate workflows, and build custom apps for print production.