Hasura Alternatives: PostGraphile, Supabase, and Directus for Auto-Generated APIs

Start with a scene that shows up often.

A three-person team inherited an internal operations dashboard two years ago. The database was Postgres, and it was not big: about twenty tables. They put Hasura in front of it, connected the tables, clicked through row-level permissions in the console, and by that afternoon the frontend had a GraphQL API it could query and mutate. Two weeks of CRUD work disappeared into a single afternoon. The relief was very concrete.

Two years later, the arrangement had started to strain. The dashboard pulled event data from Mongo, and the reporting screens needed to read ClickHouse. Hasura’s mainline had moved to DDN, the connector list had grown, and the billing unit had shifted from instances to active models, with the free tier reserved for a single developer. The team sat down to count how many models their tables, views, and remote schemas added up to, thought about relearning how metadata is written, and got nervous.

They were not rejecting Hasura. They had simply reached the point where the question changes: who should be carrying the auto-generated API layer?

What these tools actually take off your hands

The reason this category works is that it moves three jobs out of your codebase.

The first is schema reflection. You create tables, the tool reads them, and column types, foreign keys, and nullability come back out as a typed API surface. The second is query assembly. When the frontend asks for orders along with their customers and each customer’s city, nobody writes the join by hand; the tool builds SQL from the shape of the request and deals with N+1 along the way. The third is the permission decision. Who can read which row, who can change which column, usually lands in one declarative place instead of being scattered across dozens of handlers.

What separates these four tools is where that third job lands. Some write permissions into their own metadata. Some hand the question straight to database roles and row-level security. One builds a separate RBAC layer of its own. You will not notice the difference on a good day. You will notice it when you inherit someone else’s project, or when you get a call at midnight asking why one user can see another user’s data.

There is a second variable people skip past: who operates the thing. A hosted service absorbs upgrades, backups, and connection pooling on your behalf. Self-hosting hands you the controls and the on-call rotation in the same motion.

So the table below does not score anything. It puts the four tools on the same set of axes so you can see which kind of trouble you would rather avoid.

Tool Deployment License Databases API shape Where permissions live Entry cost
Hasura Self-hosted (Docker and similar) or DDN cloud Apache-2.0 v2 is mainly Postgres; DDN also connects MongoDB, ClickHouse, MS SQL Server Mostly GraphQL; saved queries can be exposed as RESTified endpoints Its own metadata: roles plus row and column permissions Self-hosting is free; DDN Base from $5 per active model per month
PostGraphile Self-hosted only, as a CLI, Node middleware, or standalone schema MIT Postgres only GraphQL only Postgres roles, RLS, and grants Software is free; the cost is servers and people
Supabase Mostly managed, with an official self-hosting option Apache-2.0 Postgres only REST (PostgREST) plus GraphQL (pg_graphql) Postgres RLS, roles, and grants Free tier; Pro from $25 per month
Directus Self-hosted or Directus Cloud Source-available under Monospace’s own license, not OSI open source Postgres, MySQL/MariaDB, Oracle, SQL Server, SQLite, CockroachDB Mostly REST, plus GraphQL Its own RBAC: roles and policies, down to individual fields Self-hosting can be free; cloud Core from $89 per month

Most people read that table and conclude they should pick whichever tool supports the most databases. That conclusion usually produces regret. Wide database support only matters when you have three legacy engines to serve at once. Otherwise it is a shelf of adapters you will never open.

The second easy mistake is treating “has GraphQL” as a shared trait. All four can emit a schema, but the schemas come from different places. Hasura’s schema is compiled from its metadata, so the thing you edit lives in metadata. PostGraphile and Supabase reflect the schema out of the database, so the thing you edit lives in SQL. Directus builds half its schema from the database and half from configuration clicked together in Studio. That difference decides how many places you touch when a field changes, and which file a new colleague should read first.

Hasura: the deepest permission model, and the tightest leash

Picture a five-person team building a SaaS back office. The product is multi-tenant. A single orders table holds rows for dozens of customer companies, and each signed-in user should only see their own company’s data. A sales manager also needs visibility into their reports’ orders, while an ordinary rep sees only the deals they personally work. Finance can edit amounts. Operations cannot.

In Hasura that is a configuration exercise. Roles, row-level filter expressions, and the set of writable columns are all declared in metadata, and identity arrives through session variables from a JWT or a webhook. Once a version is written, the whole API surface is bound by those rules, so a newly added field cannot quietly escape through some hand-written endpoint. Row-level and column-level permissions are both supported, and combined with its handling of relationships and multi-level nested queries, this remains the hardest part of Hasura to replace.

It can also serve REST. Version 2 includes RESTified endpoints, which hang saved queries and mutations on a URL template, and you can export an OpenAPI description. It is not a full REST framework, but for the common case of two fixed endpoints for a third party, it is enough.

The cost is attachment. Metadata is Hasura’s own dialect. Once the permission logic lives inside it, moving that logic elsewhere intact is close to impossible. The jump from v2 to v3 was an architecture change, with connectors, supergraph, and the build flow all renamed and rearranged. Existing projects are not forced to migrate, but new features and new connectors only grow on the new architecture. Pricing moved with the architecture too. DDN Free costs $0 but allows a single supergraph developer. Base starts at $5 per active model per month. Once the model count climbs, the bill grows faster than your request volume.

Which is why the argument for staying on Hasura can be boiled down to one sentence: your permission complexity has reached the point where rewriting it costs more than paying for it.

PostGraphile: relief for teams that keep permissions in the database

Now consider a different three-person team running an internal data dashboard. The lead came up through database administration. Their working habit is that permissions belong to the database and nowhere else. Who is an analyst, which tables each role can read, which region each row belongs to, all of it is written in Postgres with roles and RLS. Any proposal that duplicates the permission list in an application layer gets a flat no.

PostGraphile follows that habit instead of fighting it. It reads the Postgres schema and reflects tables, views, functions, and foreign key relationships into GraphQL, then reuses the roles and RLS policies that already exist. After a user signs in, you put their identity into pgSettings and every subsequent query runs inside that role’s context. There is one copy of the rules. What you see when you connect with psql is what the API sees.

Its respect for SQL shows up in other places as well. Functions can become mutations directly, so heavy business logic can stay in database functions. Smart tags let you mark which tables are exposed or rename fields from comments. The most practical feature is export, which turns the generated schema into runnable JavaScript you can maintain yourself; the official documentation calls this having no lock-in.

Its reputation for performance comes from how it executes. A conventional GraphQL server gathers requests layer by layer through DataLoader, and with many tables that becomes a long chain of small queries. PostGraphile takes another route, compiling the whole query tree into one SQL statement, or a small number of them, and letting the database optimize the result. The documentation is blunt about this, to the effect that the same speed is hard to reach with a conventional approach. On read-heavy back office systems the gap only becomes visible once the data volume grows. Early on you will not feel it.

The friction is equally clear. It only speaks Postgres, and there is no official path to a second database. It only emits GraphQL, so REST means putting a layer in front yourself. There is no official hosted offering, so processes, connection pooling, upgrades, and monitoring are yours to run. Version 5 replaced the execution engine and got much faster, but plugins are still migrating, and the documentation notes that PostGIS has not yet been ported to v5. One more detail gets overlooked: the schema is reflected from the database at runtime, so changing a table does not require regenerating code. The same property means a mistaken permission takes effect immediately, with no intermediate code standing between the mistake and the API.

Choosing it amounts to choosing a way of working. You treat the database as the core asset of the product, and someone on the team can read a query plan.

Supabase: you are buying a backend, not an API

Here is a third scene: two people building the backend for a small app. They need sign-in, avatar uploads, push notifications, and an endpoint they can query directly. At that size, standing up an API layer and then bolting on a separate auth service is pure self-inflicted work.

That is the slot Supabase occupies. Open a project and Postgres is there, Auth is there, object storage and realtime subscriptions are there. The API layer comes included: PostgREST maps tables straight to REST, and the pg_graphql extension maps the same schema to GraphQL, with both endpoints sharing one set of database permissions. You write RLS policies in SQL and both interfaces obey them at once, with anonymous users, signed-in users, and the service role each running under their own role.

Its permission model has the same origin as PostGraphile’s: the database decides. The difference is that Supabase also hands you the scaffolding around it. The price of that scaffolding is that it pulls you toward its shape. The database has to be Postgres. Self-hosting is officially supported, but it means maintaining a stack of containers, and when something breaks the search space is much larger than on the managed side. The free tier limits are worth knowing before you start: a 500MB database, at most two active projects, and projects paused after a week of inactivity. Pro starts at $25 per month and includes 8GB of disk plus one Micro instance’s worth of compute, with additional projects billed for compute separately. GraphQL is an extension layer, and from pg_graphql 1.6 onward introspection is off by default, so you have to enable it before pointing GraphiQL at the endpoint.

If your requirements include sign-in and file upload, Supabase will usually save you more work than any pure API tool. If you need neither, you are paying the comprehension cost of a backend you will not use.

Directus: a back office for colleagues who do not write code

The last scene is a content team. Six people. The operations staff want to add fields, rewrite copy, and reorder items themselves. The product manager wants to give different roles different permissions. There is one developer, and the thing they least want is a deploy every time someone wants a new field.

Directus addresses that layer. It treats your existing database as the source of truth and puts a Studio on top. Operations edit data in the interface, the developer changes structure in the database, and the two do not collide. The API is a byproduct: REST is the primary interface, GraphQL is available, and an OpenAPI description exports directly. Permissions are its own RBAC system, with roles and policies that go as fine as whether a specific field can be read or written. Database support is the widest of the four, covering Postgres, MySQL/MariaDB, Oracle, SQL Server, SQLite, and CockroachDB, which matters a great deal to companies whose database was decided years ago by someone else.

One change has to be stated plainly. The Directus repository now uses Monospace’s own Sustainable Core License, which is not on the OSI list of open source licenses. The source is visible and modifiable, but commercial scale is tied to features. Organizations with annual revenue under $5 million and fewer than 50 employees can apply for the Open Innovation Grant and self-host for free. Above that, or if you need SSO, you move up a tier: cloud Core starts at $89 per month, and SSO is not offered at the Core level. Teams that evaluate it as a free open source CMS tend to get a reminder email about six months in.

The fit is narrow and clear. Directus suits you when the core requirement is letting people manage data through an interface and the API is something you need in passing. If the core requirement is feeding a frontend, the prettiest Studio in the world will not help.

Before you commit, run a two-week side-by-side

The most dangerous move at this point is pointing the tool at your production database and seeing how it feels. All four will be running within half an hour. All four will also give you the impression, within that same half hour, that this one is simpler.

A better approach is to pick three real tables and two real permission cases, then build each one in two candidate tools. The three tables should include a primary table, a many-to-many join table, and a table with soft deletes. The two cases should include a row-level filter, such as seeing only your own department’s data, and a column-level restriction, such as amounts readable only by finance. When you are done, look at three things. They tell you more than any feature list.

The first is how permissions are written. Is it a YAML block, a SQL policy, or a set of checkboxes in a UI? Once it is written, hand it to someone who was not involved and ask them whether sales can change a particular field. Time how long it takes them to answer with confidence.

The second is the rework involved in changing structure. Add a column, change a foreign key, split one field into two tables. Do each one and write down every file and screen that had to change with it. This is where the tools diverge most, and it is exactly what a demo video hides.

The third is the first scene of a failure. Break a permission on purpose and see where the error points: a line in metadata, a named SQL policy, or a bare 500. A clear first scene saves half an hour on every future investigation. A vague one teaches the team, within six months, to try restarting things first.

So which one

Compress all of the above into sentences you can act on.

If permissions are complex, the product is multi-tenant, the data sources keep multiplying, and the team already knows Hasura’s metadata, stay on Hasura. Moving means rewriting the entire permission model, and that risk costs more than the bill. If you do move to DDN, count your active models first and work out the monthly figure before committing, not after the first billing cycle.

If you only have Postgres, permissions already live in RLS, and someone on the team will read SQL, take PostGraphile. What it offers is cleanliness: one set of permissions, one schema, one Node process, and a clear idea of where to look when something breaks. The precondition is that you can live without a hosted service.

If you need sign-in, files, and realtime subscriptions, and the team is too small for anyone to babysit infrastructure, take Supabase. Do not compare it to Hasura feature by feature as if it were a drop-in replacement. It sells a whole backend, and the API is one layer of it.

If the requirement is letting operations maintain content with fields and permissions changing often, take Directus. Check which license tier your revenue and headcount fall into before deciding between self-hosting and cloud.

If none of the four fits exactly, there is a middle path: use auto-generated APIs for part of the tables, keep the complicated business logic beside them, and connect the two through remote schemas or a service of your own. These tools are at their best on endpoints that look like CRUD. Force them to carry domain logic and you end up with a pile of if statements written in configuration.

There is also a plainer test than any feature matrix. When this thing breaks at two in the morning, would you rather be reading SQL or reading metadata? Pick whichever one you can still understand at that hour. The expensive part of a migration is not the move itself. It is every day that follows.

Related reading

Browse the full guide →

Stay updated with our latest AI insights

Follow FuturePicker on Google
Scroll to Top