How to run omes and configure the load it generates. This is the reference for local runs (laptop or a dev server) and applies equally whether you're self-hosting Temporal or running against a Temporal Cloud namespace.
For authoring new scenarios, see the README. For running against Temporal Cloud cells inside Temporal's own infra (scaffold / VCR), see the internal runbooks.
omes has three ways to run, plus cleanup. Each takes a scenario and a run-id.
--run-idis not a Temporal workflow Run ID. A Temporal Run ID identifies a single workflow execution; omes's run-id is a label for the entire load run. omes uses it to name the task queue (omes-<run-id>) and to prefix the workflow IDs it starts (w-<run-id>-<execution-id>-<iteration>). Because the task queue is derived from it, a worker and the scenario driving it must be given the same run-id.
Easiest during development — starts the worker and the scenario together. Add --embedded-server to
also start an embedded Temporal server instead of connecting to one you're already running.
go run ./cmd/omes run-scenario-with-worker --scenario workflow_with_single_noop_activity --language gogo run ./cmd/omes run-worker --run-id local-test-run --language gogo run ./cmd/omes run-scenario --scenario workflow_with_single_noop_activity --run-id local-test-rungo run ./cmd/omes cleanup-scenario --scenario workflow_with_single_noop_activity --run-id local-test-runRun any command with --help for the full, authoritative flag list.
Run configuration comes in two separate channels, split along one line:
Run flags shape the load. Scenario options decide what the load does.
How many iterations, how fast, how long, how many at once — that is the same question for every scenario, so it is a built-in flag. What each iteration actually executes is particular to one scenario, so it is an
--option.
list-scenarios shows both for a given scenario: the run configuration it will use, with the flag that
overrides each value, and the options it accepts.
These apply to every scenario and override its defaults:
| Flag | Meaning |
|---|---|
--iterations |
Total iterations to run (mutually exclusive with --duration). |
--duration |
How long to keep starting new iterations (mutually exclusive with --iterations). |
--max-concurrent |
Max iterations running at once. |
--max-iterations-per-second |
Rate limit on starting iterations (0 = unlimited). |
--max-iteration-attempts |
Attempts per iteration (default 1). |
--timeout |
Hard stop; cancels in-flight iterations and exits non-zero. |
If you set neither --iterations nor --duration, the scenario's own default applies — and most
scenarios declare none, in which case omes's default does. list-scenarios states which is the case for
each scenario.
Scenario-specific knobs are passed as repeated --option key=value pairs. Each scenario declares the
options it accepts; list-scenarios prints them with their types and defaults. A value may be loaded
from a file with @: --option sleep-activity-json=@sleep.json.
Some options are feature options: they turn on by default when the server reports support for the
underlying capability — some capabilities are reported per namespace, others by the server as a whole
— and off when it does not. Pass =false to force one off regardless; explicitly passing =true
where support is not reported fails the run. list-scenarios marks these with a dynamic default
instead of a fixed one.
go run ./cmd/omes run-scenario-with-worker --scenario throughput_stress --language go \
--option nexus-endpoint=my-endpoint --run-id my-runA single omes run executes exactly one scenario. To run two load shapes at the same time, start two
runs, each with its own --run-id (hence its own task queue). Composing load happens within a
scenario (its action tree / executor), not by combining scenarios on the command line.
run-worker (and run-scenario-with-worker) accept worker-tuning options:
--worker-profile <name>selects a code-defined worker configuration profile in the language harness. It is forwarded to the worker via theOMES_WORKER_PROFILEenv var (it is not a worker CLI flag), and when set it takes precedence over the individual tuning flags (poller counts, autoscale, slot counts, activity rate limits, versioning). Non-tuning flags (task queue, client connection, logging, metrics,--worker-err-on-unimplemented) still apply. Built-in profiles:resource-based-default— the SDK resource-based worker tuner.throughput-stress-baseline— a fixed config forthroughput_stressruns (workflow cache 50, 8 workflow-task slots, 32 activity/local-activity slots, 2 workflow-task pollers, 4 activity pollers).
--task-queue-suffix-index-start/--task-queue-suffix-index-endrun the worker across an inclusive range of task queues (<task-queue>-<start>…<task-queue>-<end>), for multi-task-queue scenarios.--embedded-serverstarts an embedded localhost server (cannot be combined with TLS or a non-default--server-address).
go run ./cmd/omes run-scenario-with-worker --scenario throughput_stress --language go \
--run-id local-profile-test --worker-profile resource-based-default--version accepts a released version (v1.24.0) or a local path to an SDK checkout — useful for
testing unreleased SDKs:
go run ./cmd/omes run-scenario-with-worker \
--scenario workflow_with_single_noop_activity --language go --version /path/to/go-sdk- A default run is quiet. Per-iteration progress logs at debug level, so at the default
infolevel you'll see a connect line, a long silence, then a completion line. Pass--log-level debugto watch iterations, and always sanity-check that work actually ran rather than trusting the absence of errors. - Language names and aliases.
--languageacceptsgo,python(py),java,typescript(ts),dotnet(cs),ruby(rb). If you pass an unknown value the error message lists the accepted set. - A scenario accepts exactly the options it declares. An unknown name or a value of the wrong type
is rejected before the run starts — before omes even connects, and before
run-scenario-with-workerbuilds a worker — and every problem is reported at once.list-scenariosshows what each scenario accepts, including defaults. A scenario that declares no options accepts none. - Feature options are on by default against a capable namespace. They resolve after omes connects,
by probing the namespace's reported capabilities, so pass
=falseexplicitly to force one off. Explicitly passing=trueagainst a namespace that doesn't report the capability fails the run. --iterationsand--durationare mutually exclusive. Setting both is rejected before the run starts.- Bad input prints as a message, not a stack trace. An unknown scenario or option, a malformed
--option, a feature the namespace doesn't support, or conflicting run flags print one line and exit non-zero. A stack trace means something failed during the run — so if you see one, read it as a real failure rather than a typo. - Some option names read like run flags but are not.
throughput_stressaccepts--option internal-iterations, which sets how much work happens inside one iteration;--iterationssets how many iterations run. Setting the wrong one produces a valid run at the wrong load rather than an error, so checklist-scenarioswhen a name looks familiar.