TL;DR
We built Constellation — an open-source GraphQL engine written in Go that is a near drop-in replacement for Hasura Community Edition. It reads the same metadata, generates the same schema, and serves the same GraphQL API. In production it uses ~90% less memory than Hasura with comparable or better latency, before any dedicated performance work.
If you run Hasura today, this post is for you. If you build GraphQL infrastructure, care about open-source sustainability, or just want to see real production memory numbers from a fresh Go rewrite — keep reading.
The problem with depending on someone else's engine
Hasura v2 has been the backbone of Nhost's GraphQL layer for years. It's a genuinely good piece of engineering, and we built a lot on top of it.
But three things changed:
Hasura v2 is winding down. Development has shifted to Hasura v3, which takes a different approach to open source — the engine core is Apache-licensed, but the CLI, web console, and developer tooling are proprietary. That's a meaningful shift from v2, where the full stack was open. Continuing to depend on an engine that's winding down toward end-of-life, or migrating our GraphQL and permissions layer to one where the tooling is closed, weren't paths we were willing to take.
Memory was consistently our heaviest service per project. A GraphQL engine sits between every client request and your database. It should be fast and lean. Instead, it was the most expensive thing we ran per project — and memory in particular is hard to throttle gracefully under load.
We didn't own a critical piece of our infrastructure. The API and permissions layer sits at the center of every Nhost application. When something goes wrong, or when you want to ship something new, depending on someone else's roadmap is expensive in ways that don't show up in dashboards.
So we built our own — while keeping full compatibility with Hasura on the GraphQL request path.
What Constellation actually is
Constellation is a GraphQL engine that turns a relational database into a role-based GraphQL API. It is designed to be a near drop-in replacement for Hasura Community Edition.
Concretely, that means:
-
Same metadata format. It reads your existing Hasura metadata — either from a YAML/JSON file on disk, or straight from Hasura's
hdb_catalog.hdb_metadatatable. - Same generated schema. Same types, same relationships, same permission-aware shape per role. We verify this with byte-level schema diffs (more on that below).
-
Same request surface. Queries, mutations, and subscriptions over the same
/v1/graphqlendpoint, plus remote schemas and cross-source remote relationships.
It's a fresh Go codebase — not a fork of Hasura. PostgreSQL and SQLite are first-class backends today. The connector design is built so additional databases can plug in without touching the query planner.
Where Hasura's behavior is surprising or outright wrong, we occasionally diverge — and every such divergence is documented in KNOWN_DIFFERENCES.md. Correctness over surface area is one of our explicit goals.
The numbers that made us ship it
We ran Constellation against real production workloads, side by side with Hasura, on the same database and the same traffic. We didn't tune anything special for these results.
Memory
Constellation's memory usage sits ~90% below Hasura's serving the same traffic. In absolute numbers: Hasura at ~180 MiB, Constellation at ~15 MiB. This is not a benchmark environment — these are production dashboards.
A note on the CPU panel in that chart: Constellation's CPU looks dramatically lower, but we're talking millicpus here. Both engines are cheap on CPU in absolute terms; the gap is real but small. Memory is where the meaningful difference lives.
Latency
Across the same window, Constellation also serves requests a little faster.
Request latency over the same period: Hasura (blue) regularly spikes toward 60–80 ms, while Constellation (purple) mostly stays under 40 ms.
To make the comparison concrete, here's the per-period delta of Constellation minus Hasura for the same traffic. Anything in the green region (below zero) means Constellation was faster; the occasional red spike above the line marks the moments it wasn't.
Latency delta (Constellation minus Hasura). Most of the line sits in the green, below-zero region, meaning Constellation was faster, with a handful of red spikes where it briefly wasn't.
These are raw production dashboards, not a curated benchmark. That's rather the point. We didn't tune anything special to get here.
How it works alongside Hasura (not instead of it — yet)
Constellation doesn't yet implement Hasura's metadata HTTP API (POST /v1/metadata). It consumes metadata but doesn't author it. So the current deployment model is straightforward:
Hasura owns metadata authoring. Constellation owns request serving. Both point at the same database.
In practice, an Nhost project running Constellation gets two endpoints:
-
https://<subdomain>.hasura.<region>.nhost.run→ Hasura (metadata authoring, plus anything Constellation doesn't serve yet) -
https://<subdomain>.graphql.<region>.nhost.run→ Constellation
The key property: you can flip Constellation on, run real traffic through it, and remove it at any time to fall back to Hasura with zero migration. That's the whole appeal of the side-by-side model.
Once Constellation supports metadata mutations on its own, the Hasura half can be dropped entirely.
What's solid vs. what's missing
Constellation is alpha. That label reflects feature coverage against Hasura — not the stability of what's already there.
Solid and in production:
- ✅ PostgreSQL and SQLite connectors
- ✅ Full GraphQL query, mutation, and subscription pipeline
- ✅ JWT and admin-secret auth
- ✅ Role-based permissions
- ✅ Remote schemas
- ✅ Cross-source remote relationships
Not yet implemented:
- ❌ Hasura Actions
- ❌ Event and cron triggers
- ❌ REST endpoints
- ❌ Allowlists and query collections
- ❌ Inherited roles, native queries, computed fields
- ❌ MSSQL, BigQuery, Snowflake backends
If your app lives mostly in the query/mutation/subscription world, there's a good chance Constellation already does what you need. If you lean heavily on Actions or event triggers, keep those on Hasura for now.
What's next — and how you can shape it
The near-term roadmap is focused on closing the gap: implementing the metadata HTTP API so Constellation can own the full stack without Hasura running alongside it, expanding the feature surface into Actions and triggers, and eventually supporting additional database backends.
But the most valuable thing right now isn't what's on our roadmap. It's real-world usage.
There are four concrete ways you can help:
Run real traffic through it. Enable Constellation next to your existing Hasura instance (see below) and point production traffic at it. That's the fastest way to find real divergences and edge cases.
Report schema diffs. If
nhost schema diffturns up a divergence that isn't covered inKNOWN_DIFFERENCES.md, open an issue with the diff hunk and a minimal metadata snippet. That's how new issues get documented — or fixed.Report runtime bugs. A query that returns different results, a subscription that misbehaves, a permission that doesn't line up — under live traffic these are the most valuable reports we can get.
Read the code and contribute. It's open source and we've worked hard to make it approachable — small interfaces, golden-file tests, and per-package documentation. PRs and questions are welcome.
Try it yourself
The lowest-friction path is enabling Constellation on any Nhost project. Add one block to nhost/nhost.toml:
[experimental.constellation]
version = "0.4.0"
Pick the latest tag from CHANGELOG.md. With that in place, your project runs both engines. Remove the block and you're back to Hasura.
To verify Constellation generates the same schema as Hasura for each role:
nhost schema dump --role user \
-u "https://<subdomain>.hasura.<region>.nhost.run/v1/graphql" \
-o schema.hasura.user.graphqls
nhost schema dump --role user \
-u "https://<subdomain>.graphql.<region>.nhost.run/v1/graphql" \
-o schema.constellation.user.graphqls
nhost schema diff -a schema.hasura.user.graphqls -b schema.constellation.user.graphqls
An empty diff means Constellation produced a byte-equivalent schema for that role. Any non-empty diff should map to a known difference — and if it doesn't, that's exactly the kind of issue we want to hear about.
Prefer to run it standalone without an Nhost project? The repository README has full build and run instructions.



Top comments (0)