Overview
Both@durable-effect/workflow and @durable-effect/jobs emit structured events at each meaningful lifecycle point. These events can be delivered to an external HTTP endpoint for observability, discarded silently, or captured in-memory during tests.
The core abstraction is the EventTracker Effect service. The engine emits events through it; the implementation decides what to do with them.
EventTracker service
Workflow events
The following events are emitted during workflow execution:| Event type | When emitted |
|---|---|
workflow.started | Workflow begins execution |
workflow.completed | Workflow finishes successfully |
workflow.failed | Workflow fails with an error |
workflow.paused | Workflow pauses (sleep or retry delay) |
workflow.resumed | Workflow resumes after a pause |
step.started | A step begins executing |
step.completed | A step finishes successfully |
step.failed | A step fails |
retry.scheduled | A retry delay is scheduled |
retry.exhausted | All retry attempts have been used |
sleep.started | A sleep begins |
sleep.completed | A sleep finishes (workflow resumes) |
Internal vs wire event schemas
Internal vs wire event schemas
The library uses two sets of schemas for each event type:
- Internal schemas (
InternalWorkflowEventSchema, etc.) — used by the library’s own code to construct events. - Wire schemas (
WorkflowStartedEventSchema, etc.) — the shape sent to your external endpoint after enrichment withenvandserviceKey.
@durable-effect/core if you need to validate or parse events on the receiving end.Job events
The following events are emitted during job execution:| Event type | When emitted |
|---|---|
job.started | Job instance is created |
job.executed | Execute function completes successfully |
job.failed | Execute function throws an error |
job.retryExhausted | All retry attempts have been used |
job.terminated | Job instance is terminated and state purged |
debounce.started | First event is added to a debounce job |
debounce.flushed | A debounce batch is processed |
task.scheduled | Execution is scheduled for a task job |
Configuring HTTP batch delivery
Pass atracker object when creating the engine. Events are buffered and sent as a JSON batch via HTTP POST.
For workflows:
Full HttpBatchTrackerConfig
env and serviceKey before sending. Events are batched up to batchSize and flushed automatically. If delivery fails, the tracker retries with exponential backoff and then silently drops the batch rather than failing the workflow.
HttpBatchTrackerLayer
If you are composing layers manually outside of the engine factory, use HttpBatchTrackerLayer directly:
NoopTrackerLayer
When no tracker config is provided, the engine defaults to NoopTrackerLayer. It implements the EventTracker interface but discards every event:
In-memory tracker for testing
UsecreateInMemoryTracker or createInMemoryTrackerLayer in tests to capture and assert on emitted events without any HTTP calls.
InMemoryTrackerHandle
Testing example
Testing example
Event schema types
All schemas are exported from@durable-effect/core. There are two categories:
- Internal types (e.g.,
InternalWorkflowStartedEvent) — the shape used internally by library code when constructing events. - Wire types (e.g.,
WorkflowStartedEvent) — the enriched shape sent to your endpoint, includingenvandserviceKey.
