Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Connector catalog

faucet-stream ships 25 sources and 20 sinks. Each is a Cargo feature (source-<name> / sink-<name>) and an independently published crate. Full API docs are on docs.rs.

Run faucet list to see what’s compiled into your binary, and faucet schema source <name> / faucet schema sink <name> for a connector’s exact config fields. Not sure which to pick? See Choosing a connector.

Legend: ✓ supported · ✗ not applicable. Tier: T1 = passes the faucet-conformance battery in CI; T2 = not yet wired into the battery.

Sources

ConnectorTier¹¹FeatureStreams¹Resumable²Effectively-once³CompressionDiscover¹⁰Underlying primitive
RESTT1 ✅ᵐsource-restHTTP + 6 pagination styles, JSONPath extraction
GraphQLT1 ✅ᵐsource-graphqlcursor pagination, variable injection
XML / SOAPT1 ✅ᵐsource-xmlstreaming XML→JSON, dot-path extraction
gRPCT1 ✅source-grpc✓⁴dynamic protobuf; unary + server-streaming
PostgreSQLT1 ✅source-postgresSQL query, rows as JSON
PostgreSQL CDCT1 ✅source-postgres-cdclogical replication (pgoutput), LSN bookmarks
MySQLT1 ✅source-mysqlSQL query, rows as JSON
MySQL CDCT1 ✅source-mysql-cdcbinlog row events, file/pos or GTID bookmarks
Microsoft SQL ServerT1 ✅source-mssql✓⁸SQL query (tiberius), rows as JSON
SQLiteT1 ✅source-sqliteSQL query, rows as JSON
AWS S3T1 ✅source-s3✓⁵object reader: JSONL, JSON array, raw text
Google Cloud StorageT2source-gcs✓⁵object reader: JSONL, JSON array, raw text
MongoDBT1 ✅source-mongodbfind() with filter/projection/sort
MongoDB CDCT1 ✅source-mongodb-cdcChange Streams, resumeToken bookmarks; max_staged_records buffer cap
RedisT1 ✅source-redisstreams, lists, key patterns
WebhookT2source-webhook✗⁶temporary HTTP server collecting POSTs
WebSocketT1 ✅source-websocketlive push feed; subscribe frames, reconnect, ping keepalive
CSVT1 ✅source-csvCSV files as JSON; strict field count by default (flexible: true to tolerate ragged rows)
ElasticsearchT1 ✅ᵐsource-elasticsearchsearch/scroll API
Apache KafkaT1 ✅source-kafkaconsumer; idle/max-messages termination, offset bookmarks
AWS KinesisT1 ✅source-kinesisper-shard GetRecords workers; sequence-number bookmarks, idle/max-messages termination
Apache ParquetT1 ✅source-parquetlocal/glob/S3, vectorized Arrow reader, projection
Apache Delta LakeT2source-deltalocal FS or S3/Azure/GCS; time travel (version/timestamp), projection pushdown, partition reconstruction
Databricks SQLT3source-databricksStatement Execution API; async poll, chunk pagination, typed decode, incremental ${bookmark}
BigQueryT1 ✅ᵐsource-bigqueryjobs.query + pageToken pagination
SnowflakeT1 ✅ᵐsource-snowflakeSQL REST API, server-side partitions
Cloud SpannerT1 ✅ᵉsource-spanner✓⁸streaming SQL (gRPC), incremental @bookmark replication, stale reads, PK-range sharding
Singer bridge ⚠️T2 ⚠️source-singer✓⁹runs an external Singer tap; NDJSON over stdout, STATE→bookmark. Tier-2 / experimental

¹⁰ Discover = enumerates the datasets behind the connection for faucet discover (tables / collections / indices / prefixes with schemas + row estimates where the catalog provides them). ¹ Streams = yields records in bounded-memory batches rather than buffering the whole result. ² Resumable = persists a bookmark to a state store so re-runs continue where they left off (incremental replication / CDC / Kafka offsets). ³ Effectively-once = the source emits a complete resume position on every page and replaying from a bookmark continues the record stream at exactly that position (immutable-log sources: CDC WAL/binlog/change streams, Kafka partition offsets); required for the atomic-watermark mechanism behind delivery: exactly_once — see Effectively-once delivery. ⁴ gRPC streams natively in server-streaming mode; unary buffers the single response. ⁵ S3/GCS stream in JSONL and raw-text modes; JSON-array mode buffers one object. ⁶ Webhook is buffer-shaped by nature (it collects POSTs over a window). ⁸ MSSQL is resumable only in replication: incremental mode (it persists a tracking-column bookmark); in full mode it is not. ⁹ The Singer bridge is resumable via the tap’s STATE messages, but the granularity of resume (and whether re-emitted rows overlap) depends on the individual tap — pair it with a keyed/upsert sink for clean, effectively-once (idempotent at-least-once) behavior.

Support tiers (the Tier column above). A connector is Tier-1 ✅ when it invokes and passes the faucet-conformance battery in CI against the connector’s real backend — config-schema validity, bounded-memory streaming, and (where applicable) bookmark round-trip, idempotent replay, truthful capabilities, and errors-not-panics (see the Faucet Connector Protocol spec, docs/spec/faucet-connector-spec-v0.md). Each Tier-1 connector wires the battery from its own tests/conformance.rs; that battery is the tiering mechanism — there is no separate scheme.

marks a connector whose battery runs in CI against a wiremock HTTP mock, not a live service instance — the rest, graphql, xml, elasticsearch, bigquery, and snowflake sources and the http sink. The mock faithfully drives the paging, schema, and error-handling behavior the checks assert, but it is not an end-to-end test against the real system (no credentialed cloud/service backend runs in CI). marks the Cloud Spanner pair, whose battery runs against Google’s official Spanner emulator (Docker) — a real gRPC Spanner implementation, closer to end-to-end than a wiremock but still not the managed service.

The connectors still marked Tier-2 are the ones whose full battery cannot run in CI (so they are not conformance-certified — Tier-2 means “not certified,” not “low quality”; they keep their own extensive wiremock/testcontainers tests): the BigQuery and Snowflake sinks and the Elasticsearch sink are cloud-only and tested against wiremock, which cannot validate real idempotent dedup; the GCS source’s bounded-memory check needs a real gRPC backend (the emulator is REST-only); the GCS sink cannot be durably counted against the emulator; the webhook source is buffer-shaped (no bounded-memory page check); and the Iceberg sink is append-only with a terminal flush that does not fit the effectively-once replay check on iceberg-rust 0.9.1. The Singer bridge ⚠️ passes the battery but is additionally experimental (v0, single-stream).

Sinks

Every sink exposes a batch_size knob for write-side re-chunking. For the file/append sinks (jsonl, csv, stdout) it’s a no-op — they write per record.

ConnectorTier¹¹Featurebatch_sizeCompressionUpsert⁸Effectively-once⁷Write unit
BigQueryT2sink-bigquerytabledata.insertAll streaming; in-place MERGE for upsert + effectively-once
PostgreSQLT1 ✅sink-postgresmulti-row INSERT (JSONB or mapped cols); COPY FROM STDIN fast-path for append (write_method: copy)
JSON LinesT1 ✅sink-jsonlno-opbuffered file append
SnowflakeT2sink-snowflakeSQL REST API; multi-statement BEGIN;INSERT;MERGE;COMMIT transaction for effectively-once
MySQLT1 ✅sink-mysqlmulti-row INSERT
Microsoft SQL ServerT1 ✅sink-mssqlmulti-row INSERT (2100-param auto-split, per-row DLQ)
SQLiteT1 ✅sink-sqlitetransaction-wrapped batch
AWS S3T1 ✅sink-s3JSONL objects, parallel uploads
Google Cloud StorageT2sink-gcsJSONL objects
MongoDBT1 ✅sink-mongodbinsert_many; multi-document transaction for effectively-once (replica set required)
RedisT1 ✅sink-redisstreams, lists, key-value (pipelined); MULTI/EXEC transaction for effectively-once
CSVT1 ✅sink-csvno-opbuffered file rows; column set frozen from first batch (on_unknown_field: warn/error)
ElasticsearchT2sink-elasticsearch_bulk NDJSON (per-row DLQ)
HTTPT1 ✅ᵐsink-httpPOST, concurrent under a semaphore
StdoutT1 ✅sink-stdoutno-opJSON Lines / pretty JSON / TSV
Apache KafkaT1 ✅sink-kafkaproducer, batched sends, multi-topic routing; transactional producer + compacted watermark side-topic for effectively-once
AWS KinesisT1 ✅sink-kinesisbatched PutRecords; partition-key routing, per-entry partial-failure retry (DLQ-routable)
Cloud SpannerT1 ✅ᵉsink-spannerbatched mutations (insert / insert_or_update / delete), cell-budget chunking, commit-token transaction for effectively-once
Apache ParquetT1 ✅sink-parquet✗⁶local/S3, schema inference (re-inferred per file on rollover), row/byte rollover
Apache Delta LakeT2sink-delta✗⁶append-only; local FS or S3/Azure/GCS; schema-inferred table creation, partitioning, one commit per flush
Apache IcebergT2sink-iceberg✗⁶REST/Glue/SQL/HMS catalog, local + cloud (S3/GCS) warehouses, fast_append snapshot, Parquet data files

⁶ Parquet and Iceberg both handle compression internally at the Parquet column level, so the file-level compression feature doesn’t apply to either. ⁷ Effectively-once = commits data and a watermark token atomically; required for delivery: exactly_once. The BigQuery sink does this via a multi-statement MERGE transaction (distinct from its default streaming insertAll path); the Kafka sink uses a transactional producer that writes each page’s records plus a commit-token record into a compacted side-topic in one Kafka transaction; the Snowflake sink runs one multi-statement BEGIN;INSERT;MERGE;COMMIT request; the Redis sink wraps the page plus a _faucet_commit_token:<scope> key in one MULTI/EXEC; the MongoDB sink commits the page plus a watermark document in one multi-document transaction (replica set required); the Cloud Spanner sink buffers the page’s mutations plus a faucet_commit_token row in one read-write transaction. Sinks configured with write_mode: upsert + key also reach effectively-once via keyed dedup, with any source. See Effectively-once delivery. ⁸ Upsert = supports write_mode: upsert / delete (insert-or-update and delete by key) in addition to plain append. The SQL sinks require column-mapping mode (auto_map, or auto_columns for mssql) and a UNIQUE/PRIMARY KEY on key; the schemaless sinks (MongoDB, Elasticsearch) map key to a match filter / _id. Iceberg upsert is not yet supported (a follow-up, blocked on iceberg-rust). See Upsert / mirror tables.

Data-integrity notes

A few connectors enforce defaults that prevent silent data loss or corruption. Inspect the exact fields with faucet schema source <name> / faucet schema sink <name>.

  • CSV source — strict by default. A row whose field count differs from the header raises an error naming the offending line. Set flexible: true to tolerate ragged rows (the pre-1.x behaviour). (Breaking default change.)
  • CSV sink — the column set is frozen from the first batch (the header cannot be rewritten in place). A field that first appears in a later page is dropped; on_unknown_field: warn (default) emits a one-shot warning naming the dropped field(s), while on_unknown_field: error aborts with a typed error.
  • Parquet sink — the Arrow schema is re-inferred per output file on rollover, so a file written after the source widens picks up the new schema. A Parquet file’s schema is immutable once opened, so a field appearing only later within a single file is dropped with a per-file one-shot warning.
  • MongoDB CDC sourcemax_staged_records (default unbounded) caps the in-memory change-event buffer (including under batch_size: 0) and aborts with a typed error rather than risking OOM, mirroring postgres-cdc / mysql-cdc.

Schema evolution

The pipeline-level schema: block detects when an incoming page’s top-level shape diverges from the sink’s destination schema and applies one policy (warn / ignore / fail / quarantine / evolve). Which sinks can actually act on it varies:

SinkSchema evolution
postgres, mysql, mssql, sqlite, bigquery✓ evolve — in-place additive/widening DDL
elasticsearch✓ evolve — can add fields only (existing-field type change is incompatible)
spanner✓ evolve — additive columns + NOT NULL relax; base-type widening is not supported by Spanner (use allow_type_widening: false)
icebergdetect-only — warn/ignore/fail/quarantine work; evolve blocked on upstream iceberg-rust (#255)
jsonl, csv, stdout, mongodb, redis, http, kafka, s3, gcs, snowflake, parquet— (schemaless; the schema: policy is inert)

on_drift: evolve against a detect-only or schemaless sink is rejected at config-load. See Schema drift for the per-sink nuances (e.g. SQLite widening is a no-op; Elasticsearch can only add fields).

Authentication at a glance

FamilyAuth options
REST / GraphQL / XMLBearer, Basic, ApiKey (header), ApiKeyQuery, OAuth2 (client-credentials), TokenEndpoint, Custom headers — see Auth cookbook
BigQueryservice-account key (path or inline JSON), application-default credentials
SnowflakeJWT key-pair, OAuth
Cloud Spannerservice-account key (path or inline JSON), application-default credentials
KafkaSASL (PLAIN/SCRAM) + TLS
WebSocketnone, Bearer token, Custom headers
Elasticsearchbasic, API key, bearer, none
S3 / GCScloud SDK credential chains (env, profile, metadata)
SQL databasesconnection URL (with embedded credentials / TLS params)

Inspect any connector’s exact auth shape with faucet schema source <name> / faucet schema sink <name>.

Batching

Default batch_size is 1000; max is 1,000,000. batch_size: 0 means “no batching” — the source emits the whole result set in one page and the sink writes it in one request (good for small lookup tables or load-job-style sinks). See Performance tuning.


¹¹ Tier = conformance status. T1 ✅ means the connector adds a tests/conformance.rs that invokes the reusable faucet-conformance battery against the real connector and passes it in CI (valid config schema, bounded-memory streaming, honest capabilities, and the further checks as they land) — that battery is the single source of truth for the tier. T2 means the connector is not yet wired into the battery; most still have their own integration tests, so T2 does not mean low quality. See the Faucet Connector Protocol (FCP v0) for the full contract.