Skip to content
Thyme Docs

Storage & JSON Types

The SDK exports two types that describe JSON-serializable data: JsonValue and JsonObject. They are the foundation of ctx.storage, the persistent state available to a task across runs.

JsonValue

type JsonValue =
  | null
  | boolean
  | number
  | string
  | JsonValue[]
  | { [key: string]: JsonValue }

These are the JSON data types. This excludes undefined, functions, BigInt, Date, and other non-JSON types.

JsonObject

type JsonObject = { [key: string]: JsonValue }

A plain object whose values are all JsonValues. This is the type of ctx.storage.

The storage mutation pattern

ctx.storage is a mutable JsonObject persisted across runs of the same executable. Mutate it in place. The platform commits eligible writes after a skip or successful execution; a failed run discards its pending writes:

ctx.storage.runs = ((ctx.storage.runs as number | undefined) ?? 0) + 1

Because JsonValue is broad, validate the field shape when reading data written by earlier versions or edited externally:

const stored = ctx.storage.seen
const seen = Array.isArray(stored)
  ? stored.filter((value): value is string => typeof value === 'string')
  : []
seen.push(latestId)
ctx.storage.seen = seen

A counter task that only updates state and never executes:

import { defineTask, z } from '@thyme-labs/sdk'
 
export default defineTask({
  schema: z.object({}),
  async run(ctx) {
    ctx.storage.runs = ((ctx.storage.runs as number | undefined) ?? 0) + 1
    return { canExec: false, message: 'State updated' }
  },
})

Rules

  • Plain JSON object only — values must be JsonValue.
  • No undefined, NaN, Infinity, or -0.
  • Forbidden keys: __proto__, constructor, prototype.
  • 100 MiB total size cap.

Local vs cloud persistence

  • Local (thyme run): seeded from functions/<task>/storage.json, printed after the run, and only written back when you pass --persist.
  • Cloud: stored per-executable with optimistic versioning and a per-run lock, so only one run mutates at a time. Editable from the executable detail panel and the management API. Management storage requests have their own smaller transport limit; the 100 MiB stored-value limit is not the size accepted by every endpoint.

Store bigint values as decimal strings and dates as ISO strings. See Storage for commit/version behavior and lifecycle callbacks for callback storage snapshots.

  • ThymeContext — ctx.storage in context.
  • Storage — persistence model and editing in the Console.