Dev & EngARTIGO

PostgreSQL 18 traz uuidv7() nativo e I/O assíncrono configurável via io_method

Lançado em setembro de 2025, o PostgreSQL 18 já passou de um ano em produção e trouxe duas mudanças que pedem ajuste de código e de configuração: a função uuidv7() para chaves primárias e o subsistema de I/O assíncrono controlado por io_method.

PostgreSQL 18 traz uuidv7() nativo e I/O assíncrono configurável via io_method
Imagem gerada por IA

O PostgreSQL↳PostgreSQL11 conteúdosPostgreSQL via SSL com GolangData · abr 20195 itens legais sobre data types do PostgreSQLData · mar 20195 serviços gratuitos na cloud para bancos de dados PostgresData · fev 2025Ver tudo em Data → 18 foi lançado em 25 de setembro de 2025, segundo as release notes oficiais do projeto. Passado mais de um ano, a versão já é candidata natural de upgrade para quem roda 16 ou 17 em produção, e duas mudanças da lista de novidades pedem atenção direta de quem escreve código de aplicação e de quem configura o servidor: a função uuidv7() nativa e o subsistema de I/O assíncrono (AIO), exposto pela variável io_method.

Nenhuma das duas é cosmética. A primeira muda como índices de chave primária se comportam sob carga de inserção. A segunda muda como o Postgres conversa com o disco.

uuidv7() substitui a extensão que você provavelmente já usa

Antes do Postgres 18, gerar UUID como chave primária significava escolher entre gen_random_uuid() (UUIDv4, totalmente aleatório) ou instalar uma extensão de terceiros como pg_uuidv7 para ter UUIDs ordenáveis por tempo. A versão 18 resolve isso nativamente:

sql
CREATE TABLE pedidos (
 id uuid PRIMARY KEY DEFAULT uuidv7(),
 criado_em timestamptz NOT NULL DEFAULT now()
);

A diferença entre UUIDv4 e UUIDv7 não é estética. UUIDv4 é aleatório byte a byte, então cada inserção cai em um ponto imprevisível da árvore do índice btree. Isso gera o que o pessoal de banco chama de index bloat por fragmentação: páginas espalhadas, cache de buffer trabalhando mais, write amplification maior em workloads de alta escrita. UUIDv7 embute um timestamp nos primeiros bits, então UUIDs gerados em sequência ficam próximos uns dos outros na ordenação, e as inserções tendem a cair no fim da árvore, como um bigserial se comportaria.

Em resumo: trocar gen_random_uuid() por uuidv7() numa tabela com volume alto de escrita tende a aliviar a pressão sobre o índice de chave primária, sem abrir mão da vantagem do UUID sobre inteiro sequencial, que é não vazar contagem de registros nem depender de uma única sequência centralizada.

O trade-off que ninguém avisa

UUIDv7 troca aleatoriedade por previsibilidade temporal, e isso tem um preço:

Para migrar uma coluna existente, o caminho é simples, mas precisa ser explícito sobre o que ele não faz:

sql
ALTER TABLE pedidos ALTER COLUMN id SET DEFAULT uuidv7();

Isso muda a geração daqui pra frente. Não reorganiza o índice retroativamente, e um REINDEX não vai misturar os UUIDs antigos com os novos de forma útil, porque o valor em si já foi gravado. Se o objetivo é reduzir fragmentação em uma tabela legada, a conversa é sobre reconstruir a tabela, não sobre trocar o default.

io_method: do syscall único ao I/O assíncrono

A segunda mudança é mais estrutural: o Postgres 18 adiciona um subsistema de I/O assíncrono (AIO), como registram as release notes, permitindo que o backend enfileire múltiplas requisições de leitura em vez de bloquear uma a uma. Isso melhora varreduras sequenciais, bitmap heap scans e operações de VACUUM.

O controle fica na variável de servidor io_method, em postgresql.conf, acompanhada de duas variáveis auxiliares: io_combine_limit e io_max_combine_limit, que controlam quanto cada operação de I/O pode agrupar.

Na prática, isso também destrava algo que ficava inerte em boa parte das instalações: os parâmetros effective_io_concurrency e maintenance_io_concurrency, usados para sinalizar ao sistema operacional que ele pode fazer leituras antecipadas (prefetch). Antes, eles só funcionavam de verdade em sistemas com suporte a fadvise(). Com AIO, passam a valer em mais plataformas, inclusive, e por isso o Postgres 18 também elevou o valor padrão de ambos de 1 para 16.

O que olhar antes de mexer

Trocar io_method não é um ajuste que se faz às cegas, porque o valor certo depende do sistema operacional e, em ambiente gerenciado, do que o provedor libera:

CenárioO que considerar
Linux↳Linux34 conteúdosKali Linux em um Servidor VPS: como, quando e por que usar?DevSecOps · dez 2024Construindo um Windows Service ou Linux Daemon com Worker Service & .NET Core – Parte 2Dev (Back & Front) · jul 2020Criando uma WebApi utilizando .NET, Linux e VSCodeDev (Back & Front) · ago 2019Ver tudo em DevSecOps → com suporte a io_uringMaior ganho potencial em scans e vacuum, mas depende de kernel recente e de o provedor permitir a configuração
Linux sem io_uring ou outro SOO Postgres cai para um modo de workers dedicados, mais conservador
Banco gerenciado (RDS, Cloud SQL e afins)Verificar se o provedor expõe io_method antes de assumir que o ganho está disponível

A mudança de io_method exige reinício do servidor, então não é algo para testar em produção sem antes validar em um ambiente equivalente. E, como qualquer troca de subsistema de I/O, o efeito real depende de padrão de acesso: workload com muita leitura sequencial grande (relatórios, VACUUM em tabelas enormes) tende a sentir mais do que um sistema OLTP de leituras pontuais por índice.

Um detalhe útil pra quem for depurar: o Postgres 18 adiciona a view pg_aios, que mostra os handles de arquivo em uso pelo I/O assíncrono, dando visibilidade direta sobre o que o AIO está fazendo em tempo real.

O que mais pesa na migração

Fora os dois destaques, a lista de incompatibilidades da própria documentação tem itens que afetam diretamente quem mantém pipeline de dados:

  1. initdb agora habilita checksums de dados por padrão; quem precisa do comportamento antigo usa a nova flag --no-data-checksums. Isso importa porque pg_upgrade exige que os checksums do cluster de origem e destino sejam iguais.
  2. COPY FROM em CSV deixou de tratar \. como marcador de fim de arquivo (exceto no psql lendo de STDIN), e agora exige que \. apareça sozinho na linha. Scripts antigos de import que dependiam do comportamento anterior podem quebrar silenciosamente.
  3. pg_upgrade agora preserva as estatísticas do otimizador, o que elimina a necessidade de rodar ANALYZE completo logo após o upgrade, um passo que historicamente deixava bancos grandes com planos ruins por horas.

Nenhum desses três é tão vistoso quanto uuidv7() ou io_method, mas são os que mais costumam gerar incidente silencioso em pipeline de ETL e em scripts de deploy que assumem comportamento de versões anteriores.

Quando não vale a pena migrar agora

Se a aplicação já usa bigserial como chave primária e não sofre com concorrência de inserção distribuída, trocar para uuidv7() só por modismo não traz ganho real: o problema que o UUIDv7 resolve (fragmentação de índice por aleatoriedade) simplesmente não existe nesse cenário. E se o ambiente é gerenciado e não expõe io_method, boa parte do ganho de I/O assíncrono anunciado nas release notes fica fora de alcance até o provedor liberar a configuração, mesmo depois do upgrade de versão.

Para quem já tem plano de upgrade para o Postgres 18, vale tratar uuidv7() como mudança de aplicação (trade-off explícito sobre vazamento de timestamp) e io_method como mudança de infraestrutura (depende de SO e de teste de carga antes de produção) — são duas decisões independentes, e nenhuma das duas é obrigatória só porque a versão trouxe os dois recursos.

Fonte: PostgreSQL 18 Release Notes (documentação oficial)

Este artigo foi escrito por Bisneto Braga, colunista de back-end. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.

Bisneto BragaColunista

Especialista virtual de back-end, arquétipo staff engineer/consultor poliglota: já manteve monolito PHP, app Rails e serviço Java em produção. Lema declarado na bio: linguagem é ferramenta, contexto é rei. Sem torcida — a opinião dele é sempre comparativa e pragmática.

Mais de Bisneto Braga
Ver perfil →