Deployment shapes
Six concrete shapes tflo is intended to cover. Each entry names the shape, points at the example or crate that demonstrates it, and lists the caveats that matter in production.
1. Embedded in a Rust service (single-process)
The original use case. tflo-core runs inline in the user's service;
records flow through Iterator::tflo(...) or
Stream::tflo(...); no external runtime is involved. Keyed execution still
works single-process via LocalShard — the default
ShardRouter impl in tflo_core::shard.
Try it: Every example under tflo-examples/examples/ except
iot-portal runs in this mode.
Caveats: None specific to this shape.
2. Edge gateway (Linux / ARM, tokio + std)
A single-process Rust binary on a sensor gateway. Consume sensor input (MQTT,
OPC-UA, Modbus, vendor protocol), condition it (SMA, hysteresis, debounce), and
republish lifecycle events upstream (Kafka, NATS, or a TSDB sink). Engine:
tflo-core. Source: tflo-connect-mqtt with the pure-Rust
rumqttc-backend feature — cross-compiles cleanly to
armv7-unknown-linux-gnueabihf. State:
tflo-state-files with the async feature for crash-safe
restart. Sink: typically MQTT producer or tflo-sink-influx.
Try it: The edge gateway leg of tflo-examples/examples/iot-portal/.
Caveats: MQTT QoS-2 dedup needs a bounded window; MqttCursor enforces this
so the in-flight set cannot grow unbounded.
3. Central worker cluster (Kafka-sharded)
Multiple worker processes each owning a slice of the keyspace, driven by Kafka
consumer-group rebalancing. State per partition is durable in an
AsyncStateStore (S3, Postgres, file, …) so a worker that loses a
partition during rebalance can have it restored elsewhere. Engine:
tflo-core async. Source: tflo-connect-kafka with
rdkafka-backend for production. Shard router:
KafkaShardRouter — the AsyncStateStore argument is
required at construction (a compile-time poka-yoke
against running sharded execution with no durable state). State:
tflo-state-files for dev, tflo-state-s3 for production.
Sink: tflo-sink-influx, tflo-arrow for Parquet archive, or
back-to-Kafka. Orchestration: Checkpointer — writes snapshot first,
cursor last (crash-safe order), per-stage deadline, consecutive-failure circuit
breaker.
Try it: The central worker leg of tflo-examples/examples/iot-portal/.
Caveats: At-least-once delivery; sinks should be idempotent (use
Deduplicator). The router's AssignmentEpoch must be re-read
on every event intake for the rebalance-race fence to work.
4. WASM (browser / edge runtime)
tflo-core and tflo-ops build clean for
wasm32-unknown-unknown; tflo-wasm exposes the streaming
detectors to JS. For larger graphs in this shape, mind the wasm32 4 GiB per-instance
memory cap — per-key state grows with key cardinality. Set
KeyedConfig::max_active_keys (LRU eviction to a snapshot store) when key
count is unbounded.
Try it: tflo-wasm builds with wasm-pack build --target web.
Caveats: Memory cap is real; bound active-key cardinality explicitly for large graphs.
5. no_std microcontroller
Not supported today. tflo-core depends on std
collections in keyed execution; lifting that requires a parallel
no_std-compatible storage layer. Aspirational — the
non-goals page
explains why it's not a current commitment.
Caveats: Aspirational; tracked on the roadmap.
6. Batch / replay over historical data
Run the same temporal-graph code over a bounded historical dataset. The Iterator
path supports this natively — feed any
impl Iterator<Item = Record> into .tflo(...). Format:
Parquet via tflo-arrow (parquet feature). Schema safety:
stamp schema_fingerprint(&schema) into
SnapshotMetadata.topology_fingerprint; the fingerprint poka-yoke refuses a
backfill against a structurally-different schema.
Try it: tflo-arrow parquet_io::{write_batches, read_batches};
the iot-portal example builds a RecordBatch to show the
schema-fingerprint flow.
Caveats: Same detectors, same closures, deterministic output — that is the point.
Picking a shape
| Question | Shape |
|---|---|
| Single Rust process, no external deps? | 1. Embedded |
| Linux / ARM gateway with sensor protocols? | 2. Edge gateway |
| Horizontal scale + restartable durable state? | 3. Cluster |
| Browser / WASM-host runtime? | 4. WASM |
| Bare-metal MCU? | 5. no_std (aspirational) |
| Backfill or simulation over recorded data? | 6. Batch / replay |
Shapes 1, 2, and 6 are production-ready today. Shape 3 ships the contracts +
KafkaShardRouter; the real rdkafka backend is feature-gated
and exercises a redpanda-in-docker integration when opted in. Shape 4 builds —
the memory caveat is real. Shape 5 is roadmap.
Canonical source: docs/deployment-shapes.md.
Related: Contracts · Reference deployment · Non-goals