Hasura – What It Is and Why It Exists

June 24, 20265 min readUpdated 8/21/2026

Hasura points at a database you already have and gives you a working GraphQL API over it immediately — filtering, sorting, pagination, relationships, aggregates and row-level permissions — without you writing a single resolver. That is the whole pitch, and it is worth being precise about what it does and does not mean before spending twenty lessons on it.

What you actually get

Give Hasura a Postgres connection string and tell it which tables to expose. That is the entire setup. This query is running against the demo application this track uses, on a real engine:

query {
  properties(orderBy: {ratingAverage: DESC}, limit: 2) {
    title
    city
    ratingAverage
    host { firstName isHost }
    images(limit: 1) { url }
  }
}
{
  "data": {
    "properties": [
      {
        "title": "Oceanfront Villa, Private Steps to Sand",
        "city": "Maui",
        "ratingAverage": 4.98,
        "host": { "firstName": "Marcus", "isHost": true },
        "images": [ { "url": "https://images.unsplash.com/photo-1613490493576-..." } ]
      },
      {
        "title": "Lakefront A-Frame",
        "city": "Lake Tahoe",
        "ratingAverage": 4.96,
        "host": { "firstName": "Priya", "isHost": true },
        "images": [ { "url": "https://images.unsplash.com/photo-1449844908441-..." } ]
      }
    ]
  }
}

Nobody wrote code to produce that. host and images are separate tables; Hasura joined them because foreign keys exist, and it did it in one SQL query rather than one per row. Aggregates come free too:

query {
  propertiesAggregate {
    aggregate { count avg { pricePerNight } }
  }
}
{"data":{"propertiesAggregate":{"aggregate":{"count":12,"avg":{"pricePerNight":261.6666666666667}}}}}

The thing most tutorials skip

That request was sent with no authentication header at all, and it still returned data. That is not Hasura being insecure — it is a configured role for anonymous visitors, and it is allowed to read published listings and nothing else.

Watch what happens when the same unauthenticated request asks for bookings:

{
  "errors": [
    {
      "message": "field 'bookings' not found in type: 'query_root'",
      "extensions": { "path": "$.selectionSet.bookings", "code": "validation-failed" }
    }
  ]
}

Read that error carefully, because it is the single most important idea in Hasura. The query did not return an empty list, and it did not return “permission denied”. The field does not exist. Permissions in Hasura do not filter results out of a fixed schema — they shape the schema itself, per role. A visitor cannot ask about a table they have no permission on, because as far as their API is concerned there is no such table. Introspection shows them a smaller API than an administrator sees.

Send the same query with the admin secret and both tables are there:

{"data":{"bookingsAggregate":{"aggregate":{"count":3}},
         "propertiesAggregate":{"aggregate":{"count":12}}}}

What Hasura is not

It is not an application server. It does not log anyone in — it verifies a token something else issued. It does not run your business rules, send your email, or charge anyone’s card. The moment a request needs to do more than read or write rows under a permission rule, it belongs somewhere else and Hasura’s job is to route to it.

Teams get into trouble by trying to push real logic into the database to keep everything inside Hasura. The demo app in this track deliberately does the opposite: every read is a GraphQL query, and every write that means something goes through its own backend. Lesson 6 covers where that line belongs.

There are two products: Hasura v2 and Hasura v3 (DDN)

This is the part that wastes people’s afternoons. Hasura v2 and Hasura v3 (DDN) are different products, not two releases of one. Terminology does not carry over, the CLI is a different binary, and a v2 answer pasted into a v3 project does not work.

ItemHasura v2Hasura v3 (DDN)What actually changes
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.
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.
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.
On a scheduleCron / scheduled triggersNot supported⚠️ No replacement. This one is simply gone.
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).

Those five rows are the orientation; the full item-by-item comparison — thirty-three rows of it — is in the getting started lesson at the end of the track. Two rows above deserve flagging now, because they surprise people: DDN has no admin secret at all, and cron triggers do not exist in v3.

v2 or v3 — which should you learn?

Both, in that order, and this track is built that way. v2 is what the overwhelming majority of running Hasura installations are, it is what you will be asked about, and its concepts — permissions shaping the schema, roles, session variables, relationships — carry into v3 even when the syntax does not. Every lesson here teaches v2 against a running engine, then says what the same idea looks like in v3.

The versions this track is written against

Every v2 example in these twenty lessons was executed against this stack before it was quoted:

$ curl -s http://localhost:8081/v1/version
{"server_type":"ce","version":"v2.42.0"}

Hasura GraphQL Engine v2.42.0, Community Edition, over Postgres 16, with the Hasura CLI at v2.40.0. server_type: ce matters and this track will say so again: response caching, allow-lists and rate limiting are Enterprise and Cloud features. Where a lesson covers one, it labels it rather than pretending to demonstrate it.

The v3 half is different and the track is honest about it: it is written from the official Hasura DDN documentation as read on 2026-08-21, and was not run locally. v3 sections show configuration, never claimed output.

The application every example comes from

All of it comes from StayHub, a short-let booking app — listings, hosts, guests, bookings, reviews. It runs Hasura next to a FastAPI backend sharing one JWT, with four roles: anonymous, customer, host and staff. It is a real application with a real permission model, which is why its examples have awkward edges that invented ones never do.

Where to go next

Lesson 2 gets an engine running next to Postgres and gets you into the console. From there the track runs foundations, then the data API, then auth, then everything beyond the database, then what it takes to put it in production — finishing with two lessons on v3 and a set of interview questions.