Hasura v3 (DDN) – Getting Started, and Upgrading from v2

August 14, 20269 min readUpdated 8/21/2026

Hasura v3 is called DDN — Data Delivery Network — and the most useful thing to understand before touching it is that it is not v2 with new commands. It is a different product that happens to share a name and a query language. This lesson covers what it is, how to get one running, and exactly what changes coming from v2.

How this lesson was written. Everything below is taken from the official Hasura DDN documentation as read on 2026-08-21 — the feature availability matrix, the glossary and the quickstart. Unlike the v2 lessons in this track, it was not run locally, so it shows configuration and commands but never claims output.

The v3 mental model

Three words carry most of it.

A connector is what talks to a data source. In v2 the engine had built-in support for a fixed list of databases; in v3 every source — Postgres, a REST service, another GraphQL API, your own TypeScript functions — is reached through a native data connector implementing a common specification. Adding a new kind of source means writing or installing a connector rather than waiting for a Hasura release.

A subgraph is a self-contained slice of the API: its metadata, its connectors, its permissions, its own repository and release cycle. It is the unit of team ownership.

A supergraph is the composition of those subgraphs into one API. This is the architectural point of v3 — several teams shipping independently into a single graph, without the central bottleneck a single v2 engine becomes.

The other shift is builds. A v2 change is applied to a running engine and takes effect. A v3 change is compiled into an immutable build with its own unique endpoint, which you can test before promoting. Metadata stops being a live thing you mutate and becomes source you compile.

Getting a v3 project running

Install the CLI. Docker Compose v2.20 or later is required.

curl -L https://graphql-engine-cdn.hasura.io/ddn/cli/v4/get.sh | bash
ddn doctor

Scaffold a supergraph, attach a connector, and let it introspect the database:

ddn supergraph init mysupergraph
ddn connector init my_connector -i
ddn connector introspect my_connector

Introspection writes what it found into the connector’s configuration; nothing is exposed in the API yet. In v2 you would now “track” tables in the console. In v3 you add models, and the equivalent of tracking everything is a wildcard:

ddn model add my_connector '*'
ddn command add my_connector '*'
ddn relationship add my_connector '*'

Then build and run it locally:

ddn supergraph build local
ddn run docker-start
ddn console --local

What you get is a project directory, not a running engine holding state:

supergraph.yaml
globals/                       # AuthConfig, CompatibilityConfig, GraphqlConfig
app/
  metadata/*.hml               # your models, types, relationships, permissions
  connector/my_connector/configuration.json
engine/build/                  # immutable build output

Those .hml files are the product. HML is Hasura Metadata Language, an extension of YAML, and it is what you edit and commit. A model looks like this:

kind: Model
version: v1
definition:
  name: Properties
  objectType: Properties
  source:
    dataConnectorName: my_connector
    collection: properties
  graphql:
    selectUniques: []
    selectMany:
      queryRootField: properties

The console still exists but its job has changed: in v3 it is for testing queries, reading traces and analytics, and managing collaboration — not for authoring. Authoring is the CLI, the files, and a VS Code extension that validates them as you type.

v2 to v3, item by item

This is the table to keep open while you are working. Every row is from Hasura’s own documentation on 2026-08-21. Rows marked with a stripe are ones where v3 currently does less than v2.

Legend. (C) connector-dependent · WIP work in progress · * supported but implemented differently · EE Enterprise or Cloud only.

ItemHasura v2Hasura v3 (DDN)What actually changes
Workflow
Where you configure itThe web Console — click to track a table, click to add a permission.hml files in your editor, driven by the ddn CLI and a VS Code extensionCode-first. The DDN console is for testing, traces and analytics, not authoring.
Metadata formatA JSON/YAML tree, applied to a running engine over the metadata APIHML — 'an extension of YAML' — compiled into a buildMetadata stops being a live API you mutate and becomes source you compile.
Applying a changeApply metadata; the running engine picks it up immediatelyddn supergraph build create produces an immutable buildEvery build is immutable and gets its own unique GraphQL endpoint, so you can test one before it is anyone's production.
CLIhasuraddnDifferent binary, different install, no shared commands.
Running it locallydocker run hasura/graphql-engine, then open the consoleddn supergraph init then ddn run docker-startThe CLI scaffolds a project directory; Docker Compose v2.20+ is required.
Open sourceCommunity Edition is Apache-2.0 and the whole engine self-hostsEngine and connectors are open source and self-hostable⚠️ The control plane is closed-source and commercial. The v3 split has no v2 counterpart.
Data sources
Connecting a databaseBuilt-in support for a fixed set of sources, configured with a connection URLA Native Data Connector (NDC) per source, from the Connector Hubddn connector init scaffolds it. Adding a new kind of source is writing a connector, not waiting for a Hasura release.
Exposing a tableTrack the tableAdd a Model (ddn model add)The word changes and so does the mechanism: a Model is a metadata object you keep in git, not a row in the engine's state.
Several sources at onceSeveral sources on one engineSubgraphs composed into a supergraphA subgraph is a self-contained domain with its own permissions, SDLC and repository — the unit of team ownership.
Query push-downHasura compiles to SQL for sources it supports nativelyThe connector declares its capabilities and Hasura pushes down what it canIncluding authorization push-down, which v2 could not do.
The GraphQL API
QueriesThe generated schema is deliberately v2-compatible.
Mutations✅ generated insert/update/delete✅ (C)Connector-dependent — a connector must implement them.
Native mutationsNew in v3 — v2 had native queries but no native mutations.
Subscriptions✅ live queries and streaming✅, streaming WIPPlain subscriptions work; streaming subscriptions are not finished.
Filteringwhere on an auto-generated bool_expAn explicit BooleanExpressionTypeYou declare which fields are filterable instead of getting all of them.
Sorting / aggregatesAuto-generated order_by, _aggregateOrderByExpression and AggregateExpression (C)Declared per model rather than generated wholesale.
RelationshipsObject and array relationships, within one sourceThe Relationship kindCan cross connectors and subgraphs, which v2's could not.
Field namingHASURA_GRAPHQL_DEFAULT_NAMING_CONVENTION env varGraphqlConfig in the globals subgraphMoves from an env var to a metadata object.
RESTRESTified endpoints, built inVia plugins; plus a first-class JSON:APIJSON:API has no v2 counterpart.
Business logic
Custom logic in the schemaActions — declare types, point at an HTTP endpointCommands on a lambda connectorYou write a TypeScript/Python/Go function in the project instead of hosting a webhook and describing it.
Existing GraphQL APIRemote schemasThe GraphQL connectorSame goal, different mechanism — it becomes a connector like any other.
On data changeEvent triggers — webhook on insert/update/delete, with retriesWIP⚠️ Not yet available. Plan to keep this outside Hasura when moving to v3.
On a scheduleCron / scheduled triggersNot supported⚠️ No replacement. This one is simply gone.
Auth
AuthenticationHASURA_GRAPHQL_JWT_SECRET or an auth webhook, set as env varsAuthConfig, in the globals subgraphConfigured as metadata, and it is supergraph-level — one auth setup for every subgraph.
Admin accessHASURA_GRAPHQL_ADMIN_SECRET grants the unrestricted built-in admin roleThere is no admin secret⚠️ The biggest surprise in this table. Every v2 habit built on the admin secret — seeding, scripts, the console — needs rethinking. API access uses a Cloud PAT (cloud_pat header).
Permissionsselect / insert / update / delete permissions, per role, per tableTypePermissions (fields) + ModelPermissions (rows) + CommandPermissionsSplit by what is being protected instead of by operation, and declared per subgraph rather than globally.
Production
Caching@cached — Enterprise/Cloud only✅* via pluginsBoth are paid surfaces, by different means.
Allow list✅ Enterprise/Cloud only✅* via plugins
API limits / rate limiting✅ Enterprise/Cloud onlyWIP
Read replicas✅ Enterprise/Cloud onlyNo longer gated behind Enterprise.
Database migrationshasura migrate manages your SQL migrationsNot Hasura's job⚠️ Use your own migration tool, then ddn connector introspect to pick the change up. A real workflow change for anyone leaning on the v2 CLI.
CI/CDhasura migrate apply + hasura metadata applyddn supergraph build createBuilds are immutable and independently testable, so promotion replaces in-place apply.
HostingSelf-host the engine, or Hasura CloudDDN Cloud, or Private DDNThe data plane self-hosts; the control plane does not.

What an existing v2 project has to become

Read down that table and the migration sorts into three piles.

Things that carry over as ideas but not as syntax. Roles, session variables, row-level filters and column allowlists all still exist — they are just declared differently. A v2 select permission becomes ModelPermissions for the rows plus TypePermissions for the fields, split by what is being protected rather than by which operation you were doing. Relationships become a Relationship object and gain the ability to cross connectors, which v2 relationships could not do.

Things that change shape entirely. Actions become Commands backed by a lambda connector, so instead of hosting a webhook and describing its types to Hasura, you write a function in TypeScript, Python or Go inside the project. Remote schemas become the GraphQL connector. And filtering stops being generated for every column: you declare a BooleanExpressionType saying what is filterable.

Things that simply do not come with you. These are the ones worth deciding on before you start, not after.

The admin secret is gone

There is no HASURA_GRAPHQL_ADMIN_SECRET in DDN and no built-in unrestricted role behind it. Every v2 habit built on that secret — seeding scripts, console access, migration tooling, the “just use admin for now” shortcut in a test suite — needs another answer. API access uses a Cloud PAT sent as a cloud_pat header.

This is the single most disruptive row in the table and it is easy to miss, because nothing about it is announced loudly. If your deployment scripts authenticate with an admin secret today, they do not have a direct translation.

Cron triggers do not exist

Scheduled and cron triggers have no v3 replacement. If you run reconciliation jobs, digest emails or nightly cleanups off Hasura’s scheduler, that work moves to your own scheduler before you migrate.

Event triggers are unfinished

Event triggers are marked work in progress. Plan for them to live outside Hasura — a listener on the database’s own change stream, or writes going through a service that emits its own events. Do not architect a v3 migration assuming they will land in time.

Database migrations are no longer Hasura’s job

hasura migrate has no successor. Schema migrations belong to your own tool — Alembic, Flyway, whatever you already use — and you tell Hasura about the result by re-introspecting the connector. For teams who leaned on the v2 CLI to version schema and metadata together, this is a real workflow change and not a small one.

So should you migrate?

If you are starting fresh, are federating across several data sources or teams, and none of the gaps above are load-bearing for you, v3 is the direction the product is going and the supergraph model is genuinely better at that job.

If you have a working v2 installation whose value is a well-tuned permission model over one Postgres database, and you use cron or event triggers, then the honest answer is that migrating buys you architecture you may not need and costs you features you currently have. v2 is not going anywhere yet. Read the table, find your own load-bearing rows, and decide from those rather than from the version number.