Database
Managed Postgres 15 with full SQL, RLS, migrations, and realtime — wired into every Swarmz project
Every Cloud-enabled project gets a dedicated Postgres 15 database. Full SQL, no proprietary query language, no ORM lock-in. The agent reads your live schema, writes migrations as you describe tables, and generates queries that match your real columns — no hallucinated names.

Postgres 15
The database is standard Postgres 15. Anything you can do in Postgres, you can do here:
- Tables, views, materialized views, indexes, constraints
- Triggers and stored procedures (PL/pgSQL)
- RLS policies, security definer functions
- Extensions (
pgvector,pg_cron,pg_net,postgis,pg_graphql, and the rest of the supabase set) - Roles, schemas, search paths
There's no Swarmz-specific query syntax. The agent writes SQL, and so do you when you want to.
Schema management
The agent treats schema changes as migrations — versioned SQL files that get applied to your database in order. When you describe a table in chat, it:
- Drafts the SQL.
- Names the migration (e.g.
20260430_create_posts_table). - Applies it to your database via the Supabase Management API.
- Commits the SQL file to your project so the schema is reproducible.
You can browse migration history from the Cloud tab and roll back if something goes sideways.
Create a posts table with title, content, author_id (references users),
published boolean, and created_at timestamp. Anyone can read published
posts. Authors can edit their own.That single message produces a migration with the table, the foreign key, and two RLS policies — no SQL skills required.

Migrations are tracked in Postgres's supabase_migrations.schema_migrations table, so they survive across environments. If you ever eject to a self-managed Supabase project, the history travels with the database.
Connecting from your app
Every Cloud project ships with a preconfigured supabase JS client. The connection URL and anon key are wired into your project's .env automatically — you don't paste anything.
import { supabase } from '@/lib/supabase';
const { data: posts, error } = await supabase
.from('posts')
.select('*, author:profiles(name, avatar_url)')
.eq('published', true)
.order('created_at', { ascending: false });The client uses your project's anon key by default, so all queries respect RLS. For server-side code that needs to bypass RLS, use the service role key inside an edge function — never expose it to the browser.
Row-level security (RLS)
RLS controls who can read, insert, update, and delete each row. It's the difference between "anyone with the anon key can read every row in users" and "users can only read their own row."
Every table the agent creates ships with RLS enabled. The agent writes policies that key off auth.uid() (the JWT claim of the signed-in user) by default:
-- Users can read their own profile.
create policy "Users read own profile"
on public.profiles for select
using (auth.uid() = id);
-- Authors can edit their own posts.
create policy "Authors update own posts"
on public.posts for update
using (auth.uid() = author_id)
with check (auth.uid() = author_id);Describe the rule in plain English and the agent translates:
Only workspace admins can delete a project.becomes a using (...) clause that joins through workspace_members and checks the role column.
Disabling RLS on a public table makes every row readable by anyone with the anon key. Only do this for tables you intentionally want to expose, and prefer a select-only policy over disabling RLS.
Realtime subscriptions
Postgres CDC (change data capture) streams over WebSocket to subscribed clients. Enable realtime per table from the Cloud tab, then subscribe with the JS client:
const channel = supabase
.channel('posts-feed')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'posts' },
(payload) => console.log('Change:', payload),
)
.subscribe();You'll get INSERT, UPDATE, and DELETE events as they happen, filtered by the RLS policies of the listening user. See Realtime for filters, presence, and broadcast.
Direct SQL
You don't have to go through the agent. The Cloud tab in your project editor includes a SQL runner — paste any query and it executes against your database with results inline.
select count(*) as total, status
from posts
group by status;You can also run SQL programmatically via the proxy API:
const res = await fetch('https://api.swarmz.net/v1/cloud/query', {
method: 'POST',
headers: { Authorization: `Bearer ${token}` },
body: JSON.stringify({ projectId, sql: 'select * from posts limit 10' }),
});Writes are rate-limited to 60/min per workspace; reads to 300/min.
Backups
Cloud takes daily automatic snapshots of your database with 7-day retention on all paid plans. Restoring a backup creates a new project from the snapshot — your live database isn't overwritten.
Point-in-time recovery (PITR) is available on Business and Enterprise plans, letting you restore to any second within the last 7 days. Free plans get the daily snapshot only.
You can browse and restore backups from the Cloud tab, or via the backups API.
Limits
Each plan has soft caps. You'll get a dashboard banner at 80% of any limit, and a hard stop on writes if you hit 100% on database size.
| Plan | DB size | Connections | Queries/min |
|---|---|---|---|
| Free | 500 MB | 60 | 1,000 |
| Pro | 8 GB | 200 | 10,000 |
| Business | 50 GB | 500 | 50,000 |
| Enterprise | Custom | Custom | Custom |
Need more? You can buy a disk add-on per project from the Cloud tab — 1 GB minimum, 200 GB max per request, prepaid monthly at the retail $/GB rate. Connection limits scale with the compute size; bumping to a larger Cloud compute tier raises the cap.
Connections are pooled by default via PgBouncer. The "connections" number above is the pool size; thousands of concurrent clients can share it because each query takes only milliseconds.
Where to next
- Authentication — wiring
auth.uid()into your queries - Realtime — subscriptions, presence, and broadcast
- Edge Functions — server-side code with service-role access
- Storage — file uploads paired with database rows