Regions
Where your database lives, how the region is chosen, and why it does not change afterwards.
Choosing a region
The region is picked once, when you create the project - in the dashboard's create-project flow, or via the API by listing the available regions and passing the chosen one:
curl -s -H "X-API-Key: $CAPYDB_API_KEY" \
https://capydb.dev/api/capydb/v1/regions{
"regions": ["eu-north-1"],
"region_details": [
{ "id": "eu-north-1", "display_name": "EU North", "location": "Helsinki, Finland" }
]
}regions is the plain list of ids; region_details carries the same regions, in the same order, with a display name and location. Only regions open for new projects are listed.
POST /v1/projects takes an optional region; omit it to let CapyDB pick a region with capacity. Point-in-time recovery and other capabilities are documented under Backups & restores.
Region ids
Region ids are CapyDB's own, shaped <area>-<direction>-<n>. They are the values every region field returns and every region input takes - projects, ephemeral databases, webhook and audit payloads, and the public status page.
| Id | Name | Location |
|---|---|---|
eu-north-1 | EU North | Helsinki, Finland |
An unknown region is refused with 400, and the message lists the valid ids.
Before 2026-09-30 this region's id was hel1. Existing projects were moved to eu-north-1 in place - nothing about the database or its connection strings changed. hel1 is still accepted as an input alias for eu-north-1 for one release and will then be refused, so send eu-north-1 from scripts, Terraform and CI. Responses already carry eu-north-1.
EU data residency
All database capacity today is on dedicated-vCPU servers in the EU. Your database, its preview databases, and its compute live in the region you picked. If your data-residency requirement is "EU", CapyDB satisfies it by construction rather than by configuration. If your requirement is a specific non-EU jurisdiction, we do not have a region for you today - see Security for the broader posture.
What is co-located with the project
- Preview databases are created on the same node as their project - clones stay in-region.
- Compute and storage are the same machine; there is no cross-region split to reason about.
- Backup artifacts are written to object storage off the database node (see Disaster recovery for the mechanics).
Region is fixed after creation
There is no API to move a project between regions, and the region field cannot be edited. This is deliberate honesty rather than a missing button: a "move region" toggle would really be a full data migration wearing a trench coat.
If you do need a project in a different region, the supported path is the same migration you would run between providers:
- Create a new project in the target region.
- Import from the old project's direct connection URL (run the preflight first).
- Update consumers with the new project's connection strings - they differ, since it is a new database with new credentials.
- Delete the old project when you are confident.
Latency, practically
Your database answers from its region; physics does the rest. Put latency-sensitive app servers near the region, and use the pooled endpoint so connection setup cost is paid rarely instead of per-request.
This is usually the single largest number in a slow page, and it is the cheapest one to fix. Serverless platforms default to a US function region. Against an EU database that is roughly 80-100ms per round trip, before your query does any work at all - so a page that issues four queries in sequence spends a third of a second waiting on the Atlantic while the database itself is busy for under a millisecond. Moving the functions is a config line; optimizing the queries is not.
Pin your functions to an EU region:
export const preferredRegion = 'arn1' // or 'fra1'{ "regions": ["arn1"] }arn1 (Stockholm) is the Vercel region closest to EU North (Helsinki); fra1 (Frankfurt) is a little further away and still far better than a US default. On Netlify, set the function region in the UI or netlify.toml; on Cloudflare Workers, enable Smart Placement so the worker runs near the origin it talks to rather than near the visitor. Anywhere you control the machine (a container, a VM), pick the EU location the provider offers.
Then reduce the round trips themselves: prefer one query with a join over several sequential ones, and be aware that a client pool with max: 1 makes even Promise.all serialize - see client pool size in serverless functions.
Connections
CapyDB speaks normal Postgres. One direct URL, one pooled URL, both usable from standard clients and frameworks.
Connect your framework
Connect any framework to CapyDB Postgres: Prisma, Drizzle, Node.js, Django, Rails, Laravel, Go and SQLAlchemy. Pooled URL for the app, direct URL for migrations.