Skip to main content
dbt Connector + Datashare is available only to existing customers of this offering and is no longer available to new customers. Learn more about Enterprise Datashare.
Use dbt to publish transformation outputs from your private Dune namespace to your team’s Datashare destination: Snowflake, Databricks, or S3. This is useful when you want to keep the transformation logic on Dune, but consume the resulting tables inside your own warehouse.
dbt Connector + Datashare is an enterprise workflow that requires both Data Transformations and Datashare to be enabled for your team.
Datashare syncs are billed based on bytes transferred and byte-months of storage for the synced table. Automated dbt runs also consume query credits.

How It Works

Datashare syncs use the table’s change data feed (CDF):
  1. dbt builds a table or incremental model with change data feed enabled in your Dune namespace.
  2. A dbt post-hook runs ALTER TABLE ... EXECUTE sync_datashare(...) on that table.
  3. Dune registers the sync and copies the table to your team’s destination. Dune resolves the destination from your team’s configuration.
  4. Dune then applies the table’s changes every five minutes by default.
  5. You monitor the sync in dune.datashare.table_syncs and dune.datashare.table_sync_runs.

Prerequisites

  • Enterprise account with Data Transformations enabled
  • Datashare destination configured for your team by Dune
  • Dune API key with write access
  • A dbt project using the Dune Trino connector
The fastest way to get started is the public template repo:

dune-dbt-template

Includes the datashare macro, a prod-only post-hook, and an opt-in example model.

Add The dbt Post-Hook

Add the datashare post-hook to your dbt_project.yml:
The hook must be restricted to your production target. Without a target guard, a local dbt run or a CI job writes to a temporary schema (<team>__tmp_<suffix>) and registers that schema as a real datashare, shipping it to your destination warehouse. Because dev schemas are ephemeral, the resulting destination table and view can outlive the source table that created them.If you are adding datashare to an existing dbt project rather than starting from the template, make sure your datashare_trigger_sync() macro opens with this check:
When the guard is working you will see one Skipping datashare sync for ...: datashare post-hook only runs on the prod target line per datashare-enabled model on every non-prod run.

Check Table Size Before Syncing

Datashare syncs are billed by reported bytes written during the sync and by byte-months of storage at your target warehouse, so it is worth checking how large a source table is before you enable a sync. You can read the Dune source table’s on-disk size from the $size metadata table, but you first need to know the physical table name that Dune is scanning, which may differ from the logical name you query. You can give a list of tables to the Dune MCP and it can calculate their sizes. Alternatively, you can use the following two-step workflow from any Trino-compatible client (the Dune SQL Editor, a notebook, or dbt run-operation).
These queries are read-only and do not require the transformations=true session property. The $size suffix must be attached to the table name and wrapped in double quotes (for example, schema."table$size").

Step 1: Find The Physical Table Name With EXPLAIN

Run EXPLAIN against the table you want to size up:
In the query plan, look for the TableScan or ScanProject node. The table = ... value is the physical table name you need for step 2. The catalog prefix before the colon (for example dune: or delta_prod:) is part of the connector and should be dropped — only the schema.table portion is used in the size query.

Step 2: Query The $size Metadata Table

Plug the physical schema.table name from step 1 into the size query, wrapping table$size in double quotes:
This returns the Dune source table’s at-rest size using SI units (1 GB = 1,000,000,000 bytes). Treat it as a planning estimate only: it is not the destination warehouse table size, and it is not the exact billing meter. Destination storage can differ because each warehouse uses different formats, compression, layout, and metadata. Datashare sync billing is based on bytes written during synchronization, as reported by Dune’s sync system. This can differ from both the Dune source table at-rest size and the destination warehouse at-rest size.

Example 1: A dbt-Created Table

For the dbt model dune.dune.lineage_query_2:
The TableScan line in the plan reads:
Here the physical name matches the logical name, so the size query is:

Example 2: A Dune-Managed Table With A Suffix

For a Dune-managed table such as base.transactions:
The plan shows a ScanProject node referencing a different physical name:
Notice the _0002 suffix on the physical table — that is the name you must use in the size query (drop the delta_prod: catalog prefix):
After confirming the source-size estimate is acceptable, run a one-off sync with dry_run: true (see Manual Syncs) to preview the generated SQL before enabling the post-hook in production.

Configure A Model

Enable datashare in meta.datashare_sync on a table or incremental model, and enable change data feed on the table:
The post-hook generates this statement:
Each sync applies all table changes since the last completed sync. Date filters in the model bound only what dbt reads from its sources.

Configuration

The template macro fails compilation if an enabled model has no unique_key, does not enable change data feed, or sets an unknown key under meta.datashare_sync.
Adding change_data_feed_enabled to an existing model does not change its existing table. Rebuild the table once with --full-refresh.
The source table must keep its change history for at least seven days. Dune rejects the sync if delta.logRetentionDuration or delta.deletedFileRetentionDuration is set below seven days. The defaults meet this requirement. Changing the partitioning of an existing share requires a full refresh. Datashare does not support UINT256 and INT256 columns. Cast them to a supported type in your model, for example cast(amount_raw as decimal(38, 0)) for exact values or cast(amount_raw as double) for calculations.

Sync Schedule

Registering a table creates a Dune sync schedule that applies changes every five minutes by default. This schedule is separate from your dbt schedule: your dbt runs control when the source table changes, and frequent syncs do not resend the full table. Setting enabled to false or pausing your dbt workflow does not stop a registered sync. To stop it, remove the table from Datashare.

Full Refresh Behavior

A full refresh copies the current table again instead of applying changes since the last sync. Dune handles the first copy and any needed recovery automatically, so use full_refresh => true only as a manual override. The post-hook sets full_refresh as follows:
  • table models: always true, because each build recreates the table with a new change history.
  • incremental models: true only when dbt runs a full refresh, for example with --full-refresh.
  • Manual syncs: false unless you pass full_refresh: true.

Manual Syncs

You can trigger a sync manually with dbt run-operation:
This is useful for previewing the generated SQL or running one-off syncs outside a normal dbt run.
Always pass --target prod. This is a separate entry point from the post-hook and does not inherit its guard. It reads the source schema from the dbt manifest, so on the default dev target it registers your temporary schema as a real datashare. dry_run: true is safe on any target, since it only prints SQL.

Monitor Syncs

Use table_syncs for the current registration state and table_sync_runs for execution history.

Remove A Table From Datashare

This stops the sync and revokes access at the destination. It does not drop the Dune table. Also set meta.datashare_sync.enabled to false, or the next prod run registers the table again.

Migrate From meta.datashare

The earlier meta.datashare configuration, with target_type, target_region, and a time window, is no longer supported. Models that still use it fail compilation in the current template. To migrate a model:
  1. Replace meta.datashare with meta.datashare_sync, enable change data feed, and set a unique_key as shown in Configure A Model.
  2. Run the model on the prod target. The old and new shares can both be active.
  3. After the first successful sync, remove the old share:

Reference