Skip to content

Data Pipelines & ETL

Flow-Like Flows can coordinate data movement across APIs, databases, files, and local storage. A reliable pipeline makes each boundary explicit: where data came from, how it changed, where it was written, and what happens when a step fails.

The Flow-Like data pipeline architecture: sources are extracted, cleaned and enriched, then loaded into useful destinations

StageResponsibility
TriggerDecide when and why the run starts
ExtractRead source records without losing provenance
NormalizeStandardize names, types, dates, and identifiers
TransformFilter, join, aggregate, enrich, and validate
LoadWrite to the destination with idempotent behavior
ObserveRecord counts, duration, failures, and checkpoints

Keep these responsibilities visible even when a small pipeline combines several of them in one Flow.

DataFusion nodes can mount files and register database or lake sources in a query session.

SourceRelevant nodes
SessionCreate DataFusion Session
PostgreSQL, MySQL, SQLite, and other databasesDataFusion databases
CSV, JSON, ParquetMount CSV, Mount JSON, Mount Parquet
Delta and IcebergDataFusion lakes
Local Flow-Like databaseOpen Database

Use source-side filters when possible. For an incremental database read, select records using a stable cursor such as an updated timestamp plus a unique ID, then save the new checkpoint only after the destination write succeeds.

Build a request with the HTTP request nodes and execute it with API Call. Handle pagination according to the provider’s contract:

  • cursor pagination: save and submit the returned cursor;
  • page pagination: increment the page until the response is empty or marks completion;
  • link pagination: follow the provider’s next link;
  • time windows: use non-overlapping boundaries and a stable tie-breaker.

Read credentials from secrets, validate the status before parsing, and respect provider rate limits.

Use format-specific readers rather than treating every file as raw text:

Validate the actual content type where practical. A file extension alone is not a sufficient trust boundary.

Register the required sources in one DataFusion session, then use SQL Query for filtering, joins, aggregation, and window functions.

SELECT
customer_id,
DATE_TRUNC('day', created_at) AS order_day,
SUM(amount) AS revenue
FROM orders
WHERE created_at >= TIMESTAMP '2026-01-01 00:00:00'
GROUP BY customer_id, DATE_TRUNC('day', created_at);

Construct dynamic query text only from validated, allow-listed values; never concatenate arbitrary user input. Keep business definitions such as revenue or active customer in one reusable query or workflow so dashboards and reports do not drift.

Use workflow nodes when the transformation is naturally record-oriented or depends on external services:

NeedPattern
Normalize one recordMap source fields into a stable destination schema
Apply business rulesBranch on validated, named conditions
Call an enrichment APILimit concurrency and cache reusable results
Process a collectionFor Each or Parallel For Each
Combine parallel resultsGather

Prefer set-based SQL for large joins and aggregations. Use per-record workflow loops only when each record requires its own logic or side effect.

Validate before writing:

  • required fields are present;
  • identifiers are unique where expected;
  • numeric and date values parse in the intended locale and timezone;
  • enum values are recognized;
  • foreign keys or reference values exist;
  • row counts and totals are plausible;
  • rejected records retain the source reference and rejection reason.

Separate invalid data from execution errors. An invalid record may be routed to review while the run continues; a broken destination connection may require the run to stop.

The local database catalog supports single and batch writes:

BehaviorNode
Insert one recordInsert
Insert a batchBatch Insert
Upsert one recordUpsert
Upsert a batchBatch Upsert
Insert CSV dataBatch Insert (CSV)

Choose a deterministic key and use upsert when a run may be retried. For external destinations, use their idempotency or merge mechanism when available.

Choose a trigger that matches freshness needs:

TriggerBest for
SchedulePeriodic imports, reports, and maintenance
App or generic eventUser-initiated or system-initiated jobs
Incoming API eventNear-real-time updates from external systems
Upstream completionMulti-stage pipelines with explicit dependencies

See App events for event configuration. Avoid polling much more frequently than the source can change or the destination can safely accept writes.

Store the last successful cursor, time window, or source offset. Update it only after the corresponding destination batch commits.

Make retries safe by using stable source identifiers, destination upserts, provider idempotency keys, or a run ledger.

Batch to bound memory and transaction size. Limit parallel work according to database capacity, file size, and API rate limits.

Record the stage, safe source identifier, error type, attempt count, and run ID. Redact credentials and sensitive payload fields. Retry transient failures with backoff; route permanent data errors to review.

At minimum, record:

  • run start, end, and duration;
  • extracted, accepted, rejected, and written counts;
  • current checkpoint;
  • retry and failure counts;
  • the Flow and configuration version used for the run.
StageOperation
TriggerRun on a schedule or explicit app event
ExtractRequest customer pages from the source API
NormalizeStandardize email, country, and timestamp fields
EnrichResolve optional reference data with bounded concurrency
ValidateRequire a source ID and valid business fields
LoadBatch upsert by source ID
FinishSave the cursor and emit a run summary

If a batch fails after extraction, repeat the same batch with the same source IDs. The upsert key and delayed checkpoint update prevent duplicates or skipped pages.

  • Source, destination, and owner are documented
  • Credentials come from secrets or provider connections
  • Pagination or incremental cursors are explicit
  • Transformations produce a stable schema
  • Invalid records have a review or quarantine path
  • Destination writes are idempotent
  • Batch size and concurrency are bounded
  • Checkpoints advance only after successful writes
  • Run metrics and safe error context are retained