Is Supabase Postgres? Yes - and Here Is What It Adds
Sagar Tayde · · 8 min read
Is Supabase Postgres? Yes - the Supabase database is a real PostgreSQL database, not a custom engine. What makes Supabase feel different is the set of services built around it, and the way security moves into the database itself. This guide is for developers who want to know exactly which part is “just Postgres” and which part is Supabase: how a request flows, the schemas and roles it creates, the four ways to connect, the limits that apply, and when the database on its own is all you need. Every Supabase fact here was checked against Supabase’s own docs on 14 November 2026.
Is Supabase Postgres?
Yes. Every Supabase project gets its own full PostgreSQL database, and Supabase’s changelog says new
projects default to PostgreSQL 17. It is not a fork or a look-alike engine: you connect with psql, pgAdmin or
any Postgres driver. Supabase adds services around that database - an auto-generated API, Auth,
Realtime and Storage - and they all read and write the same Postgres.
Supabase’s docs put it plainly: every project gets “a full Postgres database, not a Postgres abstraction”, and “we do not abstract the Postgres database - you can access it and use it with full privileges.” Its architecture guide also says Supabase prefers to get missing features added to upstream Postgres rather than run its own fork.
What type of database is Supabase?
Supabase is a relational, SQL database: tables, rows, foreign keys, joins and transactions, exactly as
in any PostgreSQL server. It is not a document or NoSQL store, even though the client library lets a
browser query it in a way that can feel like one. Extensions such as pgvector (for embeddings),
PostGIS and pg_cron add to that same database rather than replacing it.
Supabase as a product is more than the database. It is a backend platform: an auto-generated API, login, file storage, realtime updates and functions, all built on that one Postgres. You can connect to it with Prisma, Drizzle, SQLAlchemy or any other Postgres client, exactly as you would to any other Postgres server.
How Supabase works
A typical request from a browser or mobile app goes like this:
- The app calls your project’s URL with the public API key, and the signed-in user’s token if there is one.
- An API gateway routes the call to the right service: the REST API, Auth, Realtime or Storage.
- That service talks to Postgres. For data requests, it switches to the
anonorauthenticatedrole for that one request. - Row level security policies in Postgres decide which rows the request may read or change.
- When a row changes, Realtime can stream the change back to every subscribed browser.
Your own server can skip all of this and connect straight to Postgres with a connection string, like any other database.
The services around the database

According to Supabase’s architecture guide, a project combines several open-source pieces:
| Layer | What it does |
|---|---|
| PostgREST | Turns your tables into a REST API the browser can call |
| Auth | Signs users up and in, and issues tokens the database can check |
| Realtime | Streams table changes to browsers over websockets |
| Storage | Stores files, with their permissions kept in the database |
| Edge Functions | Runs your own server-side TypeScript and JavaScript code |
| Supavisor | Pools connections so many clients can share the database |
| API gateway | The single public entry point that routes traffic to the services above |
Where the database runs
Supabase lists 17 regions, including South Asia (Mumbai), ap-south-1. Its regions page says your
Postgres database, Auth service and Storage objects stay in the region you choose. If you pick a broad
general area instead of a specific region, Supabase places the project in an available region within
that area, so pick Mumbai by name if you need the data in India.
The schemas Supabase creates
Open a new project’s database and you will find more than your own tables:
| Schema | What lives there |
|---|---|
public |
Your application tables. These are what the REST API exposes |
auth |
Users, sessions and identities, managed by Supabase Auth |
storage |
File and bucket records, managed by Supabase Storage |
realtime |
Realtime configuration and messages |
extensions |
Where extensions such as pgcrypto are installed |
vault |
Encrypted secrets, through the Vault extension |
graphql |
The GraphQL API, through the pg_graphql extension |
Treat auth, storage and realtime as Supabase’s own. Reading from them is fine; changing their
structure can break the services that own them.
The roles, and how security moves into the database
Supabase creates Postgres roles that the API switches between for each request:
| Role | Used for |
|---|---|
anon |
Requests from users who are not signed in |
authenticated |
Requests from signed-in users |
service_role |
Trusted server code; bypasses row level security |
authenticator |
The API’s own login, which checks the token and switches role |
postgres |
The admin role you use from the dashboard and migrations |
When the browser calls the REST API, the request runs as anon or authenticated, and row level
security policies in Postgres decide which rows it may touch:
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY "users read their own orders"
ON orders FOR SELECT
TO authenticated
USING (user_id = auth.uid());
auth.uid() returns the signed-in user’s ID from the request’s token. This is the heart of the
Supabase model: your SQL is your access control. It also means a table exposed by the API with row
level security turned off is readable, and often writable, by anyone with the public key in the page.
Four ways to connect
From Supabase’s connection guide:
| Mode | Host and port | Network | Best for |
|---|---|---|---|
| Direct | db.<project-ref>.supabase.co:5432 |
IPv6, or IPv4 with the paid add-on | Long-running servers on IPv6 |
| Session pooler | pooler host, port 5432 | IPv4 | Long-running servers on IPv4, migrations, dumps |
| Transaction pooler | pooler host, port 6543 | IPv4 | Serverless functions with many short connections |
| Dedicated pooler | db.<project-ref>.supabase.co:6543 |
IPv6, or IPv4 with the add-on | High-traffic paid projects; transaction mode only |
Two details cause most connection errors. On the shared pooler, the username is
postgres.<project-ref>, not just postgres. And the shared pooler does not support prepared
statements in transaction mode, so ORMs such as Drizzle need prepare: false, and Prisma migrations
need a separate direct or session URL.
Connection limits by size
Each compute size allows a fixed number of direct connections, and more through the pooler:
| Size | Direct connections | Pooler clients |
|---|---|---|
| Nano and Micro | 60 | 200 |
| Small | 90 | 400 |
| Medium | 120 | 600 |
| Large | 160 | 800 |
| XL | 240 | 1,000 |
Supabase describes these as recommended values that can be changed. A busy app should connect through a pool rather than opening a connection per request.
Database size, disk size and read-only mode
Supabase separates two numbers. Database size is your data, indexes and materialised views. Disk size adds the write-ahead log and other files Postgres needs.
On the free plan, 500 MB of database size is a billing quota, not the read-only trigger. The free disk is a fixed 2 GB, and the database goes read-only when disk usage reaches 95%. On paid plans the disk grows by itself: at 90% full it expands by 50%, up to 200 GB at a time and four times in a rolling 24 hours. If it still reaches 95% after those four resizes, the project goes read-only. Supabase explains this in its database size guide.
What is portable, and what is not
Your tables, rows, indexes, views and functions are standard PostgreSQL, and a dump of them restores on
any Postgres host. Supabase itself points to standard tools such as pg_dump for moving in and out.
These parts only make sense inside Supabase:
- the
auth,storageandrealtimeschemas - policies that call
auth.uid()and foreign keys toauth.users - the
anon,authenticatedandservice_roleroles
If you ever move, these are the parts to rewrite. How to make a copy you own is covered in our Supabase backup guide.
When you only need the Postgres
If your backend is your own server, written in Node.js, Python or Go, and it handles login itself,
the services around the Supabase database are unused. Your server needs one thing: a reliable
DATABASE_URL.
For that case, a managed PostgreSQL service is simpler. Voroa’s managed PostgreSQL in Mumbai runs next to your app, is billed in rupees, and is reached by your server rather than the browser. The extensions it supports are in PostgreSQL extensions on Voroa, and pooling is covered in PostgreSQL connection pooling.
FAQ
Does Supabase use PostgreSQL or MySQL?
PostgreSQL. Every Supabase project is a Postgres database, and Supabase’s docs describe no MySQL option.
Is the Supabase database free?
The free plan includes a 500 MB database in up to two active projects, and a free project is paused after a week of inactivity. See Supabase pricing in India for paid plans.
Can I use the Supabase database without the Supabase client library?
Yes. Use any Postgres driver or ORM with a connection string. The client library is only needed for the REST API, auth, storage and realtime.
Can a Supabase database run in India?
Yes. Choose South Asia (Mumbai), ap-south-1, when you create the project. Your database, Auth and
Storage then stay in that region.
Why can my server not reach the direct connection?
Usually because your network or hosting platform has no IPv6. The direct host only resolves to an IPv6 address unless you buy the IPv4 add-on, so you see errors such as “Network is unreachable” or “could not translate host name”. Use the session pooler string instead, or buy the add-on.
Which Postgres version does Supabase use?
Supabase’s changelog says PostgreSQL 17 is the current default for new projects. Older projects on PostgreSQL 15 can be upgraded from the dashboard; the project is offline while the upgrade runs.
Use plain PostgreSQL with Voroa
If you only use the Supabase database and not the rest, start a free PostgreSQL database in Mumbai and connect your server with one variable. The wider comparison is in choosing a Supabase alternative.
Updated November 14, 2026