this.offload

Covers FrontMCP 1.11.0 as of

A CPU-heavy parser on the server's event loop delays every other call. this.offload() runs an exported function in a worker thread. Its arguments and result cross the boundary by structured clone; providers and request objects stay in the server.

await this.offload({ module: new URL("./parse.js", import.meta.url), export: "parse" }, [input], { budgetMs?, signal? });

Reference

this.offload(moduleRef, args, options?)

Available on execution contexts. Returns a promise of the function's result.

ParameterTypeDefaultDescription
moduleRef.modulestring | URLrequiredAbsolute file path or file: URL; package names and relative paths are refused.
moduleRef.exportstring"default"Exported function to call.
argsreadonly unknown[]requiredArguments that structured clone can carry.
options.budgetMsnumberserver budget, 30000 msExecution deadline; waiting for a worker does not count. Overrun terminates the worker.
options.signalAbortSignalthis.signalAbort terminates the worker and rejects the call.

@FrontMcp({ offload })

OptionTypeDefaultDescription
maxWorkersnumberavailable parallelism minus one, clamped to 1–4Maximum workers per scope; excess calls wait.
idleTimeoutMsnumber30000Stop an idle worker after this interval.
budgetMsnumber30000Default execution deadline.
envstring[]["NODE_ENV"]Environment variables copied into workers.

Resources and resource templates can set worker: true or worker: { budgetMs } to run reads in the pool. Jobs choose runner: "worker". These workers cannot resolve the server's providers; pass data to an exported function when it needs provider results. Resource reads receive a request signal; a resource's this.fetch() does not automatically pass it.

Caveats

Node only. Workers start on first use. Functions, live connections and other values that cannot be cloned fail with OFFLOAD_NOT_CLONEABLE. A public FrontMCP error keeps its public code and remedy across the boundary; other exceptions remain internal. Worker console output goes to stderr for stdio servers.

Usage

Moving a calculation out of a tool

count.ts
export function count(words: string[]) {
  return { words: words.length };
}
count.tool.ts
import { Tool, ToolContext, z } from "@frontmcp/sdk";

@Tool({ name: "count_words", inputSchema: { words: z.array(z.string()) } })
export class CountWords extends ToolContext {
  async execute({ words }: { words: string[] }) {
    return this.offload({ module: new URL("./count.js", import.meta.url), export: "count" }, [words]);
  }
}

Troubleshooting

Offloaded "…" ran past its … ms budget and was stopped

OFFLOAD_BUDGET_EXCEEDED means the worker was terminated. Reduce the work or raise budgetMs.

Offloaded "…" was stopped: its call was cancelled

OFFLOAD_ABORTED means the signal aborted. Shutdown can stop a worker too. Do not retry cancelled work automatically.

The worker running "…" failed: …

OFFLOAD_WORKER_FAILED (OffloadWorkerError) means a worker couldn't start (it could not start: …), or crashed or exited before it answered. The text after failed: says which.

OFFLOAD_UNSUPPORTED_RUNTIME

Run this work on Node, or leave the resource's worker option off in a browser or edge deployment.

Report a docs issue · Report a security concern privately