Docs / Databases
Databases: connecting and working with data
Four databases can be connected to a project: PostgreSQL, MongoDB, Redis and Chroma. The platform creates the database and the user and adds the connection string to the project’s variables.
Below, step by step: connecting, code for popular languages, import, access from your computer, backups, the in-browser studio and managing databases through an AI assistant.
Available databases
| Database | Use it for | Variables | Backups | Outside access |
|---|---|---|---|---|
| PostgreSQL 17 | The app’s main data: users, orders, content | DATABASE_URL | Nightly, kept for 3 days; on demand with a button; copies to your own S3 or WebDAV | By IP whitelist |
| MongoDB 7 | JSON documents without a fixed schema | MONGODB_URI, MONGO_URL | No | No, team apps only |
| Redis 7 | Cache, sessions, queues, pub/sub | REDIS_URL | No: keep cache and queues in it | No, team apps only |
| Chroma 1.5 | Vector search for RAG and AI agent memory | CHROMA_URL, CHROMA_TOKEN and 4 more | No | No, team apps only |
All databases run on the same server pool as the app, on the internal network: latency is minimal and they aren’t visible from the internet. Every project gets its own database and its own user or token, so team projects can’t see each other’s data. The exception is Redis: there is one per team.
Connect a database to a project
- 1
Open the project and the Databases tab
All databases connected to the project are here, each on its own sub-tab. - 2
Click + Add database and pick one
The first MongoDB or Chroma connection in a team starts the team container — it takes up to a couple of minutes. - 3
Check the variables
The connection string is already on the Variables tab:DATABASE_URL,MONGODB_URI,REDIS_URLorCHROMA_*. No need to type it in. - 4
Click Redeploy
The app restarts and reads the new variables. With no new commits there is no rebuild — the current build restarts. - 5
Open the data in the studio
The Databases menu item → project → database. See Database studio.
Read the connection string from the environment
Don’t copy the password into code or into a committed .env. The app reads the string from an environment variable, so it updates by itself when you reset the password or turn on connection pooling.
PostgreSQL
PostgreSQL 17. The platform creates the team cluster, a separate database and user for the project inside it, encrypts the password and adds DATABASE_URL to the variables. It is a plain string — postgresql://user:password@host:5432/database — so Prisma, Drizzle, TypeORM, Sequelize, SQLAlchemy, Django ORM and Laravel work with no extra setup.
Prisma
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}The build runs prisma generate. There are two ways to apply the schema:
- turn on Build with DB access in the Databases tab → PostgreSQL — the build then runs
prisma db push, and Next.js withgenerateStaticParamscan reach the database; - or run migrations when the app starts:
{
"scripts": {
"build": "prisma generate && next build",
"start": "prisma migrate deploy && next start"
}
}Node.js — pg driver
import pg from "pg";
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
const { rows } = await pool.query(
"SELECT id, email FROM users WHERE created_at > $1",
[new Date("2026-01-01")],
);Python — psycopg and SQLAlchemy
import os
import psycopg
with psycopg.connect(os.environ["DATABASE_URL"]) as conn:
print(conn.execute("SELECT now()").fetchone())
# SQLAlchemy: the same address with the driver in the scheme
from sqlalchemy import create_engine
engine = create_engine(os.environ["DATABASE_URL"].replace("postgresql://", "postgresql+psycopg://", 1))What else the PostgreSQL tab has
- Reset password — the old password stops working at once, the new one goes into the project variables and the app restarts.
- Build with DB access — the build runs on the same network as the database:
prisma db pushand static pages generated from the database. - Restore from files (.sql / .dump) — load a dump into the project database.
- DataLens — a link with a token for Yandex DataLens dashboards, details.
- Branch previews can get their own database: schema only or schema with data, details.
Import from Neon, Supabase, Railway and Vercel Postgres
- 1
Create PostgreSQL in the project
If the variables already had aDATABASE_URL, it is kept asOLD_DATABASE_URL, and the new database takes its place. - 2
Open the “Import from external database” block
The old string is filled in automatically. You can use it as is, Neon pooler included: no need to look for DIRECT_URL or a non-pooled address. - 3
Click Start Import
The platform takes a dump of the old database and restores the schema and data into the new one. - 4
Check the data and redeploy
Look at the tables in the studio, then removeOLD_DATABASE_URLand other old connection strings from the variables.
On Vercel every function lives on its own; here the app is one long-running process. Serverless client settings like max: 1 and prepare: false aren’t needed: with a regular pool, queries run in parallel.
Access from your computer: DBeaver, psql, prisma db push
The database port is closed to the outside by default. To connect from your computer, CI or a cloud IDE:
- 1
Find your public IP
On a computer — any “what is my IP” site (with a VPN on, the address is different). In Codespaces, Project IDX, CI and a terminal —curl ifconfig.me. - 2
Open the DB Access tab
Add the IP to the whitelist and turn external access on. Only addresses on the list can connect. - 3
Copy the connection address
The dashboard shows the external host and port. The user, password and database name are the same as in DATABASE_URL.
# Check from a terminal
psql "postgresql://USER:PASSWORD@HOST:PORT/DATABASE" -c "select version();"
# Prisma schema from your computer
DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE" npx prisma db pushYou need access only for a while — close the port when you’re done. Without a whitelist the database isn’t visible from the internet.
PgBouncer connection pool
As traffic grows, so does the number of PostgreSQL connections, and with it latency and timeouts. PgBouncer accepts all connections and hands them a limited number of real database connections. Turn it on and tune it on the PostgreSQL tab — the string in the variables updates by itself.
| FREE | PRO | BUSINESS | |
|---|---|---|---|
| Clients through the pool | 100 | 400 | ∞ |
| Database connections | 50 | 200 | 5,000 |
| Wait for a free connection | 20 s | 30 s | 60 s |
PostgreSQL backups
- Automatic. Copies are taken every night and kept for 3 days.
- On demand. Backups tab → Create backup — before a migration or a big import.
- To your own storage. Backups → “Your own storage”: any S3-compatible storage (AWS S3, Cloudflare R2, Backblaze B2, MinIO and others) or a cloud drive over WebDAV (Nextcloud and others). A copy goes there every 3, 6, 12 or 24 hours, old ones are removed after the retention period. The storage must be private: without keys neither the listing nor the files may open, otherwise the setting isn’t saved.
- Restore. Copies are
pg_dumpdumps (.dump) and load back with Restore from files.
MongoDB
MongoDB 7. One container per team; every project gets its own database and a user with access to it only. The variables get MONGODB_URI and MONGO_URL — the names Mongoose, Railway templates and most examples use. The database name is already in the string, no need to pass it separately.
Mongoose
import mongoose from "mongoose";
await mongoose.connect(process.env.MONGODB_URI);
const Order = mongoose.model("Order", new mongoose.Schema({
total: Number,
status: { type: String, default: "new" },
}, { timestamps: true }));
await Order.create({ total: 990 });
const fresh = await Order.find({ status: "new" }).sort({ createdAt: -1 }).limit(20);Official mongodb driver
import { MongoClient } from "mongodb";
const client = new MongoClient(process.env.MONGODB_URI);
const db = client.db(); // the project database, from the connection string
await db.collection("orders").insertOne({ total: 990, status: "new" });
await db.collection("orders").createIndex({ status: 1 });Python — PyMongo
import os
from pymongo import MongoClient
db = MongoClient(os.environ["MONGODB_URI"]).get_default_database()
db.orders.insert_one({"total": 990, "status": "new"})
print(db.orders.count_documents({"status": "new"}))- The MongoDB port isn’t open to the outside: Compass and mongosh on your computer won’t connect. View and edit documents in the studio.
- Disconnecting MongoDB deletes the project database with its data. Deleting the project deletes it too.
- There are no automatic MongoDB backups: export important data from your app or a background job to your own storage.
- Moving a project with MongoDB to another server isn’t supported yet, and a project copy (environment) is created without it.
Redis
Redis 7, available on all plans. One password-protected instance per team: the team’s bot, API and worker can share a queue or a cache. 512 MB of memory with the allkeys-lru policy — when it fills up, the least recently used keys are evicted. The string is in REDIS_URL.
Separate keys with prefixes
Redis is shared by the team’s projects. Start keys with the project name: shop:cart:42, bot:session:1001.
Node.js — redis and BullMQ
import { createClient } from "redis";
const redis = createClient({ url: process.env.REDIS_URL });
await redis.connect();
await redis.set("shop:greeting", "hello", { EX: 60 });
// A BullMQ job queue (ioredis)
import { Queue, Worker } from "bullmq";
import IORedis from "ioredis";
const connection = new IORedis(process.env.REDIS_URL, { maxRetriesPerRequest: null });
const emails = new Queue("shop-emails", { connection });
await emails.add("welcome", { to: "user@example.com" });
new Worker("shop-emails", async (job) => { /* send the email */ }, { connection });Python — redis-py
import os, redis
r = redis.Redis.from_url(os.environ["REDIS_URL"], decode_responses=True)
r.set("bot:last_update", "12345", ex=3600)
print(r.get("bot:last_update"))Socket.io with several replicas
import { createAdapter } from "@socket.io/redis-adapter";
import { createClient } from "redis";
const pub = createClient({ url: process.env.REDIS_URL });
const sub = pub.duplicate();
await Promise.all([pub.connect(), sub.connect()]);
io.adapter(createAdapter(pub, sub));Redis saves a snapshot to disk from time to time, so it usually survives a restart. Still, keep cache, sessions and queues in it, not the only copy of your data.
Chroma — a vector database for RAG
Chroma stores embeddings — numeric representations of text — and finds records by meaning. That is what RAG is built on: a bot or an AI agent first pulls matching passages of your docs from the database and only then answers. The version is Chroma 1.5 with API v2.
One Chroma server per team; a project gets its own database and its own token, and another project’s token won’t work with it. The variables are CHROMA_URL, CHROMA_HOST, CHROMA_PORT, CHROMA_TOKEN, CHROMA_TENANT and CHROMA_DATABASE. Send the token in the x-chroma-token or Authorization: Bearer header.
Python — chromadb
import os, chromadb
client = chromadb.HttpClient(
host=os.environ["CHROMA_HOST"], port=int(os.environ["CHROMA_PORT"]),
headers={"x-chroma-token": os.environ["CHROMA_TOKEN"]},
tenant=os.environ["CHROMA_TENANT"], database=os.environ["CHROMA_DATABASE"],
)
docs = client.get_or_create_collection("docs")
docs.add(
ids=["faq-1", "faq-2"],
documents=["Returns are accepted within 14 days", "Orders ship the next business day"],
metadatas=[{"source": "faq"}, {"source": "faq"}],
)
print(docs.query(query_texts=["how do I return an order"], n_results=2))JavaScript — chromadb
import { ChromaClient } from "chromadb";
const client = new ChromaClient({
path: process.env.CHROMA_URL,
headers: { "x-chroma-token": process.env.CHROMA_TOKEN },
tenant: process.env.CHROMA_TENANT,
database: process.env.CHROMA_DATABASE,
});
const docs = await client.getOrCreateCollection({ name: "docs" });- Your app computes the embeddings: with the chromadb client’s built-in model or with ready vectors from OpenAI or your own model.
- LangChain and LlamaIndex connect over HTTP with the same host, port, token header, tenant and database.
- Disconnecting deletes the project database with all its collections; the token stops working at once.
- There are no automatic backups: keep the source documents in your main database or storage — you can always rebuild the collection from them.
Database studio
Your project data right in the browser — no DBeaver, external access or connection strings. Works on a phone too.
- 1
Open the Databases menu item
Or the project’s Databases tab → “Studio: tables and queries”. The address can be bookmarked:/db?project=name&engine=postgres. - 2
Pick a project at the top
The list has the projects of all your teams, those with databases first. - 3
Switch the database
PostgreSQL, MongoDB, Redis or Chroma — whichever are connected to the project.
| Database | What you can do |
|---|---|
| PostgreSQL | Tables with data, sorting and paging, column structure. Rows with a primary key can be edited, added and deleted. An SQL editor with highlighting, table hints, history and CSV export; run with Ctrl+Enter. |
| MongoDB | Collections with document counts, search by filter and sort — in JSON or mongosh style: { status: "paid" }, ObjectId("…"). Edit, add and delete documents, aggregation pipelines, indexes. |
| Redis | Keys by pattern with type and TTL, values by type: string, hash, list, set, sorted set, stream. A command console with history. |
| Chroma | Collections with record counts and the records themselves: id, text and metadata. |
- The studio is open to the team’s Owners and Editors: it shows and changes data.
- Queries run as the project database user, not as an administrator. Other team databases and server files are out of reach.
- SQL with several statements runs in one transaction: on error, the changes are rolled back. The limit is 60 seconds, with up to 1,000 rows per result.
- The Redis console blocks server configuration, replication and subscription commands: CONFIG, MONITOR, SUBSCRIBE and the like.
-- Example: the 10 latest orders over 1,000
SELECT id, email, total, created_at
FROM orders
WHERE total > 1000
ORDER BY created_at DESC
LIMIT 10;Databases over MCP: Claude, Claude Code, Codex
An AI assistant can connect a database to a project, look at the schema, run a query or fix data on its own. The MCP server lives at https://relaxnet.pro/api/mcp; the account, projects and databases are the same as in the dashboard.
Connecting
- 1
Sign in to relaxnet.pro
With the account you use for your projects. - 2
Add the connector
Claude — Settings → Connectors → “Add custom connector”, addresshttps://relaxnet.pro/api/mcp. Claude Code and Codex — with the commands below. - 3
Allow access
The assistant opens sign-in on relaxnet.pro and asks for consent. In your relaxnet.pro profile you can revoke access or make it read-only — the assistant then sees only the read tools.
# Claude Code: then /mcp and sign in in the browser
claude mcp add --transport http relaxnet https://relaxnet.pro/api/mcp
# Codex: add the server and sign in, then open a new chat
codex mcp add relaxnet --url https://relaxnet.pro/api/mcp
codex mcp login relaxnetIf the connector was added earlier, disconnect it and connect again: the MongoDB, Redis and Chroma tools appear after the new consent.
Tools
| Tool | What it does |
|---|---|
databases | Which databases are connected to the project: host, database name, variables. No passwords or tokens. |
database_connect | Connects PostgreSQL, MongoDB, Redis or Chroma — like the + Add database button. |
db_info | PostgreSQL: database size and tables with row counts; for a table — columns, indexes and constraints. |
db_query | PostgreSQL: one read-only statement, up to 200 rows, 20 seconds. |
db_execute | PostgreSQL: changes and migrations; several statements run in one transaction, 60 seconds. |
mongo_query | MongoDB: collections, find, count, aggregations, indexes. |
mongo_write | MongoDB: insert, update, replace and delete documents, create and drop collections. |
redis_keys, redis_get | Redis: keys by pattern with type and TTL, a key’s value. |
redis_command | Redis: one command as in redis-cli. Server commands are blocked. |
chroma_collections, chroma_get | Chroma: collections and records filtered by metadata, text and ids. |
What to ask the assistant
Connect MongoDB to the shop project, redeploy it and check that the app is up.
Show the structure of the orders table in the shop project and count orders by status for October.
Add a phone column (text, nullable) to the users table. Show me the SQL first.
Find session:* keys without a TTL in the bot project's Redis and set a 1-day TTL on them.
How many records are in the docs collection in the support project's Chroma, and which source values do they have in metadata?- Data is available only to Owners and Editors of the project’s team.
- The server instructions tell the assistant to check the schema before changes and to confirm destructive requests with you: DROP, DELETE and UPDATE without WHERE, FLUSHDB, dropping collections.
- The assistant never gets database passwords or tokens — only variable names.
More about the connector — Claude, Codex and MCP and AI agents in the docs.
FAQ
DATABASE_URL is there, but the app doesn’t see it+
Variables reach the app when it starts. After connecting a database, click Redeploy: if there are no new commits, the platform restarts the current build with the new variables.
The app can’t connect from my machine: ECONNREFUSED or a timeout+
The database runs on a private network next to the app and is closed to the outside. To connect from your computer, open an external port on the DB Access tab and add your IP to the whitelist.
prisma db push from Codespaces or CI can’t reach the database+
A cloud environment has its own public IP, different from your computer’s. Find it with curl ifconfig.me and add it to the whitelist on the DB Access tab.
Can one project have several databases?+
Yes. PostgreSQL, MongoDB, Redis and Chroma can all be connected to the same project; each gets its own sub-tab in the Databases tab.
Redis keys from one project got mixed with another project’s+
There is one Redis per team, shared by all team projects. Prefix keys with the project name, for example shop:cart:42, and search by the pattern shop:*.
How do I back up MongoDB or Chroma?+
The platform takes nightly backups of PostgreSQL. For MongoDB, export important data from your app or a background job to your own storage. For Chroma, keep the source documents in your main database or storage: you can always rebuild the collection from them.
Who sees the data in the studio and over MCP?+
Owners and Editors of the project’s team. Team Viewers don’t see data. Queries run with the project database’s permissions, not as an administrator.