In most cases (around 95%) a Mirror pipeline can be mapped 1:1 onto a Turbo pipeline. The remaining cases involve features that Turbo does not currently support — see When you can’t migrate yet before you start.
Before you start
- Install the latest CLI. The Turbo commands live under
goldsky turbo— see the Turbo CLI reference and the installation guide. - Read Mirror vs. Turbo pipelines so you know which sources, transforms, and sinks change shape.
- Export your existing Mirror pipeline definition with
goldsky pipeline get <name>so you have the YAML to translate.
When you can’t migrate yet
Turbo doesn’t (yet) replace every Mirror feature. Stay on Mirror if your pipeline depends on:- Subgraph entity sources — Turbo only supports dataset sources.
- Elasticsearch, Timescale, DynamoDB, or Snowflake sinks — see Mirror vs. Turbo § Sinks for the supported sink list on each product.
- Webhook sinks authenticated with
secret_name— Turbo webhook sinks currently take inlineheadersonly. See Mirror vs. Turbo § Webhook and handler options. - Mirror-only handler options like
schema_override,payload_columns,batch_size, andbatch_flush_interval— see Mirror vs. Turbo § Transforms.
Step 1: Translate the YAML
Turbo’s YAML is similar to Mirror’s but drops a few fields and renames others.Top-level changes
| Mirror | Turbo |
|---|---|
apiVersion: 3 (required) | Remove — Turbo doesn’t use apiVersion |
resources: { size: s | m | l | xl | xxl } | resource_size: xs | s | m | l | xl | xxl (top-level field, adds xs) |
name, description | Same |
Sources
Both products usetype: dataset, but Turbo adds start_block / end_block for block ranges and uses start_at: latest | earliest for the starting position. Source-level Fast Scan filters on Mirror don’t carry over — in Turbo, filter inside a SQL transform instead. See:
Transforms
- SQL transforms — Turbo uses Apache DataFusion instead of Flink. Most Mirror SQL works as-is; we’ve backported the common Flink functions as UDFs. A handful of less-used functions need rewrites — check Turbo SQL functions reference for the supported list.
- External HTTP handlers — see HTTP handler transforms. Note that Mirror’s
schema_override,payload_columns,batch_size,batch_flush_interval, andsecret_nameare not available;one_row_per_requestandpayload_versionare. - New transforms you can adopt — TypeScript/WASM transforms, dynamic tables, and throttle.
Sinks
Most sink types have direct equivalents. Watch out for these specific renames and reshapes:- PostgreSQL secrets — Mirror uses a JSON-object secret (
type,host,port, …). Turbo uses a Postgres connection string (postgres://user:pass@host:port/db). Recreate the secret withgoldsky secret create. See Turbo Postgres sink and Mirror secrets. - SQS — Mirror uses
type: sqs; Turbo usestype: sqs_sinkand lets you passaccess_key_id/secret_access_keyinline. See Turbo SQS sink. - S3 — In Mirror this goes through the object storage sink; Turbo has a native
s3_sink. - Kafka — Turbo’s Kafka sink adds
data_format,topic_partitions,schema_registry_url, andmessage_max_bytes. - Webhooks — Turbo’s webhook sink supports
one_row_per_request,payload_version, and aprimary_key, but does not supportsecret_nameyet.
Step 2: Validate the Turbo definition
Once you have a translated YAML file:Step 3: Choose a cutover strategy
Mirror’s processed-data state does not carry over to Turbo, so plan for one of the two strategies below depending on how much double-write or downtime you can tolerate.Option A — Run both in parallel (recommended)
Best when your sink can tolerate duplicate writes (e.g. Postgres with primary keys, ClickHouse withReplacingMergeTree, or any idempotent webhook).
- Deploy the Turbo pipeline with
start_at: latestin every dataset source so it begins at the chain tip. - Leave the Mirror pipeline running.
- Once the Turbo pipeline is healthy and you see writes landing in your sink, pause the Mirror pipeline with
goldsky pipeline pause <name>. - After a buffer period to confirm Turbo is stable, delete the Mirror pipeline.
Option B — Block-number cutover
Best when your sink cannot dedupe and you want a clean handoff.- Pick a future block X for the cutover.
- Edit the Mirror pipeline so it stops at block X (filter in your SQL transform or set an
end_blockon the source). - Deploy the Turbo pipeline configured to start at block X+1 (use
start_blockon the source — see EVM sources). - Once Mirror reaches block X and Turbo picks up at X+1, pause and remove the Mirror pipeline.
Option C — Cold cutover (downtime accepted)
If a short gap in your sink is fine, pause Mirror, deploy Turbo withstart_at: latest, and accept the brief gap. Simplest, but you lose the blocks in between.
Step 4: Decommission Mirror
After the Turbo pipeline has been running cleanly for your chosen verification window:goldsky secret delete.
Common gotchas
- Solana, Bitcoin, Stellar, and NEAR sources were removed from Mirror — they’re Turbo-only now. See Solana, Bitcoin, Stellar, and NEAR.
- CLI namespace — every command moves from
goldsky pipeline ...togoldsky turbo .... Update scripts and CI accordingly. - Resource sizes — Turbo adds an
xstier. If your Mirror pipeline was onspurely to control cost,xsmay be enough. - Job mode — if your migration is actually a one-time backfill, consider Turbo job mode instead of a streaming pipeline.