Decide how a block stream becomes data your application can query. A sink writes Substreams output to your database, files, or queue and tracks its cursor so it can recover after a disconnect. You choose between a standard sink and your own consumer.
Consumption modes
Run a consumer or sink in your own infrastructure, or contact GraphOps about enterprise sink hosting.
| Mode | GraphOps support | Use it for |
|---|---|---|
| Direct gRPC stream | Self-service | Application consumers and custom materializers. |
| Customer-run sink | Self-service | Writing to SQL, files, queues, or custom stores. |
| Hosted sink | Enterprise | GraphOps-managed sink hosting. Contact support in the platform UI. |
Choose a sink
Each destination has a standard Substreams tool. The CLI sinks take your GraphOps endpoint with
-e and read your API key from SUBSTREAMS_API_KEY.
| Destination | Tool | Guide |
|---|---|---|
| Your application | Substreams libraries for JavaScript, Go, Rust, or Python | Substreams:Stream |
| Postgres or ClickHouse | substreams sink postgres or substreams sink clickhouse, built into the CLI | Run a sink, Substreams:SQL |
| Files | substreams sink protojson for JSONL; substreams-sink-files for CSV or Parquet | ProtoJSON, Files |
| Google Cloud Pub/Sub | substreams sink pubsub | Substreams:PubSub |
The SQL sink needs an output module that emits DatabaseChanges, usually db_out, or Protobuf
output annotated for relational mappings.
Sink responsibilities
A standard sink takes care of most of these. If you write your own consumer, it must do all of them.
A production sink should:
- Decode the output module type.
- Apply block-scoped data to durable state.
- Persist cursors after durable commits.
- Handle undo signals and rollback local state.
- Expose metrics for processed blocks, bytes out, bytes read, bytes written, lag, retries, and failures.
- Bound worker concurrency according to the organization's plan.