> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zavu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Runtime versions

> How runtime pinning works and when to upgrade.

## Runtime versions

Each Zavu Function is built against a specific **runtime version** — a sealed
bundle containing `@zavu/functions`, our SDK, and a small set of curated
libraries. Runtime versions are immutable: once a function is deployed against
runtime `v7`, it keeps using that exact version forever, even if we publish
newer ones.

This means your function is **stable**. We can iterate the runtime without
breaking what's already live.

## How pinning works

```
+-----------------------+        +---------------------------+
| You: zavu deploy      | -----> | Function pinned to v7     |
+-----------------------+        +---------------------------+
                                              ^
                                              |
                                          (forever)
+-----------------------+
| Zavu: publishes v8    |
+-----------------------+

# Your function is still on v7. Unaffected.

+--------------------------------+        +--------------------------+
| You: zavu deploy --update-runtime| ---->| Function now pinned to v8|
+--------------------------------+        +--------------------------+
```

* **First deploy**: function is pinned to whatever the latest runtime version
  was at deploy time.
* **Subsequent deploys** (`zavu deploy`): keep the same pin. The runtime
  doesn't change even if newer versions are available.
* **Opt-in upgrade** (`zavu deploy --update-runtime`): bump to the latest.

## Checking your pin

```sh theme={null}
curl https://api.zavu.dev/v1/functions/$FN_ID \
  -H "Authorization: Bearer $KEY" \
  | jq '.function.runtimeVersion'
```

```
"v7"
```

Same version across deploys means same runtime.

## Auditing per-deployment

Every deployment record stores which runtime ran:

```sh theme={null}
curl https://api.zavu.dev/v1/functions/deployments/$DEPLOYMENT_ID \
  -H "Authorization: Bearer $KEY" \
  | jq '.deployment | {version, runtimeVersion, deployedAt}'
```

```json theme={null}
{
  "version": 4,
  "runtimeVersion": "v7",
  "deployedAt": "2026-04-12T14:23:00.000Z"
}
```

Useful for "which deploy was on which runtime when the bug happened?".

## Upgrading

```sh theme={null}
zavu deploy --update-runtime
```

This deploys the current source code AGAINST the latest runtime version. If
the latest is `v8` and you were pinned to `v7`:

* The function's runtime pin moves to `v8`.
* All subsequent `zavu deploy` (without the flag) keep you on `v8`.

## When you should upgrade

Most of the time, never. Stay pinned. Upgrade only when:

| Reason                                                         | Action                                |
| -------------------------------------------------------------- | ------------------------------------- |
| **Security advisory** for your current runtime                 | Upgrade immediately. We'll email you. |
| **New feature** you want (`defineFlow`, new SDK methods, etc.) | Upgrade when convenient.              |
| **Curated dep version bump** that fixes a bug affecting you    | Upgrade.                              |
| **Performance improvements** in cold-start, bundle size        | Upgrade when convenient.              |
| Nothing changed and the new version is just a refactor         | Don't bother.                         |

## When you should NOT upgrade

* **Breaking change in the framework** that touches a method you use. Read
  the changelog first. Upgrade after fixing your code.
* **Dependency bump** in a curated lib (zod, hono, etc) — if your code
  depends on specific behavior, test first.

## Support policy

| Status            | Receives security patches | Accepts new deploys | Functions keep running |
| ----------------- | ------------------------- | ------------------- | ---------------------- |
| `active` (latest) | ✅                         | ✅                   | ✅                      |
| `deprecated`      | ✅ for 6 months            | ✅                   | ✅                      |
| `eol`             | ❌                         | ❌ (deploy fails)    | ✅ existing only        |

When a version moves to `deprecated` or `eol`, we email project owners 60 days
before the transition with the affected function list.

<Note>
  "EOL" never means the runtime disappears. Deployed functions keep their
  pinned runtime indefinitely — EOL only blocks new deploys against that
  version.
</Note>

## Bulk upgrade

When a security patch lands, you can sweep all your functions:

```sh theme={null}
# List all (we'll add `--outdated` filter soon; for now use the API)
zavu senders list      # to find sender IDs
zavu agents executions # for activity insight

# Per function:
cd ./my-function
zavu deploy --update-runtime
```

For programmatic bulk migration:

```sh theme={null}
for fn_id in $(curl -s https://api.zavu.dev/v1/functions \
  -H "Authorization: Bearer $KEY" \
  | jq -r '.items[].id'); do
  curl -X POST "https://api.zavu.dev/v1/functions/$fn_id/deploy" \
    -H "Authorization: Bearer $KEY" \
    -d '{"updateRuntime":true}'
done
```

## What's actually in a runtime version

The current runtime (\~3 MB) contains:

| Package           | Version range    | Purpose                                                        |
| ----------------- | ---------------- | -------------------------------------------------------------- |
| `@zavu/functions` | platform-bundled | `defineFunction`, `defineAgent`, `defineTool`, `verifyWebhook` |
| `@zavudev/sdk`    | latest stable    | Call Zavu APIs                                                 |
| `zod`             | ^3.22            | Schema validation                                              |
| `hono`            | ^4               | HTTP-friendly utilities                                        |
| `dayjs`           | ^1               | Date manipulation                                              |
| Node built-ins    | —                | `fetch`, `crypto`, `Buffer`, etc.                              |

If you `import` one of these in your function source code, esbuild marks it
as external and the runtime resolves it at execution time — no `npm install`
needed, no bundle bloat.

To use a package NOT in the bundled set, declare it in `package.json` and the
build worker installs it during `zavu deploy`:

```json theme={null}
{
  "dependencies": {
    "openai": "^4.20.0"
  }
}
```

## CPU architecture

Each function runs on **arm64** by default (AWS Graviton). You can opt into **x86\_64** when an npm dependency requires it:

| Architecture      | Compute cost | When to use                                                                                      |
| ----------------- | ------------ | ------------------------------------------------------------------------------------------------ |
| `arm64` (default) | 1.00×        | All pure-TypeScript code and any native module with modern arm64 prebuilds.                      |
| `x86_64`          | 1.25×        | Some image / crypto / wasm libs only publish x86 prebuilts. Bumps every invocation by 25% units. |

### Setting it

Pick whichever fits your workflow — they compose, with CLI flag > package.json > server default.

<CodeGroup>
  ```json package.json theme={null}
  {
    "name": "my-function",
    "zavu": {
      "architecture": "x86_64"
    },
    "dependencies": {
      "sharp": "^0.33.0"
    }
  }
  ```

  ```sh CLI flag theme={null}
  zavu deploy --arch x86_64
  ```

  ```text Dashboard theme={null}
  Function detail → Settings → CPU architecture → x86_64
  ```
</CodeGroup>

The change applies on the next `zavu deploy` — Lambda doesn't allow swapping architecture in-place, so a new function deployment is required.

### Pricing impact

The architecture multiplier compounds with the memory multiplier. Examples:

| Memory  | arm64 units / call | x86\_64 units / call |
| ------- | ------------------ | -------------------- |
| 128 MB  | 1.00               | 1.25                 |
| 256 MB  | 2.00               | 2.50                 |
| 512 MB  | 4.00               | 5.00                 |
| 1024 MB | 8.00               | 10.00                |

If you're approaching your plan's monthly quota, prefer arm64 first — switch to x86 only when you've confirmed a specific dep needs it. See [Pricing model](/concepts/functions#pricing-model) for plan quotas.

### When you actually need x86

Modern packages (most of npm) ship arm64 prebuilts. You generally only need x86 for:

* Older versions of native libs (`bcrypt < 5`, very old `sharp`, `canvas`)
* Wasm-wrapped tools without arm64 bindings
* Code that uses `process.arch === "x64"` assumptions

A `zavu deploy` on arm64 with an incompatible package usually fails with a clear "Could not find prebuild for ... arm64" error — that's your cue to switch.

## Rolling back

We don't have a `--runtime <version>` flag yet for explicit version pinning.
If an upgrade breaks you and the previous runtime is still
`active`/`deprecated` (not yet EOL), the workaround is to deploy from a
previous source commit **without** `--update-runtime`:

```sh theme={null}
git checkout <pre-upgrade-commit>
zavu deploy   # uses the pinned runtime, no flag → keeps current pin
```

If the pin is already on the broken version, the most reliable rollback is
to delete and recreate the function with the previous runtime explicitly
provisioned by Zavu support.

<Tip>
  This is rare in practice — runtime upgrades are tested in our staging
  environment before public release. But if you hit it, contact support and
  we'll help with the manual repin.
</Tip>
