a9script

Docs / The language & scripts

Limits and safety

Everything here is a number the platform holds you to, or a thing it will not let you do. None of it is arbitrary: each one exists because the alternative is a run, an endpoint or a machine that nobody can rescue at three in the morning.

What bounds a run

DefaultWhat happens at it
Time for one segment of a run60000 msThe run ends with EXECUTION_LIMIT.
Steps one run may take, across every segment5000000The same.
Values one run may hold at once100000The run ends with HEAP_LIMIT.

A segment is one stretch of running, not the whole job. checkpoint() ends a segment and starts the next one with a fresh time budget — so a job that takes hours is perfectly normal, as long as it is cut into pieces:

log("first batch done");
checkpoint();
log("this line runs in the next segment, with a fresh budget");

Time spent parked costs nothing. A script can be given a longer or shorter segment budget of its own, up to a ceiling the installation sets.

A budget cannot be caught. try/catch catches errors, including calls that could not be made; it does not catch the platform ending a run that is out of time or memory. A script must not be able to trap its own kill switch.

If you are hitting these, the answer is almost never a bigger number. Holding 100000 values means the data is in the run instead of in a dataset; running out of steps means a loop is doing work the platform has a bulk call for. Both are the shape that does not scale.

What bounds a call

  • Repeats. A call that failed in a way worth asking again about is repeated 3 times by default — four attempts in all — waiting longer each time. A configured call can ask for more, up to ten. What counts as worth asking again depends on the call: one that changes something is never repeated on a 5xx unless it is marked idempotent.
  • Silence. A call is cut off after 5 minutes without receiving any data. It is not a limit on how long the call may take: a slow, large download finishes as long as bytes keep arriving.
  • Absolutely. One call and all its repeats together may not exceed 60 minutes. Nothing you configure can lengthen this.
  • One wait. A run suspended because the far end said not now wakes after at most 24 hours, whatever the far end asked for. A longer answer is taken as 24 hours and the run’s log records both numbers, so nothing pretends the far end asked for the number it got. checkpoint refuses a longer wait outright: waking a day late does the work at the wrong time. A run that wants to wake up next week is a schedule, not a wait.

What bounds a door

Your endpoints are on the public internet, so they are metered.

  • A request body over 1 MB is refused before it is read.
  • A tenant may send 1200 requests a minute across all its endpoints; one endpoint may take 600. Over either, the caller gets 429 with a Retry-After — which every serious webhook sender already knows how to honour.
  • Verification comes first, and refusals cost nothing: a caller with no credential is turned away before it can spend any of your allowance.

An installation can change these numbers; the defaults are what you get.

What the platform will not let you do

  • Reach the network except through a connection. There is no HTTP client to import. This is what makes credentials, retries, origin limits, redaction and the recorded request true of every call, with nothing to remember.
  • Hold a credential in a script. Secrets go on connections and mail accounts, are encrypted at rest, and never come back to any surface — not to a form, not to a command, not into a run’s recorded request.
  • Touch a filesystem. Files are stored by the platform, and a script reaches them two ways: by the handle it was given, or by name out of a file store. Either way the bytes stay outside the run — a script holds a handle or a path, never the file.
  • Reach another environment. Sandbox and production are sealed off from each other, and so is every other tenant. Promoting work between your own two environments is a deliberate, reviewed act — never something a script does.
  • Return something that is not data. A result is stored as JSON, so a function, a bigint or a value that refers to itself fails the run rather than being silently trimmed.

Which guarantee is which

Three different promises, easy to conflate and expensive to guess at.

One event a sender sent becomes at most one event the platform accepted. For senders that ship a delivery id — most of the well-known ones — a repeated delivery of the same event is recognised and dropped at the door.

One accepted event runs at most once. Work is not handed out twice, and a run that was interrupted continues rather than starting again. Delivery can still fail — when every attempt is exhausted, what is left is a dead letter, and finding it is on When the work jams.

Neither one makes your script idempotent. If the far end charges a card or raises a ticket, and your integration must survive the sender genuinely sending the same order twice — a different event, hours later, because their system retried a business process rather than a delivery — that is yours to handle: remember what you have already done (a mapping, a dataset key, an idempotency key the far end honours) and check it before you act.

And for a sender that signs no delivery id, neither guarantee answers “is this request fresh”. That is what the replay window on the endpoint’s incoming authentication is for.

Production is meant to feel different

  • The environment you are in is stated at the top of the screen, and production says so in colour. Anything that changes it asks first, naming where.
  • Everything that runs carries a switch — a main script, a connection, a mail account, a watched mailbox, a function, a notification rule. Turning one off stops it at every door immediately: a webhook is still accepted and acknowledged, so the sender does not retry for days, and nothing runs. (A library, a settings script, an automation and a resource have no switch, because there is nothing there to stop.)
  • Health latches. A failure stays visible until somebody acknowledges it, rather than disappearing the moment the next run succeeds. A green screen means nothing has failed since somebody last looked — not that last night was quiet.
Rendered from docs/guide/limits-and-safety.md in the product's own repository, at build time. Found a problem on this page? Write to the address in the footer.