Control & Config

Every API request carries a script in q. It can carry more than that. These parameters decide how long the script may run, how far a loop may go, how patient a network call should be, and how much it is allowed to hold - sensible without them, and yours to change when the defaults do not suit the job.

How a limit is decided

You ask for a value; your tier decides the ceiling; the lower of the two applies. Asking for more than your tier allows is not an error - you get your tier’s ceiling and the response tells you what you actually got. A script written against a generous limit still runs on a small plan; it just runs within that plan.

Asking for More Time
curl -X POST https://ql.ocalt.com/api \
  -d "identity=you@example.ocalt.com" \
  -d "password=your_api_key" \
  -d "execution_time=900" \
  --data-urlencode 'q=SELECT ROWS FROM DB "warehouse" TABLE "movements" SET ?all
AFTER COUNT ?all SET ?n
AFTER EMIT ?n'

Time and Repetition

Parameter Default What it governs
execution_time300Seconds the whole script may run. Always seconds - never minutes, never a suffix
loopmax1000000000Iterations any one WHILE or FOREACH may take before it is stopped
depth_max64How deeply blocks and operations may nest inside each other
on_timeouterrorerror fails the request; partial returns whatever was emitted before the cut
loopmax is not there to slow you down - a billion iterations is far more than any real job needs. It is there so that a loop whose exit condition is never met stops on its own instead of consuming your execution time and telling you nothing. When it trips, the error names the line, which is usually enough to see the mistake.

Network

Parameter Default What it governs
fetch_timeout30Seconds any single FETCH or outbound request may wait
fetch_max100Outbound requests one script may make in total
fetch_redirects5Redirects followed before a fetch gives up

A slow third party should not cost you your whole execution time. fetch_timeout is per request, so a script making twenty calls with a thirty-second timeout can still spend ten minutes waiting - which is why execution_time governs the total and always wins.

Memory and Size

Memory is what one script may hold at a single moment. It is not your storage, and deliberately so: storage is what you keep, memory is what a machine can hold in RAM while working, and there is far less of the second.

Plan memory_max Storage, for comparison
Free128 MB-
Starter1 GB8 GB
Pro4 GB64 GB
Enterprise8 GB256 GB
Syndicate Starter16 GB512 GB
Syndicate Pro32 GB1 TB
Syndicate Max48 GB8 TB
Syndicate Max B64 GB16 TB

The two scales part company on purpose. A plan with sixteen terabytes of storage is not a plan that can hold sixteen terabytes in memory - no machine can. What the storage figure promises is that you can keep that much; what the memory figure promises is how much of it one script may have open at once.

That one number decides the rest:

Limit Equal to
memory_maxYour plan’s figure above
Maximum POST sizeThe same figure - a request you cannot hold is a request you cannot process
Maximum file uploadThe same figure, and it must also fit in your remaining storage
output_maxThe same figure. A response is built in memory before it is sent, so what you can emit is what you can hold

Output is not separately capped. There is no fixed ceiling sitting under your plan waiting to truncate a large response - if you have four gigabytes of memory, you may emit four gigabytes. The only thing that stops a response is running out of the memory you were given, and that raises an error naming the figure rather than quietly cutting the output short.

An upload is checked twice: against your memory limit when it arrives, and against your remaining storage before it is written. A 4 GB upload on a plan with 4 GB of memory and 200 MB of space left is refused for the second reason, not the first.

Limits Persist

A limit you set is remembered. Send execution_time=900 once and every later request in your namespace runs with it - including requests you never make yourself.

That last part is the point. A visitor loading your Site Mode page cannot send parameters; their browser knows nothing about your plan. The limits your site runs under are the ones you set, whenever you last set them, from wherever you set them.

Set Once, Applies Everywhere After
curl -X POST https://ql.ocalt.com/api \
  -d "identity=you@example.ocalt.com" -d "password=your_api_key" \
  -d "execution_time=900" -d "fetch_timeout=60" \
  -d "q=EMIT 1"

(* From now on every script in this namespace gets 900 seconds and a
   60-second fetch timeout — the API, the Console, a cron, and every
   visitor hitting your Site Mode pages. *)

Sending a parameter on a later request changes the stored value again. Sending nothing leaves it as it was. To go back to the defaults, set them back explicitly - there is no reset, because a limit that silently returned to its default would be a limit you could not rely on.

memory_max is not one of these. It is your plan’s ceiling rather than a preference, so it cannot be set, raised, or persisted. Everything else in the table below can.

Behaviour

Parameter Default What it does
dry_runoffParse and validate the script. Nothing executes, nothing is written, no quota is spent
explainoffReturn how the script was understood - every verb, its arguments and how they chained
traceoffReturn a line-by-line record of what ran and how long each statement took
Checking a Script Without Running It
curl -X POST https://ql.ocalt.com/api \
  -d "identity=you@example.ocalt.com" -d "password=your_api_key" \
  -d "dry_run=1" \
  --data-urlencode 'q=DELETE ROWS FROM DB "shopdb" TABLE "orders" WHERE "id" IS LESS THAN 100'

(* Returns whether it parses and what it would do. The rows are untouched. *)

dry_run is what an editor, a deployment check or a code review runs. It answers “is this valid, and what does it touch?” without the answer costing anything or changing anything.

Seeing What You Got

Ask for the limits in force and the response tells you, already clamped to your tier. Useful when a script behaves differently on two plans and you want to know why.

The Limits This Request Ran Under
curl -X POST https://ql.ocalt.com/api \
  -d "identity=you@example.ocalt.com" -d "password=your_api_key" \
  -d "config=1" -d "q=EMIT 1"

(* {"execution_time":300,"loopmax":1000000000,"memory_max":"1GB",
    "fetch_timeout":30,"fetch_max":100,"tier":"free"} *)

Full Parameter Reference

Parameter Default Unit
q-The script. Required
identity-Your username or email. Required
password-Your API key. Required
execution_time300seconds
loopmax1000000000iterations
depth_max64levels
fetch_timeout30seconds
fetch_max100requests
fetch_redirects5hops
memory_maxyour planbytes, or 1GB on Free
output_maxyour memory limitbytes
on_timeouterrorerror or partial
dry_run00 or 1
explain00 or 1
trace00 or 1
config00 or 1 - report the limits in force
config_set-field:value - persist a limit for this namespace. A request parameter, never a script verb, so a script cannot raise its own ceiling. Every later request, Site Mode included, inherits it.
These are request parameters, not verbs. A script cannot raise its own ceiling from inside itself - that would make a limit something a runaway script could remove. See Quotas & Pricing for what each tier allows.