# Postgres (Neon) Per-tenant Postgres database on Neon. Execute SQL over HTTP: no Postgres setup, no connection pool to manage, no credentials to rotate. Public for all tenants; existing `database` (D1/SQLite) tenants are unaffected. ## Prerequisites Edge calls require this resource to be provisioned first; unprovisioned calls return an error. ### Provision curl -s -X POST https://cohesivity.ai/api/resources/postgres \ -H "Authorization: Bearer " ### Delete curl -s -X DELETE https://cohesivity.ai/api/resources/postgres \ -H "Authorization: Bearer " Provisioning happens once, before the application runs; the running application does not provision its own resources. ## Relationship to /database This is a separate offering from `database` (SQLite/D1). Both can coexist on the same tenant. `database` and `postgres` have different SQL dialects, different parameter placeholders, and different metrics: pick one per use case. - `database` (D1/SQLite): rows-based billing, `?` placeholders, edge-colocated, single-threaded writer, ~10 GB hard cap. - `postgres` (Neon): compute/storage/transfer billing, `$1` placeholders, regional, autoscaling compute, per-tier storage ceiling. Realtime and social-login auto-provision `database` for their event tables and continue to do so independent of whether the tenant has provisioned `postgres`. Inbox auto-provisions `postgres` when needed and stores normalized mail in the reserved `coh_inbox` schema. Postgres teardown returns `409 inbox_requires_postgres` until Inbox teardown completes. ## SQL Dialect This is **PostgreSQL**, not SQLite. Key differences from `database`: - `BIGSERIAL` or `GENERATED ALWAYS AS IDENTITY` replaces `INTEGER PRIMARY KEY AUTOINCREMENT` - Parameter placeholders are `$1`, `$2`, ..., not `?` or `?1` - `TIMESTAMPTZ`, `JSONB`, `TEXT[]`, `ILIKE` all available - `NOW()` works in DEFAULT clauses - One statement per `query` string; multi-statement SQL in a single string is not supported. Running several statements in one request requires a batch (`statements`, see Edge Usage below) ## Edge Usage - **Base URL:** https://cohesivity.ai/edge/postgres - **Recommended auth:** `POST https://cohesivity.ai/edge/session?key=` → `Authorization: Bearer ` - **Fallback auth:** `?key=` query parameter - **Method:** POST with a JSON body in one of two forms: sending both `query` and `statements` is a 400: - **Single:** `{ "query": "SQL", "params": [...] }` → `{ "rows": [...], "rowCount": N }` - **Batch:** `{ "statements": [{ "query": "SQL", "params": [...] }, ...] }` → `{ "results": [{ "rows": [...], "rowCount": N }, ...] }`, one result per statement in submission order - `rowCount` is the real affected-row count for INSERT/UPDATE/DELETE - A result that hits the row cap carries `"truncated": true` (see Limits below) ## Batches - All statements in a batch run in a **single atomic transaction** in one round-trip. On any failure the whole batch rolls back: nothing is applied, and the error does not identify which statement failed - Transaction-control or session statements (BEGIN/COMMIT/ROLLBACK/SAVEPOINT/RELEASE/SET/RESET) inside a batch are rejected with 400, because the batch is already a transaction - Max 50 statements per batch. **Each statement bills one postgres request**, so batch size is also bounded by the tier's per-minute request cap (e.g. 30 on ephemeral) ## Provisioning curl -s -X POST https://cohesivity.ai/api/resources/postgres \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"region":"apac"}' Accepted regions are documented in the regions block below. No beta grant is required; normal plan, quota, and Neon-region limits still apply. ## Limits - Max query length: 50,000 chars per statement - Max rows returned: 10,000 per response, cumulative across batch results: once the budget is exhausted, later slots return `rows: []` with `"truncated": true` - Max 50 statements per batch; each statement bills one postgres request against the per-minute cap - Per-tier concurrent SQL limit, statement timeout, and max compute (see Rate Limits below) - Scale-to-zero after 5 minutes of inactivity; first query after idle pays a brief cold-start cost ## Rate Limits Ephemeral tenants pause as a whole if any authoritative hard cap below is exceeded. Claimed tiers use account-scoped buckets shared across every project owned by the Cohesivity user; OpenAI, AI Gateway, Deepgram, and Exa are fluid-only after tier, rate, and concurrency checks; AI Gateway and Deepgram have no fixed monthly usage bucket for claimed tiers. **Ephemeral** - compute unit seconds: 3600 per ephemeral tenant lifetime before claim or expiry - public transfer bytes: 250 MB per ephemeral tenant lifetime before claim or expiry - written bytes: 250 MB per ephemeral tenant lifetime before claim or expiry - live storage: 100 MB max total - restore gb months: 0.05 per ephemeral tenant lifetime before claim or expiry - requests: 30 per minute **Claimed Free** - live storage: 512 MB max total - requests: 120 per minute - compute unit seconds: 18000 per month - storage gb months: 1 per month - restore gb months: 0.5 per month - public transfer bytes: 5 GB per month - written bytes: 5 GB per month **Claimed Plus** - live storage: 2 GB max total - requests: 600 per minute - compute unit seconds: 90000 per month - storage gb months: 5 per month - restore gb months: 5 per month - public transfer bytes: 25 GB per month - written bytes: 50 GB per month **Claimed Pro** - live storage: 10 GB max total - requests: 3000 per minute - compute unit seconds: 540000 per month - storage gb months: 25 per month - restore gb months: 25 per month - public transfer bytes: 100 GB per month - written bytes: 250 GB per month