Why rflow?
rflow is Artemis without writing Rust, Defender without the vendor, Temporal without the SDK — a single fast binary where GitHub-Actions-shaped YAML gets exactly-once, reorg-aware, simulation-gated automation. Self-hosted, any custody, any EVM chain — or no chain at all.
How it compares
| rflow | OpenZeppelin Defender | Tenderly Web3 Actions | Gelato Functions | Goldsky | |
|---|---|---|---|---|---|
| Self-hosted | ✅ single binary + Postgres | ❌ SaaS | ❌ SaaS | ❌ network + SaaS | ❌ SaaS |
| Custody | Any — raw keys, AWS KMS, GCP, Privy, Turnkey, Fireblocks, PKCS#11, … | Defender Relayers hold keys | Bring-your-own signing in JS | Gelato executors | n/a (data only) |
| Automation language | Declarative YAML + expressions | JS autotasks | JS/TS actions | Solidity/TS functions | pipelines/SQL (no tx sending) |
| Exactly-once execution | ✅ journal + idempotency keys, survives kill -9 | best-effort | best-effort | onchain dedicated | n/a |
| Pre-flight simulation gate | ✅ default on every send | manual | ✅ (their infra) | ✅ | n/a |
| Reorg awareness | ✅ per-trigger confirmations: 0 | N | finalized + on_reorg: responses | limited | limited | n/a | ✅ (data) |
| Backtesting against real history | ✅ rflow replay / rflow test, dry-run by default | ❌ | ❌ | ❌ | n/a |
| Human approval gates on transactions | ✅ approval: — telegram/CLI, journaled | ✅ (multisig proposals) | ❌ | ❌ | n/a |
| Historical backfill + live in one config | ✅ start_block/end_block cursors | ❌ | ❌ | ❌ | ✅ (data) |
| Cross-chain (event on A → tx on B) | ✅ one file, same wallet address per chain + wait_for sagas | manual wiring | manual wiring | manual wiring | ❌ |
| Off-chain-only automations (cron → HTTP → Telegram) | ✅ zero networks needed | partial | partial | ❌ | ❌ |
| AI-agent operability | ✅ built-in MCP server (rflow mcp) | ❌ | ❌ | ❌ | ❌ |
| Pricing | free, open source | per-usage SaaS | per-usage SaaS | per-execution fees | per-usage SaaS |
The differentiators
Exactly-once, honestly. Every trigger occurrence is claimed once in Postgres, every step is journaled before its side effect, and every transaction carries a client-generated idempotency key enforced by a unique index. Kill the process mid-run and restart: the run resumes after the last completed step, and an ambiguous send is resolved by lookup — never re-fired blindly. Read the details; we also document what is not guaranteed.
Reorg-aware where it matters. Confirmations are per-trigger, so the same event can
alert at head (confirmations: 0) and pay at depth. rflow validate prints per-chain
depth advice and warns when a head-fired trigger sends funds. See
Reorgs.
The relayer problems are already solved. Nonce management, gas pricing, gas bumping, rebroadcast, stuck-tx replacement, per-relayer allowlists and automatic top-ups are rrelayer's job, embedded in-process. rflow never re-implements them — once a transaction is queued, rrelayer owns it.
No vendor, no ports. The engines are internal; rflow exposes a single health/status port. Everything runs on your machine against your RPC endpoints, and your signing keys never leave your custody model.
Fast. Event decode → expression eval → relayer send are in-process function calls; no HTTP or serialization on the hot path. WebSocket head tracking gets triggers firing the moment a block lands.