drift Docs
Start
What is Drift?
The tour, if you are new here.
Use cases
Whether Drift does your thing.
Getting started
Nothing to deployed, in one command.
Architecture
How a slice is put together.
What it costs
The free grant, four unit prices, two rules.
Build
Canvas
Static sites, same origin as your API.
Tools
Operate
Auth
Accounts, tokens and scopes.
Security
Boundaries, sandboxing and hardening.
Troubleshooting
Error codes
What went wrong, and what to do about it.
Legal
Acceptable use
What a slice may not be used for.
Data processing
The DPA, and every sub-processor.

Limits and alerts

A function runs inside three declared bounds, and tells you when it crosses one. The bounds are the Driftfile's; the telling is an alert you define per function.

Limits, and what the caller sees

Three knobs bound a function, and all three are set in the slice's shape: the memory it books, plus the function timeout and the request rate for the slice. This is what a client gets when one is reached:

X-Drift-ReasonCause, and what to do
  • 504
    X-Drift-Reason
    FUNCTION-TIMEOUT
    Cause, and what to do
    The invocation outlived function_timeout. It is stopped at that budget rather than left running, so a slow function is ended and not merely abandoned.
  • 429
    X-Drift-Reason
    Cause, and what to do
    The slice passed rate_limit for the current window. Counted per account and slice, across every request that arrives however it arrives. Raise the limit, or send less.
  • 503 + Retry-After: 1
    X-Drift-Reason
    FUNCTION-MEMORY
    Cause, and what to do
    That function is holding all the memory it booked, so there is no room to start another invocation. It clears on its own as calls finish, and booking more memory raises how many can run at once. Not a 429 — your caller did nothing wrong.
  • 503 + Retry-After: 5
    X-Drift-Reason
    SLICE-MEMORY
    Cause, and what to do
    The whole slice is briefly under memory pressure and is shedding new work. It clears on its own.
  • 500
    X-Drift-Reason
    EVICTED
    Cause, and what to do
    One invocation grew past the memory its function booked and was stopped, so everything running beside it kept going. The remedy is a bigger memory: the function was booked too small, not written wrong. Your function's log carries the detail.
  • 500
    X-Drift-Reason
    FUNCTION-FAILED
    Cause, and what to do
    The function ran and produced no response that could be sent — it exited without writing one, or wrote something unreadable. Your function's log carries what it printed.

The body says nothing about Drift. Every response above carries a plain {"error":"service unavailable"} or {"error":"internal error"}, because it is your API answering your users — and they can neither read your Driftfile nor act on it. The machine-readable reason rides in the X-Drift-Reason header for your own logging and alerting, and anything actionable (which function, which figure, which remedy) goes to that function's log, where the person who can change it is the person reading.

A 503 and a 500 ask for opposite things. A 503 clears by itself, so a retry is reasonable. A 500 from an eviction repeats identically until the booking changes, which is why it carries no Retry-After: sending your caller round a loop that cannot end would be worse than telling them it failed. See memory and concurrency for how the booking decides both.

A timeout is enforced once, on one clock, so a call cannot be cut off in one place while still running in another. With no runtime limit declared the ceiling is 300 seconds, which stops a connection hanging indefinitely. The free tier resolves to 10 s of runtime, 60 requests per minute, and five function slots booking 8 MB each — 40 MB across the slice, reshapeable into any slots up to five that add up to the same. A configured slice books memory per function and sets its own.

Alerts

The slice evaluates alerts once a minute against each function's error count over a sliding window, and fires a webhook on each state change: one POST when it starts firing, one when it resolves, not one per tick. Alert definitions survive a restart.

Shell
drift atomic alert add checkout-errors checkout \
  --on errors --threshold 5 --window 5m \
  --notify webhook=https://hooks.slack.com/services/…

drift atomic alert list
drift atomic alert remove checkout-errors

Or declare them alongside the function in the Driftfile:

Driftfile
atomic:
  functions:
    - name: "post:checkout"
      handler: PostCheckout
      memory: 32MB
      alerts:
        - on: errors
          threshold: 5
          window: 5m
          notify: "webhook=https://hooks.slack.com/..."

on: errors and notify: webhook= are the whole surface. Other trigger and notify types are rejected when the alert is registered, not silently ignored. The window minimum is 60 seconds. The webhook receives JSON:

JSON
{
  "alert": "checkout-errors",
  "function": "checkout",
  "trigger": "errors",
  "transition": "firing",      // or "resolved"
  "threshold": 5,
  "window": 300,
  "at": "<RFC 3339 timestamp>"
}