De tempos em tempos alguém posta "Just Use Postgres" na internet e a resposta habitual é um misto de concordância tímida e "depende". Em 2026, o "depende" encolheu bastante. O PostgreSQL 18, lançado em setembro de 2025, trouxe async I/O com io_uring, UUIDv7 nativo e melhorias de performance que fecham gaps que antes justificavam bancos especializados.
Não estou dizendo que você deve deletar seu Redis amanhã. Estou dizendo que a pergunta mudou. Antes era "qual banco especializado usar para cada caso?" e agora é "preciso mesmo de mais um banco ou o Postgres resolve?". Neste post, passo pelos casos concretos: caching, documentos, busca vetorial e full-text search. Com código.
O que o PostgreSQL 18 trouxe de novo
O PostgreSQL 18 foi lançado em 25 de setembro de 2025. A versão mais recente é a 18.3, de fevereiro de 2026. As novidades que mais impactam a tese "Just Use Postgres":
O novo subsistema de I/O assíncrono melhora performance de sequential scans, bitmap heap scans e vacuum. Em benchmarks, os ganhos chegam a 3x em cenários específicos. O parâmetro io_method permite escolher entre worker, io_uring e o comportamento síncrono tradicional via sync.
A função uuidv7() gera UUIDs ordenados por timestamp. Isso resolve um problema antigo: UUIDs v4 aleatórios fragmentam indexes B-tree. Com UUIDv7, inserções sequenciais mantêm a localidade dos dados no disco.
-- UUIDv7: ordenado por timestamp, ideal para chaves primárias
SELECT uuidv7();
-- Resultado: 019576a2-cc52-7b08-8500-4b5f3e2a1d0f
-- Comparação: UUIDv4 continua aleatório
SELECT gen_random_uuid();
-- Resultado: f47ac10b-58cc-4372-a567-0e02b2c3d479
Outras novidades relevantes: skip scan para indexes B-tree multicoluna (o otimizador agora pula prefixos de colunas), virtual generated columns computadas na leitura (agora o padrão para colunas geradas), e suporte a autenticação OAuth.
Caching: UNLOGGED tables no lugar do Redis
O caso de uso mais comum do Redis é cache. Gravar dados temporários com TTL e ler com latência mínima. O PostgreSQL faz isso com UNLOGGED tables.
Tabelas UNLOGGED não geram WAL (Write Ahead Log). O resultado: escrita cerca de 2x mais rápida que tabelas normais. O trade-off é que os dados se perdem em caso de crash do servidor. Para cache, isso é aceitável por definição.
CREATE UNLOGGED TABLE cache (
key TEXT PRIMARY KEY,
value JSONB NOT NULL,
expires_at TIMESTAMPTZ NOT NULL DEFAULT now() + INTERVAL '1 hour'
);
-- Inserir ou atualizar cache
INSERT INTO cache (key, value, expires_at)
VALUES (
'user:42:profile',
'{"name": "Ana", "role": "admin"}'::jsonb,
now() + INTERVAL '30 minutes'
)
ON CONFLICT (key) DO UPDATE
SET value = EXCLUDED.value, expires_at = EXCLUDED.expires_at;
-- Ler do cache (ignorando expirados)
SELECT value FROM cache
WHERE key = 'user:42:profile' AND expires_at > now();
-- Limpar expirados periodicamente
DELETE FROM cache WHERE expires_at < now();
Para pub/sub, o PostgreSQL tem LISTEN/NOTIFY nativo. Para filas de trabalho, SKIP LOCKED permite implementar job queues sem contention entre workers.
O ponto fraco: latência. O Redis opera na casa de 0,1ms. O Postgres com UNLOGGED tables fica na faixa de 0,5-2ms. Para a maioria das aplicações web, essa diferença não aparece no tempo de resposta percebido pelo usuário. Para trading de alta frequência ou gaming em tempo real, Redis continua sendo a escolha certa.
O Redis 7.2 atingiu EOL em fevereiro de 2026 e o 7.4 vai em novembro. Se você está planejando migrar de versão de qualquer forma, vale avaliar se o Postgres cobre o que você precisa. Menos um processo para monitorar, menos um backup para configurar.
Documentos: JSONB substitui MongoDB em muitos cenários
O tipo JSONB do PostgreSQL armazena documentos JSON em formato binário com suporte a indexação. Com GIN indexes, queries de containment (@>) são rápidas. Com jsonpath, disponível desde o PostgreSQL 12, você tem consultas expressivas sobre estruturas aninhadas.
CREATE TABLE products (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
data JSONB NOT NULL
);
CREATE INDEX idx_products_data ON products USING GIN (data);
INSERT INTO products (data) VALUES (
'{"name": "Teclado Mecânico", "price": 299.90, "tags": ["periferico", "gaming"], "specs": {"switches": "Cherry MX Brown", "layout": "ABNT2"}}'
::jsonb);
-- Query com jsonpath
SELECT data FROM products
WHERE data @? '$.tags[*] ? (@ == "gaming")';
-- Combinando JSON com SQL
SELECT data->>'name' AS nome, (data->>'price')::numeric AS preco
FROM products
WHERE data @> '{"specs": {"switches": "Cherry MX Brown"}}'
ORDER BY preco;
Onde o MongoDB ainda ganha: volume massivo de documentos (centenas de milhões), schemas que mudam com frequência sem previsibilidade, e workloads puramente de leitura por chave primária sem joins. Para o cenário comum de projetos que usam MongoDB como um banco relacional disfarçado com documentos JSON, o Postgres com JSONB faz o mesmo trabalho com SQL completo à disposição.
Busca vetorial: pgvector compete com Pinecone
Com a extensão pgvector, o PostgreSQL armazena e consulta embeddings vetoriais. A combinação pgvector + pgvectorscale (da Timescale) entrega, em benchmarks de 2026, 1,4x menor latência p95 e 1,5x maior throughput em comparação com o Pinecone, a 79% menos custo quando self-hosted na AWS.
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE documents (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
content TEXT NOT NULL,
embedding vector(1536)
);
-- Index HNSW para busca aproximada
CREATE INDEX idx_docs_embedding ON documents
USING hnsw (embedding vector_cosine_ops);
-- Busca por similaridade de cosseno
SELECT content,
1 - (embedding <=> '[0.1, 0.2, ...]'::vector) AS similarity
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, ...]'::vector
LIMIT 10;
Para datasets de até 5 milhões de vetores com volume moderado de queries (centenas por segundo), pgvector em uma instância Postgres bem dimensionada dá conta. Acima disso, ou com requisitos rígidos de latência na casa de milhares de queries por segundo, bancos vetoriais dedicados como Pinecone ou Weaviate justificam a complexidade adicional.
O ponto forte: seus vetores ficam no mesmo banco que seus dados relacionais. Uma query pode combinar busca semântica com filtros SQL tradicionais sem sincronização entre bancos.
Full-text search: tsvector cobre o básico
O PostgreSQL tem suporte nativo a full-text search via tsvector e tsquery desde a versão 8.3. Com GIN indexes, a performance é boa para volumes moderados.
ALTER TABLE products ADD COLUMN search_vector tsvector
GENERATED ALWAYS AS (
to_tsvector('portuguese', coalesce(data->>'name', '') || ' ' || coalesce(data->>'description', ''))
) STORED;
CREATE INDEX idx_search ON products USING GIN (search_vector);
SELECT data->>'name' AS nome,
ts_rank(search_vector, query) AS rank
FROM products, to_tsquery('portuguese', 'teclado & mecanico') AS query
WHERE search_vector @@ query
ORDER BY rank DESC;
Onde o Elasticsearch ainda ganha: aggregations complexas sobre texto, fuzzy matching sofisticado, busca distribuída em bilhões de documentos. Para um blog, um e-commerce médio ou busca interna de uma aplicação SaaS, o full-text search do Postgres é suficiente e elimina a necessidade de manter um cluster Elasticsearch separado.
Quando não usar só Postgres
A tese "Just Use Postgres" funciona para a maioria dos projetos. Não funciona para todos.
- Se sua aplicação precisa consistentemente de respostas abaixo de 0,5ms para cache, Redis ou Memcached continuam sendo a escolha. Postgres não compete nessa faixa.
- Se você tem centenas de milhões de documentos que mudam de estrutura frequentemente e não precisa de joins, MongoDB é mais natural.
- Acima de 5-10 milhões de vetores com milhares de queries por segundo, bancos vetoriais dedicados escalam melhor horizontalmente.
- Para busca de texto em bilhões de documentos, Elasticsearch foi construído para isso.
- Para streaming de eventos, o
LISTEN/NOTIFYdo Postgres não substitui Kafka. Ele é síncrono e não tem persistência de mensagens.
Não é que Postgres faz tudo melhor. É que faz o suficiente para que muitos projetos não precisem de 4 bancos de dados diferentes em produção. Menos infra, menos backup, menos monitoramento, menos pontos de falha.
Conclusão
O MySQL 8.0 chega ao EOL em 30 de abril de 2026 com 58% das instâncias MySQL ainda rodando essa versão. O Redis 7.2 já atingiu EOL. Se você está planejando migrações de qualquer forma, este é o momento de avaliar se consolida parte da sua stack em PostgreSQL.
O PostgreSQL 18 com async I/O, UUIDv7, UNLOGGED tables, JSONB, pgvector e full-text search nativo cobre uma faixa enorme de casos de uso que antes exigiam bancos separados. Não é a resposta para tudo, mas para um número crescente de projetos, a resposta para "qual banco usar?" é a mesma: Postgres.
O PostgreSQL 19, previsto para setembro de 2026, deve trazer Transaction IDs de 64 bits, resolvendo o problema de wraparound que existe desde as primeiras versões. Mais um motivo para quem está avaliando consolidação ficar de olho.
Referências pesquisadas nesta publicação
- PostgreSQL 18 Released! - postgresql.org
- PostgreSQL 18 New Features - Neon
- Get Excited About Postgres 18 - Crunchy Data
- I Replaced Redis with PostgreSQL (And It's Faster) - DEV Community
- It's 2026, Just Use Postgres - Tiger Data
- pgvector vs. Pinecone: Vector Database Comparison - Tiger Data
- Why we replaced Pinecone with PGVector - Confident AI
- MySQL 8.0 End of Life - Fortified Data