Siglo workflows in mission-critical production environments.
[!TIP]
For a comprehensive, step-by-step production hardening guide covering PostgreSQL OCC, @siglo/scheduler polling, zero-trust network policies, named compensation DLQs, and DevTools security, see the dedicated Production Best Practices & Operational Runbook.
1. Zero-Daemon Architecture vs Worker Clusters
Siglo does not mandate external central orchestration servers or daemons (like Temporal or Camunda). It operates as an embedded in-process execution engine that runs within your existing:
- Node.js API servers (Express, Fastify, Hono, NestJS)
- Background queue workers (BullMQ, AWS SQS)
- Stream consumers (Apache Kafka, RabbitMQ)
- Serverless / Edge functions (AWS Lambda, Google Cloud Run, Cloudflare Workers with Node.js compatibility enabled)
When to Run In-Process vs Dedicated Workers
- Synchronous Low-Latency APIs (< 5s): Execute workflows directly inside your HTTP route handlers using
@siglo/fastifyor@siglo/express. - Long-Running & Background Workflows (> 5s): Ingest requests into a queue (BullMQ or SQS) and execute workflows within dedicated worker container pools.
2. Production Checklist
- Storage Adapter Configured: Production
StorageAdapter(@siglo/postgresor@siglo/redis) registered viauseStorage(). - Idempotency Stores Enabled: Critical payment, billing, or notification steps configured with
.idempotent(). - Telemetry & Tracing: Distributed tracing activated via
@siglo/opentelemetry. - Deadlines Set: Step and workflow level
.timeout(ms)configured to prevent hung worker threads. - Compensations Tested: Sagas and compensating rollbacks tested with fault injection in staging.
- Retention Cleanup Cron: Periodic maintenance job calling
cleanExpiredCheckpoints()scheduled.
3. High-Throughput Idempotency & Distributed Locking
To prevent duplicate processing when workers run concurrently across multiple Kubernetes pods:4. Connection Pooling and Resource Limits
When running workflows with parallel fan-out (parallel([...])) or batch mapping (map(...)):
- Database Pools: Set
maxpool connections to(concurrency * workerInstances) + buffer. - Bounded Concurrency: Always specify
{ concurrency: N }onmap()steps to avoid exhausting memory or database sockets. - Node.js Memory: Set
--max-old-space-size=2048or higher if batching large datasets in memory.
5. Retention & State Cleanup
Checkpoints and audit event tables should be cleaned according to compliance retention policies:Minimal Example: Production Fastify Service
Failure Example: Handling Distributed Lock Timeouts
Testing Example
Operational Caveats
- Avoid Unbounded In-Memory Checkpoints: In-memory checkpoints default to storing state in RAM. In production, always use
@siglo/postgresor@siglo/redisto persist checkpoints across container restarts. - Graceful Worker Shutdown: Listen for
SIGTERMandSIGINTin container workloads, aborting activeAbortControllersignals to allow active steps to clean up cleanly.
