worker.trigger(...) call.
For the underlying model (how channels are addressed, multiplexed, and torn down), see Channels
architecture.
Payload size
The limit applies to the complete serialized UTF-8 JSON envelope, measured in bytes. The Rust, Node, Python, and Go SDKs support messages up to 64 MiB. The browser SDK has a 16 MiB outbound limit and does not fragment messages because browser WebSocket APIs do not expose frame control. Browser workers also have a 16 MiB receive limit. For Rust, Node, Python, and Go, messages up to 16 MiB are sent as one text frame. Larger messages, up to and including 64 MiB, are sent as one fragmented WebSocket text message using multiple frames. The engine sends every message larger than 1 MiB to a worker as one fragmented text message of 1 MiB frames, so no frame it sends exceeds a worker’s frame size limit. Applications send and receive these messages through the usual function APIs. The receiving worker must run SDK version 0.24.5 or later to accept messages larger than 16 MiB. An updated engine checks the serialized envelope against the target worker’s receive limit and returnspayload_too_large to the caller when the target cannot accept it. The engine sets
that limit when the worker registers:
- A browser worker gets 16 MiB.
- A worker that declares the
large-messages.v1protocol feature gets 64 MiB, whatever version it reports. The Rust, Node, Python, and Go SDKs declare it from 0.25.0; the browser SDK does not. - Any other worker gets 64 MiB when the version it reports is an SDK version of 0.24.5 or
later, written as semver (
0.24.6,0.25.0-rc.5) or PEP 440 (0.25.0rc5,0.24.5.post1). It gets 16 MiB when the version is missing, cannot be parsed, or is older, including pre-releases of 0.24.5. Other features, such asobserve.v1, do not count.
large-messages.v1, so the engine relies on the
version they report. A Rust worker on one of them that sets WorkerMetadata.version to its own
version instead of the SDK version therefore stays at 16 MiB. Upgrade it to SDK 0.25.0 or later.
Above 64 MiB, the Rust, Node, Python, and Go SDKs reject the message locally with
payload_too_large; the error message links to this Payload size section. Engines
older than the updated size check forward messages as a single frame without checking the target’s
limit. An older worker may then disconnect if the message is too large for it. Use an engine and
SDKs from the same release, or newer.
The engine reads up to 64 MiB per message from a worker, whether the message arrives as one
frame or as fragments, so it also accepts the single large frames of SDKs older than 0.24.5. When a
worker sends a larger message, the engine drops it and the connection stays open. A call gets
payload_too_large as its result, and when a function returns a result that is too large, its
caller gets payload_too_large instead. Other calls on the connection are not affected. A message
the engine cannot answer, such as a call that expects no result, is dropped and logged.
Observer activations follow the same limits, and the engine keeps at most 64 MiB of one observed
event (every field its observers capture, input and output counted separately). An event over either
limit is not delivered: the observer counts a TOO_LARGE drop and the engine logs a warning. See
Observers / Event size.
Use a channel for payloads above 64 MiB. Channels stream payload bytes separately from the JSON
function envelope. See Using channels.
Using channels
A channel is created by one worker and has two local stream ends:writer and reader; plus two
serializable refs (writerRef / readerRef) that can be handed to another function. The
subsections below cover the local-end API: creating a channel, writing bytes into its writer, and
reading bytes from its reader.
Create a channel
worker.createChannel() returns a channel with two local stream objects and two serializable refs:
writer and reader are the local stream ends, and writerRef / readerRef are the tokens you
pass to another function so it can read or write the other end.
- Node / TypeScript
- Python
- Rust
Write to a channel
Write the payload to the localwriter and close it when finished. The bytes flow through the
engine to whichever worker holds the matching reader.
- Node / TypeScript
- Python
- Rust
Read from a channel
Read the localreader until the other end closes. The bytes arrive in the order they were written
by whichever worker holds the matching writer.
- Node / TypeScript
- Python
- Rust
Using channels across functions
A channel only becomes useful once both ends are owned by different code paths. Typically one function that holds the localwriter / reader and another that receives the matching ref in its
payload. The two subsections below cover that handoff: first how to send a ref alongside a normal
trigger call, then how the receiving function turns it back into a live stream to read or write.
Pass a channel ref to another function
Pass thereaderRef (or writerRef) as part of a normal function invocation. The receiving
function uses the ref to read from (or write to) the channel.
- Node / TypeScript
- Python
- Rust
ChannelReader / ChannelWriter
objects before the handler runs, so the ref arrives ready to iterate or write to. Rust receives the
ref in JSON and reconstructs the reader or writer explicitly with ChannelReader::new(...) or
ChannelWriter::new(...).
Read from a channel ref
- Node / TypeScript
- Python
- Rust
Write to a channel ref
- Node / TypeScript
- Python
- Rust