Extensão Database
PostgreSQL gerenciado para o seu app, com backups automáticos e zero configuração para rodar em Rails.
O que a Extensão entrega
Todo app não-estático nasce com um PostgreSQL gerenciado: banco, usuário e credencial dedicados ao app, com backups automáticos. Não é preciso subir um banco à parte nem configurar réplica — a Extensão Database já entrega isso pronto no primeiro deploy.
O primeiro banco (plano base) é
cortesia — um por time, não por app. Times com mais de um app pagam o
plano de catálogo a partir do segundo banco.
Variáveis de ambiente injetadas
O Jataí injeta duas variáveis automaticamente no app — nenhuma configuração manual é necessária.
DATABASE_URL=postgresql://usuario:senha@host:6432/banco?prepared_statements=false&pgbouncer=true
DIRECT_DATABASE_URL=postgresql://usuario:senha@host:5432/banco
DATABASE_URL é a conexão do app
e passa por um pooler de conexões (por isso a porta
6432). No modo transaction do
pooler, prepared statements não funcionam, e a URL carrega o parâmetro que desliga esse recurso em cada
ORM: prepared_statements=false é
lido pelo Active Record e pgbouncer=true
pelo Prisma. Cada um ignora o parâmetro do outro. Em Rails e em Prisma, portanto, é
zero-config. Outros drivers (node-postgres, Drizzle, psql) só precisam
consumir DATABASE_URL diretamente.
DIRECT_DATABASE_URL vai direto ao
PostgreSQL, sem pooler. Use-a só para migrações: ela consome o limite
de conexões do plano e não escala para servir requisições. O caso típico é o Prisma, que se recusa a rodar
prisma migrate por um pooler:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_DATABASE_URL")
}
Rode jatai env list
a qualquer momento para conferir o valor atual.
Migrations e comandos avulsos
Migrations (fase de release do deploy) e comandos avulsos via
jatai run não passam pelo pooler:
a plataforma troca, só nesses processos, a
DATABASE_URL por uma conexão
direta ao banco. Isso é transparente ao cliente — não é preciso configurar nada — e evita erros de lock
em migrations concorrentes que o modo transaction do pooler causaria. Apps que rodam migrações na
subida do próprio container (fora da fase de release) devem apontá-las para
DIRECT_DATABASE_URL.
Planos
O plano define o limite de armazenamento e o número máximo de conexões simultâneas do banco.
| Plano | Armazenamento | Conexões | Preço |
|---|---|---|---|
base |
512 MB | 20 | R$ 19/mês (cortesia no 1º banco do time) |
escala_1 |
1 GB | 50 | R$ 29/mês |
escala_2 |
5 GB | 100 | R$ 119/mês |
Comportamento de quota
Ao ultrapassar o armazenamento do plano contratado (com uma pequena margem de tolerância), a
plataforma revoga apenas escrita: o usuário do app perde a
permissão de INSERT e
UPDATE. Leitura e
DELETE continuam funcionando
normalmente, então dá para liberar espaço apagando dados sem precisar de suporte.
Assim que o uso volta a ficar abaixo do limite do plano, a escrita é restaurada automaticamente — sem intervenção manual.