Architecture
Learn how Trama fits into a microservices architecture and how the runtime coordinates distributed workflows through an HTTP API, queue-backed workers, persistent saga state, and observability.
Why orchestration exists
In microservices systems, business transactions span multiple services with different failure modes. Trama exists to keep retries, compensation, state tracking, and observability in one orchestration layer instead of scattering that logic across every service boundary.
Core Components
Client→
Ktor API→
Queue→
Processor→
Executor→
Services
Application: REST endpoints, callback receiver, and runtime bootstrap.RuntimeBootstrap: wires queue, consumer, processor, store, and observability.SagaExecutionProcessor: worker orchestration, ack/retry control, and rate-limit integration.WorkflowExecutor: node dispatch, retry policy decisions, compensation transitions. Delegates toTaskNodeHandler(sync and async HTTP) andSwitchNodeHandler(JSON Logic branching).CallbackReceiver: validates HMAC-signed callback tokens and re-enqueues async executions to resume.SagaExecutionStore: persistence abstraction (Redis/Postgres backing).
Execution Lifecycle
- Definition is validated and stored (or provided inline).
- Execution request enqueues a workflow payload.
- Consumer claims ready messages and hands them to workers.
- Executor dispatches each node — sync task nodes make HTTP calls immediately; async task nodes fire a request, pause the execution, and wait for a callback.
- For async nodes: the external service POSTs to the callback endpoint with a signed token. The callback receiver validates the token and re-enqueues the execution to resume from the next node.
- Switch nodes evaluate JSON Logic expressions and route to the matching branch without making any HTTP call.
- On failure, the executor applies the retry or backoff policy, then drives compensation in reverse order if retries are exhausted.
- Metrics and traces are emitted throughout all stages.
Mermaid Diagram
flowchart TB classDef api fill:#1e293b,stroke:#60a5fa,stroke-width:2px,color:#e5e7eb; classDef runtime fill:#1e293b,stroke:#4ade80,stroke-width:2px,color:#e5e7eb; classDef infra fill:#1e293b,stroke:#f59e0b,stroke-width:2px,color:#e5e7eb; classDef obs fill:#1e293b,stroke:#c084fc,stroke-width:2px,color:#e5e7eb; classDef external fill:#1e293b,stroke:#fb7185,stroke-width:2px,color:#e5e7eb; C[Client]:::api subgraph Trama direction TB A[Ktor API]:::api subgraph Ingress direction LR CB[Callback Receiver]:::api Q[Redis Queue]:::infra end P[Saga Processor]:::runtime E[Saga Executor]:::runtime ST[Postgres Store]:::infra M[Prometheus Metrics]:::obs T[OpenTelemetry Traces]:::obs end S[External Services]:::external C --> A A --> Q A --> CB CB --> Q Q --> P P --> E E --> S E --> ST S -->|async callback| A P -.-> M E -.-> T