Hasura gained popularity and became widely adopted for its ability to quickly let teams spin up a GraphQL API on top of a relational database, particularly PostgreSQL. That speed makes it a strong early-stage choice. But as systems grow, many teams start running into architectural limits like:
- Schema rigidity: Hasura’s API layer is tightly coupled to the database schema, which makes it harder to evolve APIs or decouple logic over time.
- Architectural control: Fine-grained control over resolver logic, caching, or gateway behavior is challenging to achieve.
- Vendor lock-in: Hasura’s proprietary metadata format introduces vendor lock-in and complicates migration efforts.
- Limited extensibility: Adding functionality through actions or remote schemas often requires managing external services, adding friction to development workflows.
If you're starting to hit those limits and exploring alternatives, a more robust solution like Grafbase should be on your radar. Grafbase’s schema-first model supports multiple data sources out of the box, enables declarative federation, and avoids the need to stitch or host separate subgraph services. With the Postgres extension, you can introspect your schema and publish it directly into a federated GraphQL API while controlling how your gateway behaves.
This guide provides practical migration steps to guarantee a smooth migration from Hasura to Grafbase, offers side-by-side comparisons with Hasura, and helps you determine whether Grafbase is the right next step for your team.
Grafbase vs. Hasura: Comparing key concepts
This section compares key features between Hasura and Grabase to help you understand how these core features are translated and handled on each platform.
Feature | Hasura | Grafbase |
---|---|---|
Schema management | Auto-generated from Postgres | Schema Definition Language (SDL) first, explicit schema definition, declarative GraphQL schema (schema.graphql ) |
Data sources | PostgreSQL (primary), Remote schemas, REST via actions | PostgreSQL, REST, gRPC, Snowflake, Kafka via extensions |
API Gateway | Basic built-in API layer; limited control over gateway behavior | GraphQL Gateway with custom resolvers, and federated subgraphs |
CLI |
hasura-cli for migrations, metadata, and project management |
grabase CLI for local dev, schema introspection, publishing, and gateway setup |
Schema registry | No native schema registry or versioning; schema can be exported via introspection or the console | Built-in schema registry, versioning, schema validation with Grafbase check |
To dig deeper into how the two tools compare, this Hasura alternative guide covers more architectural and workflow-level differences. You’ll also find platform-specific details in the Grafbase docs if you're exploring a larger rollout across teams or environments.
Once you are familiar with what Grafbase offers, the next step is learning how to implement it. The following sections guide you through each stage of the process, including exporting Hasura metadata, generating your Grafbase schema, configuring subgraphs, and deploying via the Grafbase Gateway.
Preparing for migration
Before starting your migration, audit your current setup and align your team on what a successful switch looks like. Use this checklist to make sure your team is ready for migration:
- Audit Hasura setup: List all tables, relationships, permissions, actions, event triggers, and remote schemas in use.
- Identify business logic: Document any implemented custom logic.
- Map auth flows: Understand your current authentication and authorization setup.
- List integrations: Note any webhooks, REST endpoints, or third-party integrations.
- Set clear migration goals: Get your team on board, make sure everyone agrees on the plan, and define the migration objectives.
Migration tools
You’ll need to have these tools installed:
- Grafbase CLI
- Grafbase Gateway
- Grafbase Postgres extension
Step-by-step migration process
We’ll build a small demo project with features like custom actions and remote schema (REST API) to demonstrate how to safely migrate a real Hasura setup to Grafbase.
1. Export Hasura metadata
As mentioned earlier, you need to audit your Hasura setup before the migration process. Start by exporting your Hasura metadata via the CLI by running:
hasura metadata export
Alternatively, you can also use the Hasura console or API which is part of the Hasura open source framework.
This will instantly generate a metadata
containing configuration data about your Hasura actions, remote schemas, custom types, and more. Study them carefully, as these will help you shape your Grafbase schema.
2. Generate a federated GraphQL schema
The next step is to generate GraphQL schema. Even if your database is complex, the Grafbase PostgreSQL extension makes it easier to convert and translate the exported Hasura metadata for use in Grafbase. This extension also helps teams generate a GraphQL schema from an existing PostgreSQL database.
To generate the GraphQL schema, follow these steps:
a. Make sure you have installed the Grabase CLI and the Grafbase Postgres extension.
b. Next, create a grafbase-postgres.toml
configuration file in your project and add this:
# Change this to reflect the version of the extension you want to use.
extension_url = "https://grafbase.com/extensions/postgres/0.4.7"
# The generated SDL needs to know in which schema the type comes from.
# If the schema name is not written in the schema, Grafbase will use this value.
default_schema = "public"
# The name of the database in the Grafbase configuration.
database_name = "default"
c. Next, introspect your database and generate a GraphQL schema by running:
grafbase postgres \
--database-url "postgres://postgres:user@password:5432/your_db_name" \
introspect > schema.graphql
This will generate a schema.graphql
file that represents your database schema.
3. Configure the project
Next, within your project, create a grafbase.toml
file to configure the Postgres extension and point to the generated schema:
[extensions.postgres]
# Change to the latest version.
version = "0.4.7"
[[extensions.postgres.config.databases]]
name = "default" # This must match the name in the grafbase-postgres.toml
url = "postgres://postgres:user@password:5432/your_db_name"
[subgraphs.postgres]
schema_path = "./schema.graphql"
Test the success of the SDL generation and launch the development server by running:
grafbase dev
Navigate to http://127.0.0.1:5000
in your browser to explore the generated schema.
With the Postgres subgraph deployed, let’s now federate an external REST API into the graph.
4. Publish the Postgres subgraph
Once you're ready, first create a new graph in the Grafbase Dashboard. Next, publish the Postgres schema to the Grafbase platform as a virtual subgraph using this command:
grafbase publish \
--name postgres \
<name-of-org>/<name-of-graph>@<branch> \
--schema schema.graphql \
--virtual
This lets you map your database into a federated graph with no intermediate API layer, no stitching, and no subgraph service to maintain.
You can do this for as many schemas as you have. But what happens if you have REST APIs to federate?
5. Migrate remote schemas
Grafbase provides different extensions to extend federated graphs. One such extension is the REST extension, which, when integrated, enables you to define REST endpoints and map them to GraphQL fields using two directives: @restEndpoint
and @rest
.
To use this REST extension, you must create a new schema file separate from your Postgres schema, as Grafbase requires that Postgres and REST extensions reside in different subgraphs.
This example uses the publicly available fake store REST API. Follow these steps to see how you will use it in Grafbase:
a. Add the REST extension: In the grafbase.toml
file, add the code below to install the REST extension, then add the link to the new REST schema you created. Like so:
[extensions.rest]
version = "0.4.1"
[subgraphs.rest]
schema_path = "./rest-schema.graphql"
Run grafbase extension install
to install the newly added REST extension into the grafbase_extensions
directory. This command installs any extensions declared in the grafbase.toml
that are not yet installed.
b. Define the REST schema: In the newly created REST schema file, add this code:
extend schema
@link(
url: "https://grafbase.com/extensions/rest/0.4.1"
import: ["@restEndpoint", "@rest"]
)
@restEndpoint(name: "restProducts", baseURL: "https://fakestoreapi.com")
type RestProducts {
title: String!
price: Float!
description: String!
category: String!
image: String!
}
type Query {
getAllRestProducts: [RestProducts!]!
@rest(
method: GET
endpoint: "restProducts"
path: "/products"
selection: """
[.[] | {
title: .title,
price: .price,
description: .description,
category: .category,
image: .image
}]
"""
)
}
This code fetches product data from a public REST API (fakestoreapi.com
) and exposes it as a GraphQL query (getAllRestProducts
) using Grafbase’s REST extension.
Test locally by saving, stopping your local development environment, and then running grafbase dev
again. It’s as simple as that!
c. Publish the REST subgraph: Now, you can publish this new subgraph to the Grafbase platform by running the deploy command you used previously, but with a change to reflect the name of the subgraph you want to publish and the path to the current local schema:
grafbase publish \
--name rest \
<name-of-org>/<name-of-graph>@<branch> \
--schema rest-schema.graphql \
--virtual
Integrating REST APIs typically requires setting up Actions in Hasura, which can involve complex configuration. By contrast, as demonstrated above, this was accomplished in just three straightforward steps on Grafbase.
6. Combine and deploy subgraphs with the Grafbase Gateway
After publishing the new subgraph, you can deploy the federated graph using the Grafbase Gateway. The gateway automatically keeps up with subgraph updates and unifies different subgraphs into a single federated graph for querying. In this case, it will federate the Postgres and REST subgraphs.
Follow these steps to deploy:
a. Create an access token in the Grafbase organization settings.
b. Export the access token and start the gateway using this command:
export GRAFBASE_ACCESS_TOKEN="ey..." //exported token
c. Start the gateway by running:
grafbase-gateway --graph-ref name-of-graph --config grafbase.toml
The --config
argument is optional, but to start the gateway with a graph ref, the access token is mandatory.
You now have the schema registry populated, the gateway set up, and the federated graph on Grafbase up and running. You can send queries to the Grafbase Gateway and observe it in action with your Federated Graph.
Refer to the Grafbase Postgres extension guide for more information on features, configuration options, and running the gateway.
Post-migration tips
On successful migration from Hasura to Grafbase, it's also essential to validate and optimize your new setup. Here’s a checklist of what to test and monitor post-migration:
Query parity between systems
Confirm that all critical and/or complex queries and mutations behave as expected and return the same data structures and values as they did in Hasura.
Additionally, to verify schema consistency between the exported Hasura metadata and the generated schema on Grafbase, run:
diff name_ofhasura_metadata.graphql name_of_grafbase_schema.graphql
This will show you line-by-line differences between your Hasura-generated schema and your Grafbase schema, helping you identify mismatches or missing types and fields.
Set up schema checks
Using the grafbase check
command, you can check your schema against the Grafbase Platform. This will help you safeguard against introducing breaking changes or errors into your GraphQL API, especially when working in multiple teams. Read more on the dedicated docs page.
Deployment configuration (cloud services or self-hosted)
Validate that tokens, secrets, and environment variables are securely stored and accessible in your cloud or container platform.
Subgraphs management
Organize schemas and group related functionality into logical subgraphs for modularity and clarity.
Observe latency and performance changes
Without relying on external tools like Grafana or Datadog, Grafbase provides built-in solutions for telemetry and observability features. You can benchmark workload and key metrics after migration, and use the Grafbase dashboard to view insights and analytics on error rates and slow responses, helping you to detect regressions proactively.
Horizontal scaling
Monitor how your federated graph performs as you add more subgraphs or services. Grafbase’s gateway is designed to scale, but you’ll still want observability in place.
There are additional steps to verify success after migration, but taking the above as a starting point is a great approach.
Troubleshooting mixing resolver extensions in the same subgraph
You might encounter the following error when starting the federated gateway:
Error: could not start the federated gateway
Caused by: Error validating federated SDL: Selection Set Resolver extension postgres-0.4.1 cannot be mixed with other resolvers in subgraph 'postgres', found rest-0.4.1
Cause: This error occurs when you try to use both the Postgres and REST resolver extensions in a single subgraph (in this case, using REST extension in the Postgres subgraph). Grafbase doesn't support combining multiple selection set resolver extensions (such as @postgres
and @rest
) within the same subgraph.
Solution: Separate the conflicting extensions into distinct subgraphs. For example, if your Postgres subgraph already uses the @postgres
extension, create a new subgraph (e.g., rest) for REST-based resolvers and configure it independently in your grafbase.toml
.
These benefits are available to you after migration
Now that you have seen how to easily migrate from Hasura to Grafbase, here’s a summary of some advantages that the highlighted Grafbase features provide for your team and how they help you scale beyond Hasura’s limitations.
Hasura limitations | Grafbase solution |
---|---|
Schema rigidity | Grafbase uses a schema-first approach. As such, it lets you compose your GraphQL schema from multiple sources (databases, APIs) rather than binding it directly to a single database schema. |
Architectural control | Grafbase provides more granular control over caching strategies and gateway behavior. Its Edge Gateway allows you to orchestrate all your data fetching and optimize performance at the gateway layer, rather than being restricted to database-driven resolvers. |
Vendor lock-in | Grafbase avoids proprietary metadata formats tightly coupled to its runtime. Its approach is to use standard GraphQL schemas and open configuration, making migration and integration with other tools less risky and complex. |
Limited extensibility | Grafbase is designed for extensibility, allowing you to connect multiple APIs and services and implement domain-specific logic directly within your schema. |
Wrapping up
For teams running into Hasura’s limitations, exploring alternatives like Grafbase provides benefits that make it a worthwhile move.. The benefits include long-term flexibility and maintainability, improved API architecture, enhanced developer productivity, and experience. Grafbase also provides more control over your GraphQL gateway and production-grade federation support.
Ready to try it out? Get started with Grafbase and migrate your federated graph to Grafbase in minutes.
Top comments (0)