Apache NiFi is an open-source data integration tool designed to automate the flow of data between systems. It provides a user-friendly web-based interface that allows users to design, monitor, and control data flows through a visual programming approach. NiFi is particularly useful for organizations that need to move large volumes of data from diverse sources to various destinations in a scalable, reliable, and efficient manner.
A NiFi flow is a directed graph of processors joined by connections. Data moves through the graph as FlowFiles: each FlowFile has a map of attributes (filename, path, MIME type, custom values) and a pointer to its content. Processors are reusable components, several hundred of them in the standard distribution, that get, transform, route and put data: ListSFTP and FetchSFTP pick up files, ConvertRecord changes formats using record readers and writers with a schema, RouteOnAttribute branches on expressions, and PutS3Object or PublishKafka deliver results. Connections are queues; when a queue reaches its back pressure threshold, the upstream processor stops being scheduled, which protects downstream systems from overload.
NiFi is widely adopted in industries like finance, healthcare, telecommunications, and government for its ability to manage data pipelines efficiently and securely.
Each NiFi node is a JVM process. The flow controller hands out threads to processors according to their scheduling settings. Three repositories on local disk make the system durable: the FlowFile repository is a write-ahead log of FlowFile state, so queued data survives a restart; the content repository stores the bytes, and FlowFiles that are only routed or have attributes changed never copy content; and the provenance repository records every event (create, receive, modify, route, send, drop) for lineage and replay. NiFi Registry stores versioned flow definitions so flows can be promoted from development to production like code.
Processor properties accept NiFi Expression Language, which reads FlowFile attributes. A typical routing and naming setup looks like this (property name, then value):
# RouteOnAttribute (Routing Strategy: Route to Property name)
csv_files ${filename:toLower():endsWith('.csv')}
large_files ${fileSize:gt(104857600)}
# UpdateAttribute: build a partitioned object key
s3.key raw/${source}/${now():format('yyyy/MM/dd')}/${filename}
# PutS3Object
Bucket my-landing-bucket
Object Key ${s3.key}
Flows can also be managed through the REST API, for example to start a process group from a deployment script:
curl -X PUT https://nifi.example.com:8443/nifi-api/flow/process-groups/$PG_ID \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"id": "'$PG_ID'", "state": "RUNNING"}'
| Tool | Model | Best for |
|---|---|---|
| Apache NiFi | Visual, continuous data flow with per-record lineage | Moving and routing data between many systems, edge and file ingestion, regulated environments needing provenance |
| Apache Airflow | Scheduled DAGs of tasks, code-first | Orchestrating batch jobs (Spark, SQL, dbt); Airflow does not move the data itself |
| Kafka Connect | Source and sink connectors around Kafka | High-throughput streaming into and out of Kafka |
| Spark / Flink | Distributed compute | Heavy transformations, joins and aggregations |
A common pattern combines them: NiFi ingests and lands raw data, Kafka distributes events, and Spark or SQL engines transform it under Airflow orchestration.