Resonate Defaults
Overview
Use this skill when an agent (or user) needs to answer a "what is the default for X in Resonate?" question. The canonical reference page lives at:
That page is the single source of truth — every value below mirrors it. If the canonical page and this skill disagree, the canonical page wins and this skill is stale.
The skill carries a quick-lookup table so an agent can answer common questions in one hop. For anything not in the table, read the canonical page or the source files listed under Source-of-truth files.
When to use this skill
Trigger this skill when the question is about a default value, especially:
- "What does
ctx.run retry by default?"
- "What is the default timeout for a durable function?"
- "What is the default
ttl / group / target?"
- "What does
Exponential() default to without arguments?"
- "What is
RESONATE_URL if I do not set it?"
- "What is the default Resonate server port / log level / storage backend?"
- Any "I called the constructor /
Options(...) / Exponential(...) with no args — what did I get?"
If the question is how to configure something (versus what the default is), reach for the relevant resonate-basic-* or resonate-server-deployment skill instead.
Source-of-truth files
When the canonical page does not answer the question, read these files directly. Do not guess or deflect.
src/options.ts — per-call Options defaults (timeout, target, tags, version, nonRetryableErrors, etc.)
src/retries.ts — Exponential, Constant, Linear, Never constructor defaults
src/resonate.ts — init defaults (group, ttl, pid, verbose, logLevel, prefix, url resolution)
src/network/http.ts — HttpNetwork defaults (request timeout, URL fallback)
src/context.ts — runtime resolution that picks Exponential for regular functions vs Never for generator functions
resonate/options.py — Options dataclass defaults
resonate/retry_policies/exponential.py, constant.py, linear.py, never.py — retry-policy constructor defaults
resonate/resonate.py — init defaults (group, ttl, pid, log_level, env-var resolution)
resonate/processor.py — workers cap (min(32, workers or os.cpu_count() or 1))
resonate/src/options.rs — Options struct defaults (note: no per-call retry_policy field)
resonate/src/resonate.rs — init defaults (group, ttl, pid, env-var resolution)
Tagged 0.1.0 (the tag has no v prefix — go get github.com/resonatehq/resonate-sdk-go@0.1.0 to pin it; @latest does not resolve to the tag). Values verified against the 0.1.0 tag source. The canonical doc-page summary lives in the Go SDK skill guide § Defaults.
resonate.go — Config defaults (TTL 60s, AsyncHeartbeat, NoopEncryptor, empty Prefix), New network resolution (URL → Network → RESONATE_URL → ErrNetworkRequired), DefaultTopLevelTimeout, DefaultRetryPolicy
context.go — child-call defaults (DefaultChildTimeout), RunOpts/RPCOpts/PromiseOpts/DetachedOpts
- the retry-policy types (
ConstantRetry, LinearRetry, ExponentialRetry, NoRetry) and NewNonRetryable
httpnet/http.go — HTTPOptions{Group} (the default group is "default"); groups are set on the transport, not on Config
promises.go / schedules.go — the direct Promises / Schedules sub-clients (PromiseCreateOptions, ScheduleCreateOptions, DefaultTopLevelTimeout as their timeout fallback)
Server flag defaults are mirrored on the operator-facing page https://docs.resonatehq.io/deploy/run-server#configuration until iter-65 lands file:line citations from the server crate.
Quick-lookup table
The values below mirror the canonical page. If you cite from this table, the value is current as of the canonical page's last update; if the question is high-stakes, double-check by visiting the canonical URL.
Retry policies (per-call options)
| Policy |
TypeScript default |
Python default |
Rust |
Go |
Exponential delay / Base |
1000 ms |
1 sec |
not exposed |
Base 100ms (in DefaultRetryPolicy) |
Exponential factor |
2 |
2 |
not exposed |
×2 (implicit) |
Exponential maxRetries / MaxAttempts |
Number.MAX_SAFE_INTEGER |
sys.maxsize |
not exposed |
MaxAttempts: 3 (bounded) |
Exponential maxDelay / Max |
30_000 ms |
30 sec |
not exposed |
Max 30s |
Constant delay / Delay |
1000 ms |
1 sec |
not exposed |
required field (ConstantRetry{MaxAttempts, Delay}) |
Constant maxRetries / MaxAttempts |
Number.MAX_SAFE_INTEGER |
sys.maxsize |
not exposed |
required field |
Linear delay / Base |
1000 ms |
1 sec |
not exposed |
required field (LinearRetry{MaxAttempts, Base}) |
Linear maxRetries / MaxAttempts |
Number.MAX_SAFE_INTEGER |
sys.maxsize |
not exposed |
required field |
Never / NoRetry |
no parameters |
no parameters |
not exposed |
NoRetry (no parameters) |
Both TS and Py compute the n-th Exponential delay as min(delay * factor^attempt, maxDelay); Linear is delay * attempt; Never is 0 on attempt 0 and null/None after. Go's retry policies ARE exposed (unlike Rust) as the ConstantRetry / LinearRetry / ExponentialRetry / NoRetry structs implementing resonate.RetryPolicy, and Go's DefaultRetryPolicy is ExponentialRetry{MaxAttempts: 3, Base: 100ms, Max: 30s, Jitter: true} — a bounded 3-attempt default, the sharpest cross-SDK asymmetry (see below). Go durations are native time.Duration, never raw ms/sec.
ctx.run / per-call Options defaults
| Field |
TypeScript |
Python |
Rust |
Go |
id |
undefined (auto) |
None (auto) |
n/a (struct does not carry it) |
n/a (passed to Run/RPC, not the opts struct) |
timeout |
86_400_000 ms = 24 h |
31_536_000 sec = 1 year |
Duration::from_secs(86_400) = 24 h |
DefaultChildTimeout / DefaultTopLevelTimeout = 24 h (time.Duration) |
target |
"default" |
"default" |
"default" |
configured group ("default") |
tags |
{} |
{} |
empty HashMap |
nil map |
version |
0 |
0 |
0 |
reserved, not yet consumed (issue #5) |
retryPolicy / retry_policy / RetryPolicy |
resolved at call time: Exponential() for regular fn, Never() for generator fn |
lambda f: Never() if isgeneratorfunction(f) else Exponential() |
no per-call retry policy (see asymmetries) |
has per-call RetryPolicy (like TS/Py); nil → DefaultRetryPolicy = ExponentialRetry{MaxAttempts: 3, ...} |
nonRetryableErrors / non_retryable_exceptions |
[] |
() |
n/a |
via resonate.NewNonRetryable(err) wrapper |
durable |
n/a |
True |
n/a |
n/a |
idempotency_key |
n/a |
lambda id: id (identity) |
n/a |
n/a |
encoder / Encryptor |
n/a |
None |
n/a |
NoopEncryptor (set on Config.Encryptor) |
The short answer to "what does ctx.run retry by default in the TypeScript SDK?" is Exponential() (1 s base, ×2 factor, 30 s cap, effectively unbounded retries) for regular async functions, and Never() for generator functions. In Go the answer is different: DefaultRetryPolicy is bounded to 3 attempts (ExponentialRetry{MaxAttempts: 3, Base: 100ms, Max: 30s, Jitter: true}).
Init defaults (new Resonate() / Resonate() / Resonate::local() / resonate.New(Config{}))
| Field |
TypeScript |
Python |
Rust |
Go |
group |
"default" |
"default" |
"default" |
"default" (set on the transport via httpnet.HTTPOptions{Group}, NOT on Config) |
ttl |
60_000 ms = 60 sec |
10 sec |
60_000 ms (remote) / u64::MAX (local) |
60s (Config.TTL, a time.Duration) |
pid |
random UUID |
uuid.uuid4().hex |
"default" (local) / from network (remote) |
from network (localnet.NewLocal takes an explicit *pid) |
verbose / log_level |
verbose=false, logLevel="warn" |
logging.INFO |
n/a |
n/a |
prefix |
RESONATE_PREFIX or empty |
n/a |
RESONATE_PREFIX or empty |
Config.Prefix (empty; not read from env) |
heartbeat |
n/a |
n/a |
n/a |
AsyncHeartbeat at TTL/2 (use NoopHeartbeat{} with localnet) |
workers / concurrency cap |
none (event loop) |
min(32, workers or os.cpu_count() or 1) |
none (Tokio runtime) |
none (goroutines) |
| HTTP request timeout |
RESONATE_TIMEOUT or 10_000 ms |
n/a |
n/a |
n/a |
| HTTP URL fallback |
"http://localhost:8001" |
derived from scheme/host/port |
derived from scheme/host/port |
none — URL→Network→RESONATE_URL, else ErrNetworkRequired |
Environment variables
| Env var |
Default when unset |
RESONATE_URL |
unset → local in-memory mode in TS/Py/Rs; TS HttpNetwork falls back to "http://localhost:8001". Go is the exception: unset (with no Config.URL/Network) → ErrNetworkRequired, not a localhost fallback |
RESONATE_HOST |
unset (Py + Rs only — TS does not consume it) |
RESONATE_SCHEME |
"http" (Py + Rs) |
RESONATE_PORT |
"8001" (Py + Rs) |
RESONATE_TOKEN |
unset |
RESONATE_USERNAME |
unset (Py only) |
RESONATE_PASSWORD |
"" (Py only) |
RESONATE_PREFIX |
unset → empty (TS + Rs) |
RESONATE_TIMEOUT |
10_000 ms (TS HTTP only) |
Go reads ONLY RESONATE_URL from the environment. It does not consult RESONATE_HOST / RESONATE_PORT / RESONATE_SCHEME / RESONATE_TOKEN / RESONATE_PREFIX. Token, prefix, and group are set explicitly on Config (or, for group, on the transport). The single env hook is RESONATE_URL; if it (and Config.URL / Config.Network) is unset, resonate.New returns ErrNetworkRequired rather than falling back to localhost.
Server flag defaults (Rust binary)
| Flag |
Default |
--server-host |
localhost |
--server-port |
8001 |
--server-bind |
0.0.0.0 |
--level |
info |
--storage-type |
sqlite |
--storage-postgres-pool-size |
10 |
--storage-mysql-pool-size |
10 |
--tasks-lease-timeout |
15_000 ms |
--tasks-retry-timeout |
30_000 ms (most deployments lower this to 500 ms) |
--observability-metrics-port |
9090 (0 disables) |
--transports-http-push-enabled |
true |
--transports-http-poll-enabled |
true |
--transports-gcps-enabled |
false |
--transports-bash-exec-enabled |
false |
--transports-http-push-auth-mode |
none |
--transports-http-push-auth-header |
Authorization |
Critical cross-SDK asymmetries
The defaults look like they line up across SDKs. They do not. Flag these explicitly when answering:
- Time units differ. TypeScript expresses durations in milliseconds. Python expresses durations in seconds. Rust is mixed —
Options.timeout is a Duration, but ttl is u64 milliseconds. Go uses native time.Duration everywhere (24 * time.Hour, 100 * time.Millisecond) — never a raw number. A naive copy-paste between SDKs is almost always wrong.
- Go's default retry policy is BOUNDED. TS and Py default to effectively-unbounded retries (
Number.MAX_SAFE_INTEGER / sys.maxsize). Go's DefaultRetryPolicy caps at MaxAttempts: 3. A Go workflow gives up after 3 attempts where the TS/Py equivalent would retry almost forever. This is load-bearing when porting — do not assume Go inherits the unbounded default.
- Per-call retry policy: Go HAS one, Rust does NOT. Go's
RunOptions/RunOpts carry a RetryPolicy field (like TS/Py); Rust has no per-call retry policy (server-side --tasks-retry-timeout governs it). Go is the TS/Py side of this split, not the Rust side.
- Go's
0.1.0 tag shipped direct Promises() and Schedules() sub-clients. r.Promises().Resolve/Reject/Cancel/Create/Get and r.Schedules().Create/Get/Delete are real methods now — prefer them over the CLI, the server HTTP API, or the low-level r.Sender().PromiseSettle (that low-level path still requires manual JSON→base64→quoted-string Value encoding; the sub-client methods do it for you via the instance's Codec). The remaining Go gap is a top-level resonate.Schedule(id, cron, fn, args) convenience wrapper that dispatches a registered function by name on a cron — Python, TypeScript, and Rust all have one; Go's Schedules().Create only creates the underlying cron-fired promise, so dispatching a registered function through it means setting the resonate:target tag and {"func":...,"args":...} param shape by hand.
Options.timeout envelope. TypeScript and Rust default to 24 h. Python defaults to 1 year (31_536_000 seconds). Same field, drastically different upper bound.
ttl unit and value. TypeScript and Rust = 60_000 ms (= 60 s). Python = 10 sec. Same name, different unit and different value.
- Retry-policy time units. TS retry-policy parameters are in milliseconds; Python's are in seconds. The curve shape is identical; the numbers are not.
- Rust has no per-call
retry_policy. Retry cadence for Rust workers is determined server-side by the --tasks-retry-timeout flag, not by anything on Options. This is a known asymmetry — do not assume Rust mirrors TS/Py here.
- Worker concurrency cap. Only Python imposes one (
min(32, workers or os.cpu_count() or 1)). TypeScript runs on the Node/Bun event loop; Rust runs on the user-supplied Tokio runtime. Neither caps task execution at the SDK layer.
Don't deflect — read the source
If a default is not in this skill and not on the canonical page, the correct response is to read the source file listed under Source-of-truth files. Do not answer with:
- "check the SDK source"
- "see the GitHub repo"
- "consult the SDK documentation"
Those answers are the deflection pattern this skill exists to eliminate. The links above are the source. Fetch them and read.
If the canonical page itself is missing a value an agent needs, that is a gap in the canonical page — file it, do not paper over it.
Verifying the answer
Two quick checks before you cite a number:
- Unit check. If the SDK is Python and the number is in milliseconds, you are wrong. If the SDK is TypeScript and the number is in seconds, you are wrong (Rust
Duration is the only place this gets nuanced).
- Asymmetry check. Before generalising a TS default to Python or Rust, re-read the asymmetries section above. Most cross-SDK questions have at least one trap.
1---2name: resonate-defaults3description: Look up default values across the Resonate server and SDKs (TypeScript, Python, Rust, Go). Use when answering "what is the default for X?" — retry policies, ctx.run timeouts, Options fields, init parameters, server flags, or RESONATE_* environment variables. Directs to the canonical defaults reference and the per-SDK source files; do not deflect to "check the SDK source" — read the source listed here.4license: Apache-2.05---67# Resonate Defaults89## Overview1011Use this skill when an agent (or user) needs to answer a "what is the default for X in Resonate?" question. The canonical reference page lives at:1213- **<https://docs.resonatehq.io/reference/defaults>**1415That page is the single source of truth — every value below mirrors it. If the canonical page and this skill disagree, the canonical page wins and this skill is stale.1617The skill carries a quick-lookup table so an agent can answer common questions in one hop. For anything not in the table, read the canonical page or the source files listed under [Source-of-truth files](#source-of-truth-files).1819## When to use this skill2021Trigger this skill when the question is about a default value, especially:2223- "What does `ctx.run` retry by default?"24- "What is the default timeout for a durable function?"25- "What is the default `ttl` / `group` / `target`?"26- "What does `Exponential()` default to without arguments?"27- "What is `RESONATE_URL` if I do not set it?"28- "What is the default Resonate server port / log level / storage backend?"29- Any "I called the constructor / `Options(...)` / `Exponential(...)` with no args — what did I get?"3031If the question is **how** to configure something (versus what the default is), reach for the relevant `resonate-basic-*` or `resonate-server-deployment` skill instead.3233## Source-of-truth files3435When the canonical page does not answer the question, read these files directly. Do not guess or deflect.3637### TypeScript SDK ([`resonatehq/resonate-sdk-ts`](https://github.com/resonatehq/resonate-sdk-ts))3839- `src/options.ts` — per-call `Options` defaults (`timeout`, `target`, `tags`, `version`, `nonRetryableErrors`, etc.)40- `src/retries.ts` — `Exponential`, `Constant`, `Linear`, `Never` constructor defaults41- `src/resonate.ts` — init defaults (`group`, `ttl`, `pid`, `verbose`, `logLevel`, `prefix`, `url` resolution)42- `src/network/http.ts` — `HttpNetwork` defaults (request timeout, URL fallback)43- `src/context.ts` — runtime resolution that picks `Exponential` for regular functions vs `Never` for generator functions4445### Python SDK ([`resonatehq/resonate-sdk-py`](https://github.com/resonatehq/resonate-sdk-py))4647- `resonate/options.py` — `Options` dataclass defaults48- `resonate/retry_policies/exponential.py`, `constant.py`, `linear.py`, `never.py` — retry-policy constructor defaults49- `resonate/resonate.py` — init defaults (`group`, `ttl`, `pid`, `log_level`, env-var resolution)50- `resonate/processor.py` — `workers` cap (`min(32, workers or os.cpu_count() or 1)`)5152### Rust SDK ([`resonatehq/resonate-sdk-rs`](https://github.com/resonatehq/resonate-sdk-rs))5354- `resonate/src/options.rs` — `Options` struct defaults (note: no per-call `retry_policy` field)55- `resonate/src/resonate.rs` — init defaults (`group`, `ttl`, `pid`, env-var resolution)5657### Go SDK ([`resonatehq/resonate-sdk-go`](https://github.com/resonatehq/resonate-sdk-go))5859Tagged `0.1.0` (the tag has no `v` prefix — `go get github.com/resonatehq/resonate-sdk-go@0.1.0` to pin it; `@latest` does not resolve to the tag). Values verified against the `0.1.0` tag source. The canonical doc-page summary lives in the [Go SDK skill guide § Defaults](https://docs.resonatehq.io/develop/go#defaults).6061- `resonate.go` — `Config` defaults (`TTL` 60s, `AsyncHeartbeat`, `NoopEncryptor`, empty `Prefix`), `New` network resolution (`URL` → `Network` → `RESONATE_URL` → `ErrNetworkRequired`), `DefaultTopLevelTimeout`, `DefaultRetryPolicy`62- `context.go` — child-call defaults (`DefaultChildTimeout`), `RunOpts`/`RPCOpts`/`PromiseOpts`/`DetachedOpts`63- the retry-policy types (`ConstantRetry`, `LinearRetry`, `ExponentialRetry`, `NoRetry`) and `NewNonRetryable`64- `httpnet/http.go` — `HTTPOptions{Group}` (the default group is `"default"`); groups are set on the transport, not on `Config`65- `promises.go` / `schedules.go` — the direct `Promises` / `Schedules` sub-clients (`PromiseCreateOptions`, `ScheduleCreateOptions`, `DefaultTopLevelTimeout` as their timeout fallback)6667### Server ([`resonatehq/resonate`](https://github.com/resonatehq/resonate))6869Server flag defaults are mirrored on the operator-facing page <https://docs.resonatehq.io/deploy/run-server#configuration> until iter-65 lands file:line citations from the server crate.7071## Quick-lookup table7273The values below mirror the canonical page. If you cite from this table, the value is current as of the canonical page's last update; if the question is high-stakes, double-check by visiting the canonical URL.7475### Retry policies (per-call options)7677| Policy | TypeScript default | Python default | Rust | Go |78|---|---|---|---|---|79| `Exponential` `delay` / `Base` | `1000` ms | `1` sec | not exposed | `Base 100ms` (in `DefaultRetryPolicy`) |80| `Exponential` `factor` | `2` | `2` | not exposed | `×2` (implicit) |81| `Exponential` `maxRetries` / `MaxAttempts` | `Number.MAX_SAFE_INTEGER` | `sys.maxsize` | not exposed | **`MaxAttempts: 3`** (bounded) |82| `Exponential` `maxDelay` / `Max` | `30_000` ms | `30` sec | not exposed | `Max 30s` |83| `Constant` `delay` / `Delay` | `1000` ms | `1` sec | not exposed | required field (`ConstantRetry{MaxAttempts, Delay}`) |84| `Constant` `maxRetries` / `MaxAttempts` | `Number.MAX_SAFE_INTEGER` | `sys.maxsize` | not exposed | required field |85| `Linear` `delay` / `Base` | `1000` ms | `1` sec | not exposed | required field (`LinearRetry{MaxAttempts, Base}`) |86| `Linear` `maxRetries` / `MaxAttempts` | `Number.MAX_SAFE_INTEGER` | `sys.maxsize` | not exposed | required field |87| `Never` / `NoRetry` | no parameters | no parameters | not exposed | `NoRetry` (no parameters) |8889Both TS and Py compute the n-th `Exponential` delay as `min(delay * factor^attempt, maxDelay)`; `Linear` is `delay * attempt`; `Never` is `0` on attempt 0 and `null`/`None` after. **Go's retry policies ARE exposed (unlike Rust)** as the `ConstantRetry` / `LinearRetry` / `ExponentialRetry` / `NoRetry` structs implementing `resonate.RetryPolicy`, and Go's `DefaultRetryPolicy` is `ExponentialRetry{MaxAttempts: 3, Base: 100ms, Max: 30s, Jitter: true}` — a **bounded 3-attempt** default, the sharpest cross-SDK asymmetry (see below). Go durations are native `time.Duration`, never raw ms/sec.9091### `ctx.run` / per-call `Options` defaults9293| Field | TypeScript | Python | Rust | Go |94|---|---|---|---|---|95| `id` | `undefined` (auto) | `None` (auto) | n/a (struct does not carry it) | n/a (passed to `Run`/`RPC`, not the opts struct) |96| `timeout` | `86_400_000` ms = **24 h** | `31_536_000` sec = **1 year** | `Duration::from_secs(86_400)` = **24 h** | `DefaultChildTimeout` / `DefaultTopLevelTimeout` = **24 h** (`time.Duration`) |97| `target` | `"default"` | `"default"` | `"default"` | configured group (`"default"`) |98| `tags` | `{}` | `{}` | empty `HashMap` | `nil` map |99| `version` | `0` | `0` | `0` | reserved, not yet consumed ([issue #5](https://github.com/resonatehq/resonate-sdk-go/issues/5)) |100| `retryPolicy` / `retry_policy` / `RetryPolicy` | resolved at call time: `Exponential()` for regular fn, `Never()` for generator fn | `lambda f: Never() if isgeneratorfunction(f) else Exponential()` | **no per-call retry policy** (see asymmetries) | **has per-call `RetryPolicy`** (like TS/Py); nil → `DefaultRetryPolicy` = `ExponentialRetry{MaxAttempts: 3, ...}` |101| `nonRetryableErrors` / `non_retryable_exceptions` | `[]` | `()` | n/a | via `resonate.NewNonRetryable(err)` wrapper |102| `durable` | n/a | `True` | n/a | n/a |103| `idempotency_key` | n/a | `lambda id: id` (identity) | n/a | n/a |104| `encoder` / `Encryptor` | n/a | `None` | n/a | `NoopEncryptor` (set on `Config.Encryptor`) |105106The short answer to **"what does `ctx.run` retry by default in the TypeScript SDK?"** is `Exponential()` (1 s base, ×2 factor, 30 s cap, effectively unbounded retries) for regular `async` functions, and `Never()` for generator functions. **In Go the answer is different: `DefaultRetryPolicy` is bounded to 3 attempts** (`ExponentialRetry{MaxAttempts: 3, Base: 100ms, Max: 30s, Jitter: true}`).107108### Init defaults (`new Resonate()` / `Resonate()` / `Resonate::local()` / `resonate.New(Config{})`)109110| Field | TypeScript | Python | Rust | Go |111|---|---|---|---|---|112| `group` | `"default"` | `"default"` | `"default"` | `"default"` (set on the transport via `httpnet.HTTPOptions{Group}`, NOT on `Config`) |113| `ttl` | `60_000` ms = **60 sec** | `10` sec | `60_000` ms (remote) / `u64::MAX` (local) | `60s` (`Config.TTL`, a `time.Duration`) |114| `pid` | random UUID | `uuid.uuid4().hex` | `"default"` (local) / from network (remote) | from network (`localnet.NewLocal` takes an explicit `*pid`) |115| `verbose` / `log_level` | `verbose=false`, `logLevel="warn"` | `logging.INFO` | n/a | n/a |116| `prefix` | `RESONATE_PREFIX` or empty | n/a | `RESONATE_PREFIX` or empty | `Config.Prefix` (empty; **not** read from env) |117| `heartbeat` | n/a | n/a | n/a | `AsyncHeartbeat` at `TTL/2` (use `NoopHeartbeat{}` with `localnet`) |118| `workers` / concurrency cap | **none** (event loop) | `min(32, workers or os.cpu_count() or 1)` | **none** (Tokio runtime) | **none** (goroutines) |119| HTTP request timeout | `RESONATE_TIMEOUT` or `10_000` ms | n/a | n/a | n/a |120| HTTP URL fallback | `"http://localhost:8001"` | derived from scheme/host/port | derived from scheme/host/port | **none** — `URL`→`Network`→`RESONATE_URL`, else `ErrNetworkRequired` |121122### Environment variables123124| Env var | Default when unset |125|---|---|126| `RESONATE_URL` | unset → local in-memory mode in TS/Py/Rs; TS `HttpNetwork` falls back to `"http://localhost:8001"`. **Go is the exception:** unset (with no `Config.URL`/`Network`) → `ErrNetworkRequired`, not a localhost fallback |127| `RESONATE_HOST` | unset (Py + Rs only — TS does not consume it) |128| `RESONATE_SCHEME` | `"http"` (Py + Rs) |129| `RESONATE_PORT` | `"8001"` (Py + Rs) |130| `RESONATE_TOKEN` | unset |131| `RESONATE_USERNAME` | unset (Py only) |132| `RESONATE_PASSWORD` | `""` (Py only) |133| `RESONATE_PREFIX` | unset → empty (TS + Rs) |134| `RESONATE_TIMEOUT` | `10_000` ms (TS HTTP only) |135136**Go reads ONLY `RESONATE_URL` from the environment.** It does **not** consult `RESONATE_HOST` / `RESONATE_PORT` / `RESONATE_SCHEME` / `RESONATE_TOKEN` / `RESONATE_PREFIX`. Token, prefix, and group are set explicitly on `Config` (or, for group, on the transport). The single env hook is `RESONATE_URL`; if it (and `Config.URL` / `Config.Network`) is unset, `resonate.New` returns `ErrNetworkRequired` rather than falling back to localhost.137138### Server flag defaults (Rust binary)139140| Flag | Default |141|---|---|142| `--server-host` | `localhost` |143| `--server-port` | `8001` |144| `--server-bind` | `0.0.0.0` |145| `--level` | `info` |146| `--storage-type` | `sqlite` |147| `--storage-postgres-pool-size` | `10` |148| `--storage-mysql-pool-size` | `10` |149| `--tasks-lease-timeout` | `15_000` ms |150| `--tasks-retry-timeout` | `30_000` ms (most deployments lower this to `500` ms) |151| `--observability-metrics-port` | `9090` (`0` disables) |152| `--transports-http-push-enabled` | `true` |153| `--transports-http-poll-enabled` | `true` |154| `--transports-gcps-enabled` | `false` |155| `--transports-bash-exec-enabled` | `false` |156| `--transports-http-push-auth-mode` | `none` |157| `--transports-http-push-auth-header` | `Authorization` |158159## Critical cross-SDK asymmetries160161The defaults look like they line up across SDKs. They do not. Flag these explicitly when answering:162163- **Time units differ.** TypeScript expresses durations in **milliseconds**. Python expresses durations in **seconds**. Rust is **mixed** — `Options.timeout` is a `Duration`, but `ttl` is `u64` milliseconds. **Go uses native `time.Duration` everywhere** (`24 * time.Hour`, `100 * time.Millisecond`) — never a raw number. A naive copy-paste between SDKs is almost always wrong.164- **Go's default retry policy is BOUNDED.** TS and Py default to effectively-unbounded retries (`Number.MAX_SAFE_INTEGER` / `sys.maxsize`). Go's `DefaultRetryPolicy` caps at `MaxAttempts: 3`. A Go workflow gives up after 3 attempts where the TS/Py equivalent would retry almost forever. This is load-bearing when porting — do not assume Go inherits the unbounded default.165- **Per-call retry policy: Go HAS one, Rust does NOT.** Go's `RunOptions`/`RunOpts` carry a `RetryPolicy` field (like TS/Py); Rust has no per-call retry policy (server-side `--tasks-retry-timeout` governs it). Go is the TS/Py side of this split, not the Rust side.166- **Go's `0.1.0` tag shipped direct `Promises()` and `Schedules()` sub-clients.** `r.Promises().Resolve/Reject/Cancel/Create/Get` and `r.Schedules().Create/Get/Delete` are real methods now — prefer them over the CLI, the server HTTP API, or the low-level `r.Sender().PromiseSettle` (that low-level path still requires manual JSON→base64→quoted-string `Value` encoding; the sub-client methods do it for you via the instance's `Codec`). The remaining Go gap is a top-level `resonate.Schedule(id, cron, fn, args)` convenience wrapper that dispatches a *registered function* by name on a cron — Python, TypeScript, and Rust all have one; Go's `Schedules().Create` only creates the underlying cron-fired promise, so dispatching a registered function through it means setting the `resonate:target` tag and `{"func":...,"args":...}` param shape by hand.167- **`Options.timeout` envelope.** TypeScript and Rust default to **24 h**. Python defaults to **1 year** (`31_536_000` seconds). Same field, drastically different upper bound.168- **`ttl` unit and value.** TypeScript and Rust = `60_000` ms (= 60 s). Python = `10` sec. Same name, different unit *and* different value.169- **Retry-policy time units.** TS retry-policy parameters are in **milliseconds**; Python's are in **seconds**. The curve shape is identical; the numbers are not.170- **Rust has no per-call `retry_policy`.** Retry cadence for Rust workers is determined server-side by the `--tasks-retry-timeout` flag, not by anything on `Options`. This is a known asymmetry — do not assume Rust mirrors TS/Py here.171- **Worker concurrency cap.** Only Python imposes one (`min(32, workers or os.cpu_count() or 1)`). TypeScript runs on the Node/Bun event loop; Rust runs on the user-supplied Tokio runtime. Neither caps task execution at the SDK layer.172173## Don't deflect — read the source174175If a default is not in this skill **and** not on the canonical page, the correct response is to **read the source file** listed under [Source-of-truth files](#source-of-truth-files). Do **not** answer with:176177- "check the SDK source"178- "see the GitHub repo"179- "consult the SDK documentation"180181Those answers are the deflection pattern this skill exists to eliminate. The links above are the source. Fetch them and read.182183If the canonical page itself is missing a value an agent needs, that is a gap in the canonical page — file it, do not paper over it.184185## Verifying the answer186187Two quick checks before you cite a number:1881891. **Unit check.** If the SDK is Python and the number is in milliseconds, you are wrong. If the SDK is TypeScript and the number is in seconds, you are wrong (Rust `Duration` is the only place this gets nuanced).1902. **Asymmetry check.** Before generalising a TS default to Python or Rust, re-read the asymmetries section above. Most cross-SDK questions have at least one trap.