SingleRunner
Single-process cluster layer for durable entities and workflows. It wires
Sharding with no-op runner communication, no-op runner health checks,
SQL-backed message storage, environment-based sharding configuration, and
either SQL-backed or in-memory runner storage.
This layer is meant for local, embedded, or small single-node setups where the process handles all cluster work itself. It still requires a SQL client because mailbox messages and replies are stored in SQL.
Layers
Provides a SQL-backed single-node cluster for running durable entities and workflows.
When to use
Use to run durable cluster entities and workflows in a local, embedded, or small single-node process while keeping mailbox and reply state in SQL.
Details
The layer provides Sharding, Runners, and MessageStorage. It loads
ShardingConfig from environment variables and overlays
options.shardingConfig when provided. Message storage is always SQL-backed;
runner storage is SQL-backed by default and switches to in-memory storage
when runnerStorage is set to "memory".
Gotchas
- Even when
runnerStorageis"memory", message storage remains SQL-backed, so callers must still provideSqlClientandCrypto.Crypto(used to hash over-length message deduplication keys). - Runner communication and runner health are no-op services, so this layer is for single-process use rather than multi-runner coordination.
See
- ShardingConfig.layerFromEnv for loading environment configuration before applying
shardingConfigoverrides - SqlMessageStorage.layer for the SQL-backed message storage that this layer provides
- SqlRunnerStorage.layer for the default SQL-backed runner storage selected when
runnerStorageis omitted or"sql" - RunnerStorage.layerMemory for the in-memory runner storage selected by
runnerStorage: "memory"
Signature
declare function layer(options?: { readonly runnerStorage?: "memory" | "sql"; readonly shardingConfig?: Partial<{ readonly assignedShardGroups: readonly Array<string>; readonly availableShardGroups: readonly Array<string>; readonly entityMailboxCapacity: number | "unbounded"; readonly entityMaxIdleTime: Input; readonly entityMessagePollInterval: Input; readonly entityRegistrationTimeout: Input; readonly entityReplyPollInterval: Input; readonly entityTerminationTimeout: Input; readonly maxResidentEntities: number | "unbounded"; readonly preemptiveShutdown: boolean; readonly refreshAssignmentsInterval: Input; readonly runnerAddress: Option<RunnerAddress>; readonly runnerHealthCheckInterval: Input; readonly runnerListenAddress: Option<RunnerAddress>; readonly runnerShardWeight: number; readonly sendRetryInterval: Input; readonly shardLockDisableAdvisory: boolean; readonly shardLockExpiration: Input; readonly shardLockRefreshInterval: Input; readonly shardsPerGroup: number; readonly simulateRemoteSerialization: boolean; readonly unprocessedMessageBatchSize: number; }>;}): Layer<Sharding | MessageStorage | Runners, ConfigError, Crypto | SqlClient>