Docs

Local development, logs and streaming

Run functions locally exactly as in production, tail logs live, set secrets per environment, stream responses and size memory.

Updated Oct 17, 2026Open in console

Run functions locally

sov functions serve runs a function folder (or a folder of functions) the way Forge runs them: the JSON body is the event, context has the same keys, generators stream, and your plan's memory and timeout apply. Every request runs the code on disk, so there is nothing to restart; saving a file with a syntax error is reported at once.

sov functions serve ./functions --env-file .env.local
# Serving 2 function(s) — same runtime as production, reloads on every call
#   hello (python, main.py)  POST http://127.0.0.1:8787/functions/v1/hello
#   chat  (node, index.mjs)  POST http://127.0.0.1:8787/functions/v1/chat

curl -X POST http://127.0.0.1:8787/functions/v1/hello -d '{"name":"Ada"}'

Secrets come from .env and .env.local in the folder, --env-file and --env NAME=value; nothing is sent to Sovaria. Options: --timeout, --memory, --port, --no-watch.

Logs

sov functions logs                          # every function, newest first
sov functions logs send-receipt --status error --since 2h
sov functions logs --source trigger -q "Stripe"
sov functions logs send-receipt --follow    # live tail (Server-Sent Events) until Ctrl+C

In the console, Edge Functions → Triggers & logs → Invocations filters by function, status, how the run started (API call, streamed call, trigger, schedule, background) and text, and updates live. Logs are kept as long as your plan's function log retention.

Secrets per environment

Environment secrets reach every function in one environment (production, staging, an API version). A function's own secrets win over them, and they win over project secrets. Values are encrypted and never shown again.

sov functions secrets set STRIPE_KEY=sk_test_… --env staging
sov functions secrets set --env-file .env.production          # production when --env is omitted
sov functions secrets list --env staging
sov functions secrets unset STRIPE_KEY --env staging

Streamed responses

A handler that yields (Python generator, JavaScript async function*) streams each item to callers that ask for it with Accept: text/event-stream (Server-Sent Events) or ?stream=ndjson. Without it, the items come back joined (strings) or as a list. The run is still one invocation with one log entry.

def handler(event, context):
    for token in ["Hello", ", ", "world"]:
        yield token

Memory and timeout per function

Each function runs with your plan's maximum memory and run time unless you set less. Less memory also lowers its compute bill, which is measured at the memory it runs with.

sov functions limits resize-image --memory 512 --timeout 30
sov functions limits resize-image            # show setting, effective values and plan maximums
sov functions limits resize-image --reset

Cold starts

Forge keeps sandboxes started and waiting, so a call skips interpreter start-up: in a benchmark of a trivial Python function the median call went from about 119 ms to about 32 ms. Each sandbox still serves exactly one call and is then destroyed, so nothing leaks between calls or projects.

Something unclear or missing on this page?Tell us