# Migrações

A plataforma não executa migrations por você: o **seu app** (ou uma ferramenta de migrations da sua linguagem) as aplica usando a `DATABASE_URL` entregue ([Conexão e referências](/bancos/conexao-e-referencias/)).

## Regras

- **Toda migration tem `down`** e foi testada (suba e desça em ambiente local antes do deploy).
- Mudanças destrutivas em dois passos (expand-contract): adicione o novo, migre o código, só depois remova o antigo. Nunca `DROP` ou renomeação destrutiva num passo só.
- Faça um [backup sob demanda](/bancos/backup-restore/) antes de uma migration arriscada.
- Migrations usam SQL parametrizado e a mesma conexão TLS (`sslmode=verify-full`, `ssl=true` ou `LIBSQL_URL`).
- Cota: um banco acima de `quota_mb` fica `read_only`; migration que cresce dados pode falhar por isso.

## Onde rodar

Rode as migrations na **inicialização do serviço**, antes de aceitar tráfego, de forma idempotente (a ferramenta guarda a versão aplicada). Com mais de uma instância subindo, use o lock da própria ferramenta de migrations. Se a migration falha, o app deve sair com erro: o deploy não fica `ready` e o rollback ([Rollback](/operacao/rollback/)) volta ao deploy anterior.

Atenção: o rollback do deploy **não** desfaz o schema. Se o código antigo for incompatível com a migration já aplicada, rode a `down` ou restaure um backup.

## Se algo falhar

| Sintoma | O que fazer |
|---|---|
| deploy não chega a `ready` por erro de migration | Leia o log de build/runtime ([Logs](/operacao/logs/)), corrija a migration e faça novo deploy. |
| `read_only` / erro de escrita | Cota estourada: libere espaço; volta ao normal ao baixar do limite. |
| `503 unavailable` ao conectar | Repita com backoff; o app não deve derrubar o deploy por indisponibilidade transitória do banco além do tempo de retry. |
