Category

Artigos

Os Pilares Tecnológicos: Do Suporte à Sustentabilidade

By Artigos

A evolução da gestão de dados não depende apenas de uma mudança de mentalidade. Para sair de uma atuação predominantemente operacional e assumir um papel mais estratégico, o profissional também precisa transformar a forma como trabalha e as tecnologias que utiliza.

Durante muito tempo, administrar um banco de dados significava acompanhar indicadores, responder a alertas e intervir manualmente sempre que algum problema aparecia. Esse modelo pode funcionar em ambientes menores ou menos complexos, mas se torna cada vez mais limitado à medida que sistemas, volumes de dados, integrações e expectativas de disponibilidade crescem.

É nesse contexto que tecnologias como observabilidade, automação, Infraestrutura como Código (IaC) e práticas de Engenharia de Confiabilidade passam a ter um papel importante.

A mudança não acontece de uma única vez. Ela pode ser entendida como uma evolução em três camadas: Suporte, Sustentação e Sustentabilidade. No Suporte, a prioridade é responder ao que está acontecendo. Na Sustentação, o objetivo é tornar a operação mais previsível e confiável. Na Sustentabilidade, o olhar se amplia para decisões que precisam continuar fazendo sentido no longo prazo.

Do monitoramento à observabilidade

Uma das primeiras mudanças acontece na forma de enxergar o ambiente. No nível operacional, o monitoramento é fundamental para identificar situações que exigem atenção. Ele pode responder perguntas como:

  • A CPU ultrapassou determinado limite?
  • O disco está próximo da capacidade máxima?
  • O número de conexões aumentou?
  • Existe alguma instância indisponível?
  • Uma query está demorando mais do que o esperado?

Esses indicadores são importantes porque ajudam a detectar eventos e reagir rapidamente. O problema é quando essa é a única visão disponível.

A observabilidade amplia essa perspectiva. Em vez de apenas identificar que algo está errado, ela ajuda a investigar por que aquilo está acontecendo e quais impactos o comportamento de um componente provoca no restante do ambiente.

Para isso, métricas, logs e rastreamentos (traces) podem ser analisados em conjunto. O comportamento do PostgreSQL pode ser relacionado, por exemplo, a um autovacuum mal configurado causando lentidão no sistema, ao inchaço inchaço (bloat) de tabelas após uma atualização na aplicação, ou então ao aumento inesperado de memória pela falta de um pooler de conexões, como o PgBouncer.

Ferramentas como Datadog, Prometheus e Grafana podem fazer parte dessa estrutura, mas a observabilidade vai além da adoção de uma ferramenta específica. Trata-se de construir uma visão integrada do ambiente. Essa mudança também aproxima a operação de outras dimensões do negócio. Um aumento de consumo de recursos não é apenas uma questão técnica: dependendo do ambiente, pode representar aumento de custos, impacto na experiência do usuário ou necessidade de rever uma decisão arquitetural.

A pergunta deixa de ser apenas: “O que quebrou?”. E passa a incluir: “Por que isso aconteceu, qual é o impacto e o que podemos aprender com esse comportamento?” Essa mudança de pergunta é fundamental para sair de uma atuação puramente reativa.

Automação e Infraestrutura como Código contra o toil

Outro obstáculo para a evolução do profissional é o excesso de trabalho manual e repetitivo. Na cultura de SRE, o termo toil é utilizado para descrever atividades operacionais manuais, repetitivas e sem valor duradouro, que tendem a crescer conforme o ambiente cresce.

Imagine, por exemplo, um profissional que precisa configurar manualmente um novo ambiente de PostgreSQL sempre que um projeto é criado. Ou que depende de scripts executados individualmente para realizar tarefas recorrentes de manutenção.

Na rotina de quem atua diretamente em um ambiente PostgreSQL, o toil pode ser identificado como: ter que executar reindex ou vacuum full manualmente durante a madrugada ou então ter que aplicar os mesmos ajustes de tuning no postgresql.conf e no pg_hba.conf a cada nova instância provisionada.

Enquanto essas atividades ocupam a maior parte da agenda, sobra pouco espaço para análise, planejamento e melhoria. É aí que entram automação e Infraestrutura como Código (IaC). Em vez de depender exclusivamente de comandos executados manualmente, o ambiente pode ser descrito em código e versionado. Tecnologias como Terraform e Ansible, por exemplo, permitem automatizar diferentes etapas da configuração e operação da infraestrutura. O benefício não está apenas em executar tarefas mais rapidamente.

A automação também contribui para:

  • Reduzir intervenções manuais;
  • Diminuir a possibilidade de erro humano;
  • Padronizar ambientes;
  • Facilitar a reprodução de configurações;
  • Registrar alterações;
  • Tornar processos mais previsíveis;
  • Liberar tempo para atividades de maior valor.

A lógica muda de: “Preciso fazer isso novamente.” para: “Como posso fazer com que isso aconteça de forma confiável sem depender de uma nova intervenção manual?” Esse é um dos movimentos que caracterizam a passagem do Suporte para a Sustentação.

Do DBRE ao DSE: quando a engenharia encontra a estratégia

A automação e a observabilidade ajudam a construir uma operação mais confiável. Mas existe outro passo importante: incorporar práticas de engenharia ao gerenciamento dos bancos de dados. É nesse contexto que surge o Database Reliability Engineering (DBRE).

Inspirado pelos princípios de SRE, o DBRE aplica práticas de Engenharia de Confiabilidade aos ambientes de banco de dados. Isso pode envolver automação, observabilidade, testes, versionamento e integração com processos de desenvolvimento e entrega.

O banco deixa de ser tratado como uma caixa preta administrada separadamente e passa a fazer parte de um fluxo de engenharia mais amplo. Configurações podem ser versionadas. Alterações podem passar por revisão. Processos podem ser automatizados. Ambientes podem ser testados antes de chegar à produção. É uma mudança importante porque transforma a confiabilidade em uma característica construída pelo processo, e não apenas em algo que depende da experiência ou da intervenção manual de uma pessoa. Mas a evolução não termina no DBRE.

Quando a confiabilidade encontra o longo prazo

O Data Sustainability Engineer (DSE) parte dessa base tecnológica para ampliar novamente o campo de visão.

O DSE precisa compreender profundamente o banco de dados, mas também precisa considerar aspectos de arquitetura, automação, segurança, conformidade, cloud, custos e necessidades do negócio.

Uma decisão arquitetural, por exemplo, não deve ser analisada apenas pela capacidade de funcionar hoje. É necessário considerar como ela se comportará diante do crescimento esperado, quais recursos serão necessários, quais riscos serão introduzidos e qual será o impacto financeiro ao longo do tempo.

Imagine uma empresa que espera triplicar o volume de acessos nos próximos anos. A pergunta não é somente se o PostgreSQL atual suporta a carga de hoje. É preciso avaliar se a arquitetura escolhida consegue acompanhar esse crescimento, quais mudanças serão necessárias e quanto custará mantê-la. É nesse ponto que a interdisciplinaridade se torna essencial.

Tecnologia como meio para uma atuação mais estratégica

Observabilidade, automação, IaC e práticas de DBRE não existem apenas para modernizar o conjunto de ferramentas utilizado pelo profissional. Elas criam as condições para uma mudança maior: reduzir o tempo gasto reagindo ao presente e aumentar a capacidade de pensar sobre o futuro. A evolução pode ser resumida assim:

Camada Principal pergunta Abordagem
Suporte O que aconteceu? Monitoramento e intervenção
Sustentação Como evitar que isso volte
a acontecer?
Observabilidade, automação e confiabilidade
Sustentabilidade Como garantir que o ambiente continue adequado no futuro? Estratégia, arquitetura, eficiência e planejamento

Isso não significa que uma camada substitui completamente a outra. Um ambiente sustentável continua precisando de monitoramento. Um profissional estratégico continua precisando conhecer profundamente a operação. A diferença está na capacidade de conectar essas dimensões e usar a tecnologia para ampliar sua atuação.

A evolução do DBA para o DSE, portanto, não acontece simplesmente pela adoção de novas ferramentas. Ela acontece quando tecnologia, processos e conhecimento técnico passam a ser utilizados para construir ambientes mais previsíveis, eficientes e preparados para acompanhar a evolução do negócio.

O próximo passo é ampliar o olhar

A tecnologia pode ajudar a tirar o profissional da rotina de intervenções manuais e criar espaço para uma atuação mais estratégica. Mas essa transformação também exige novas perguntas, novas competências e uma compreensão mais ampla sobre o papel dos dados dentro das organizações.

É justamente essa evolução que está por trás do conceito de Data Sustainability Engineer (DSE).

Quer entender como essa mudança se relaciona com a evolução da carreira de DBA e com a construção de ambientes de dados mais sustentáveis?

Leia o White Paper completo e aprofunde-se no conceito de DSE, nos pilares dessa transformação e nos caminhos para uma gestão de dados orientada ao longo prazo.

[Ler o white paper]

Quando uma função retorna texto, mas você precisa de linhas: explorando o Full Text Search no PostgreSQL

By Artigos

O Full Text Search do PostgreSQL oferece recursos para pesquisar documentos, ranquear resultados e também destacar os trechos mais relevantes de um texto. Entre essas funcionalidades está a ts_headline, que pode ser usada para gerar um resumo do conteúdo encontrado e destacar os termos que correspondem à busca.

Mas o que acontece quando você precisa de mais do que um único texto de retorno?

Imagine uma tabela de livros em que cada registro possui o conteúdo de um capítulo ou parágrafo. Ao realizar uma busca por uma determinada palavra, pode ser interessante retornar não apenas o registro encontrado, mas cada trecho relevante do conteúdo como uma linha independente.

É aí que surge uma situação interessante: a função ts_headline consegue retornar vários fragmentos, mas o resultado ainda é um único valor do tipo texto.

O papel do ts_headline

No PostgreSQL, a função ts_headline recebe um documento e uma consulta de texto e retorna um trecho do documento no qual os termos encontrados são destacados. Ela também permite configurar como esses trechos serão gerados.

Entre as opções disponíveis estão:

  • MaxWords e MinWords: Número máximo e mínimo de palavras em cada trecho exibido
  • HighlightAll: Quando True, o resultado será o trecho completo com o texto pesquisado destacado, ignorando os parâmetros acima 
  • MaxFragments: Máximo de fragmentos de texto a serem exibidos
  • FragmentDelimiter: Texto que será utilizado para separar os diferentes fragmentos no resultado (ex.: $)

Por exemplo, podemos configurar a função para retornar vários fragmentos separados pelo caractere $:

  SELECT 
    ts_headline(
        content,
        to_tsquery('english', 'happy'),
        'MaxFragments=3
         FragmentDelimiter=$'
    )
FROM mytable
WHERE ts_content @@ to_tsquery('english', 'happy');

Entendendo a Consulta:

  • content: Coluna do tipo text com o texto original não processado onde a marcação será aplicada
  • ts_content: Coluna do tipo tsvector pré-processada (GENERATED ALWAYS AS (to_tsvector(‘english’, content)) STORED), usada na cláusula WHERE. Necessário a criação de um índice GIN sobre ela (CREATE INDEX … USING gin (ts_content)), para garantir melhor desempenho nas buscas
  • to_tsquery: Converte a string informada em uma consulta estruturada (tsquery) no idioma correspondente

O resultado pode ser algo semelhante a:

Este é um fragmento com <b>happy</b>$outro fragmento com <b>happy</b>$e mais um fragmento com <b>happy</b>

Para quem precisa apenas exibir o conteúdo, isso pode ser suficiente. Mas, se a aplicação precisa trabalhar com cada fragmento individualmente, ainda existe um problema: todos eles continuam dentro de uma única string.

Transformando o texto em linhas

Uma alternativa é utilizar a função regexp_split_to_table.

Ela recebe um texto e uma expressão regular que define onde o conteúdo deve ser dividido. Diferentemente de funções que retornam um único valor, regexp_split_to_table transforma cada parte resultante da divisão em uma linha.

Como já definimos um delimitador específico para o ts_headline, podemos utilizá-lo para separar os fragmentos:

SELECT
regexp_split_to_table(
ts_headline(
content,
to_tsquery('english', 'happy'),
'MaxFragments=3
 FragmentDelimiter=$'
   ),
   '$'
)
FROM mytable WHERE ts_content @@ to_tsquery('english', 'happy');

Nesse caso, o ts_headline continua responsável por encontrar e destacar os trechos relevantes, enquanto o regexp_split_to_table transforma o resultado em múltiplas linhas.

Em vez de receber:

Este é um fragmento com <b>happy</b>$outro fragmento com <b>happy</b>$e mais um fragmento com <b>happy</b>

passamos a ter algo conceitualmente como:

Este é um fragmento com <b>happy</b>
outro fragmento com <b>happy</b>
e mais um fragmento com <b>happy</b>

Onde cada fragmento agora é apresentado em linhas.

Essa combinação é útil justamente porque cada função resolve uma parte diferente do problema: uma trabalha com a busca e a geração dos trechos relevantes, enquanto a outra reorganiza o resultado para que ele possa ser tratado como um conjunto de linhas.

Por que isso é interessante?

Esse tipo de situação aparece quando o resultado de uma função SQL não está no formato mais conveniente para o restante da consulta ou para a aplicação que vai consumir os dados.

No caso do Full Text Search, podemos pensar em três etapas:

  1. Encontrar os documentos relevantes: O operador @@ verifica se o tsvector corresponde à consulta.
  1. Gerar os fragmentos: O ts_headline utiliza a consulta para produzir trechos relevantes e destacar os termos encontrados.
  1. Transformar o resultado em linhas: O regexp_split_to_table utiliza o delimitador definido anteriormente para transformar o texto em registros individuais.

Essa separação de responsabilidades deixa a consulta mais flexível e permite que os fragmentos sejam tratados individualmente em etapas posteriores.

Um cuidado importante com ts_headline

Existe, porém, um ponto importante quando trabalhamos com essa abordagem: o custo da própria função ts_headline.

A documentação do PostgreSQL destaca que ts_headline trabalha sobre o documento original, e não simplesmente sobre o tsvector, o que pode tornar a operação custosa. Por isso, seu uso deve ser pensado com cuidado, especialmente quando existe uma quantidade grande de documentos correspondentes à consulta.

Uma estratégia comum é primeiro encontrar e ordenar os resultados relevantes e só depois aplicar a geração dos trechos aos registros que realmente serão apresentados. Dessa forma, evitamos executar o processamento de destaque em um conjunto muito maior do que o necessário.

Quando o formato do resultado também importa

Esse exemplo mostra uma característica interessante do PostgreSQL: muitas vezes, o desafio não está em encontrar uma função que faça exatamente tudo o que precisamos, mas em combinar funções que resolvem etapas diferentes do problema.

O Full Text Search já oferece os mecanismos para identificar documentos relevantes e gerar destaques. Quando precisamos transformar esse resultado em uma estrutura diferente, outras funções SQL podem entrar em cena para reorganizar os dados.

Nesse caso, ts_headline e regexp_split_to_table trabalham juntos para transformar um texto com vários fragmentos em um conjunto de linhas que pode ser manipulado individualmente.

É um exemplo simples, mas que mostra como explorar as funções nativas do PostgreSQL pode evitar processamento adicional na aplicação e resolver problemas de transformação diretamente na consulta.

Receba mais conteúdos como este!

Assine a nossa newsletter e acompanhe conteúdos técnicos, análises e discussões sobre PostgreSQL, arquitetura e engenharia de dados.

[Quero receber os próximos conteúdos]

Por que o DevOps ainda falha no dia a dia?

By Artigos

Se você acompanha a área de tecnologia, sabe que a cultura DevOps já provou o seu valor. Na teoria, o desafio de unir quem desenvolve o software e quem mantém a estrutura funcionando está resolvido.

Mas a realidade que encontramos nas empresas é bem diferente. É comum ver uma adoção apenas superficial do conceito: automatizam-se alguns processos, cria-se uma equipe isolada chamada “DevOps” e o trabalho é considerado concluído. O problema é que essa colaboração não funciona na prática sem o apoio real da gestão.

Muitas vezes, a liderança enxerga a infraestrutura apenas como um custo, e não como a base da operação. É o pensamento de “meu foco é vender, servidor é apenas gasto”. Com essa visão, para lançar produtos mais rápido, as áreas de negócio pedem para cortar o que chamam de burocracia: testes, monitoramento estruturado, configuração de ambiente e planejamento de capacidade.

O que a gestão esquece é que ignorar esses requisitos técnicos essenciais é assumir um problema futuro. Mais cedo ou mais tarde, essa falta de estrutura pode resultar em indisponibilidade no sistema, perda de produtividade, retrabalho e, principalmente, impacto direto para o negócio.

O problema real da comunicação e a falta de responsabilidade compartilhada

Na edição de 2025 da Pesquisa Postgres em Foco, mais de 71% das pessoas consideraram a comunicação em suas equipes como “boa” ou “muito boa”. Mas, ao compararmos esse dado com a realidade dos nossos atendimentos, fica claro que a eficiência de uma comunicação não se mede apenas pela percepção do time, mas pelos resultados que ela gera na operação.

Existe uma ideia falsa de que apenas enviar um aviso resolve a comunicação. Uma pessoa do time de desenvolvimento atualiza um sistema importante na sexta-feira no fim do dia, manda uma mensagem no chat e sai de folga. O deploy da nova versão é lançado. Se o banco de dados falhar na madrugada de sábado, a equipe de infraestrutura fica sozinha para descobrir o erro.

Essa falta de retorno mostra que não existe uma responsabilidade compartilhada sobre o que vai para o ar. O problema não está necessariamente em quem fez o deploy ou em quem estava de plantão. Está no processo que permite que uma mudança importante aconteça sem que as pessoas responsáveis pela operação tenham contexto suficiente para acompanhar seus impactos.

Se a comunicação direta apresenta falhas, o monitoramento dos sistemas deveria servir como o ponto de alinhamento entre as equipes. No entanto, é muito comum encontrarmos painéis de acompanhamento que mostram que tudo está bem na infraestrutura, quando na verdade o cliente está enfrentando problemas.

A equipe de TI olha para as métricas, vê que o uso de processador e memória do banco de dados está normal e afirma que o sistema está saudável. Enquanto isso, na ponta da operação, o cliente está levando 8 segundos para conseguir finalizar uma compra no site.

Ferramentas de monitoramento isoladas da realidade da empresa não ajudam a operação. O monitoramento precisa conectar o que é crítico para o negócio, como o tempo exato para emitir um boleto, até o detalhe mais técnico no banco de dados. Sem essa visão completa, as equipes vão continuar gastando tempo em melhorias que não resolvem os problemas reais da empresa.

O desafio da prática

Faça um exercício simples na sua próxima segunda-feira: pergunte ao seu time de desenvolvimento qual foi a funcionalidade mais crítica lançada na última semana. Em seguida, pergunte ao time de infraestrutura e banco de dados quais métricas eles estão monitorando para garantir que essa funcionalidade específica está funcionando bem.

Se as respostas não se conectarem, você encontrou o seu primeiro gargalo.

O DevOps só começa de verdade quando o sucesso do código e a saúde da infraestrutura deixam de ser acompanhados como coisas separadas. Isso significa compartilhar responsabilidades, métricas e, principalmente, uma mesma compreensão sobre o que representa uma operação saudável para o negócio.

Quando a tecnologia deixa de ser apenas operação

Esse é um dos pontos em que a diferença entre adotar uma prática e realmente incorporá-la à operação fica mais evidente.

DevOps não se resume à automação de processos ou à criação de novos fluxos de trabalho. A mudança depende de uma visão integrada sobre tecnologia, pessoas e negócio. Desenvolvimento, infraestrutura, banco de dados e gestão precisam entender como suas decisões se conectam e quais impactos elas podem gerar ao longo do tempo.

Isso também muda a forma como os problemas são tratados. Em vez de atuar apenas quando algo quebra, a equipe passa a buscar sinais que indiquem riscos, entender as causas dos problemas e criar condições para que eles não se repitam.

Na prática, isso significa sair de uma atuação predominantemente reativa para uma operação mais previsível. Significa transformar monitoramento em uma visão mais ampla do ambiente, automatizar aquilo que consome tempo sem gerar valor e criar processos que permitam que as equipes trabalhem de forma coordenada.

Essa evolução não acontece apenas com a adoção de novas ferramentas. Ela exige mudanças na forma de tomar decisões e de enxergar a própria tecnologia dentro da empresa.

Do discurso à prática

A distância entre o que uma organização diz sobre DevOps e a forma como ela realmente opera aparece justamente nos detalhes: quem é responsável por uma mudança depois que ela entra em produção? Quais métricas determinam se uma funcionalidade foi bem-sucedida? O time consegue identificar um problema antes que ele chegue ao cliente? As decisões de infraestrutura consideram o crescimento esperado do negócio?

São perguntas que ajudam a revelar se a tecnologia está apenas sustentando a operação atual ou se também está sendo preparada para acompanhar as necessidades futuras.

A transformação começa quando essas perguntas deixam de ser responsabilidade de uma única área e passam a fazer parte das decisões da organização. É nesse ponto que práticas como observabilidade, automação, confiabilidade e planejamento deixam de ser apenas conceitos técnicos e passam a contribuir para uma gestão de tecnologia mais sustentável.

Entender essa mudança exige olhar além das ferramentas e dos processos. É preciso compreender como a evolução da tecnologia está transformando os papéis profissionais, as responsabilidades das equipes e a própria relação entre TI e negócio.

Se as respostas do seu time não bateram, use o nosso mapa estratégico para unificar seus indicadores!?

No white paper O Mapa Estratégico para Navegar na Nova Era da TI, exploramos essas transformações e os caminhos para evoluir de uma atuação focada apenas na sustentação da operação para uma visão mais estratégica, previsível e sustentável da tecnologia.

Leia o white paper completo e conheça o mapa estratégico para saber como passar no “teste da segunda-feira”.

[Ler o White Paper]

Dois cubos transparentes contendo dados digitais flutuantes sobre fundo escuro, representando a transferência e proteção de informações.

Estado ou Evento? O que seu modelo de dados está realmente armazenando?

By Artigos

Existe uma diferença importante entre armazenar o estado atual de alguma coisa e armazenar os eventos que fazem esse estado mudar.

À primeira vista, parece uma escolha de modelagem simples. Se precisamos saber o valor atual, armazenamos o valor atual:

entity_id | current_value

Mas e quando precisamos responder:

  • Qual era o valor ontem?
  • Qual será o valor considerando eventos já programados?
  • Como chegamos ao estado atual?
  • O que aconteceria se um evento passado fosse corrigido?
  • Podemos reconstruir o estado em qualquer momento?
  • O valor armazenado continua consistente depois de múltiplas alterações concorrentes?

Nesse ponto, o problema deixa de ser apenas uma questão de armazenamento. Passa a ser uma questão de como o estado do sistema é representado e derivado. E o Postgres oferece ferramentas particularmente interessantes para trabalhar com esse tipo de modelo.

Estado é dado ou é consequência?

Considere uma sequência simples de eventos:

data        alteração
01/09       +10
03/09        -4
07/09        +8

Podemos armazenar diretamente:

07/09 → 14

Mas esse 14 não é um evento. Ele é uma consequência dos eventos anteriores. Isso cria duas possibilidades de modelagem.

Armazenar o estado

entity_id | current_value
----------+--------------
1         | 14

Armazenar os eventos

entity_id | event_date | quantity
----------+------------+---------
1         | 01/09      | +10
1         | 03/09      |  -4
1         | 07/09      |  +8

Armazenar apenas o estado atual simplifica as leituras, mas perde a rastreabilidade e a flexibilidade temporal.  Armazenar eventos como fonte de verdade permite reconstruir o estado em qualquer momento, lidar com eventos futuros e auditar alterações. A questão arquitetural é: Qual dessas informações é a fonte de verdade do sistema?

O problema de manter estado e histórico ao mesmo tempo

Uma aplicação pode decidir armazenar os dois:

events
current_state

Isso pode ser extremamente eficiente para leitura. Mas agora temos duas representações da mesma realidade. Sempre que um evento for inserido, alterado ou removido, o estado materializado precisa continuar correto. Imagine uma transação que:

  1. registra um novo evento;
  2. atualiza o estado atual;
  3. alguma etapa falha antes da segunda operação;
  4. ou duas transações tentam atualizar o mesmo estado simultaneamente.

Agora temos um problema de consistência. O valor atual deixou de ser apenas um dado. Ele passou a ser um dado derivado que precisa ser sincronizado.

É aqui que o banco de dados deixa de ser apenas o lugar onde armazenamos informações e passa a participar diretamente da implementação das regras do domínio.

O PostgreSQL consegue derivar esse estado

Se os eventos são a fonte de verdade, o estado pode ser calculado, uma Window Function permite transformar uma sequência de alterações em um valor acumulado:

SELECT
    event_date,
    quantity,
    SUM(quantity) OVER (
        ORDER BY event_date
    ) AS state
FROM events
ORDER BY event_date;

O resultado representa a evolução do estado:

data        alteração    estado
01/09       +10          10
03/09        -4           6
07/09        +8          14

A importância dessa consulta não está na sintaxe do SUM(). Está no fato de que o estado não precisa necessariamente existir como uma coluna armazenada, ele pode ser derivado a partir dos eventos que o determinam.

O tempo também faz parte do modelo

Agora imagine que existam eventos futuros:

01/09   +10
03/09    -4
07/09    +8
15/09    -3

A pergunta: “Qual é o estado?” fica incompleta. Precisamos perguntar: “Qual é o estado em relação a qual momento?” Esse detalhe muda a consulta. O estado em 10/09 deve considerar determinados eventos. O estado em 20/09 pode considerar outros. A dimensão temporal deixa de ser apenas um atributo dos registros e passa a fazer parte da própria regra de negócio.

Esse é um dos motivos pelos quais sistemas que trabalham com histórico, vigência ou eventos futuros podem se tornar significativamente mais complexos do que uma tabela com um simples current_value.

E se não houver um registro para determinada data?

Outro detalhe importante aparece quando queremos analisar a evolução do estado diariamente. Podemos ter eventos em:

01/09
03/09
07/09

mas querer consultar:

01/09
02/09
03/09
04/09
05/09
06/09
07/09

Não precisamos necessariamente criar registros artificiais para cada dia. O PostgreSQL consegue gerar essa dimensão temporal durante a consulta:

generate_series(
    DATE '2026-09-01',
    DATE '2026-09-07',
    INTERVAL '1 day'
)

Combinando essa série com os eventos e uma Window Function, podemos reconstruir a evolução do estado sem transformar cada ponto da linha do tempo em um registro persistido. O importante aqui não é generate_series() em si, é a possibilidade de separar a representação dos eventos da representação do tempo que queremos analisar.

Mas calcular tudo sob demanda é sempre uma boa ideia?

Não. Esse é justamente o ponto em que uma decisão técnica precisa substituir uma preferência por determinada técnica. Se temos milhões de eventos e uma aplicação consulta o estado atual milhares de vezes por segundo, recalcular todo o histórico a cada leitura provavelmente não será uma boa estratégia. Nesse cenário, podemos considerar outras abordagens:

Estado derivado sob demanda

O histórico é a fonte de verdade e o estado é calculado quando necessário.

Vantagem: consistência e capacidade de reconstrução.
Custo: processamento durante a leitura.

Estado materializado

O estado atual é armazenado e atualizado junto com os eventos.

Vantagem: leituras rápidas.
Custo: complexidade de manutenção e necessidade de garantir consistência.

Estratégia híbrida

Mantemos eventos como histórico e também algum nível de estado materializado ou agregado. Por exemplo:

eventos históricos
        ↓
checkpoint
        ↓
eventos posteriores
        ↓
estado atual

Nesse caso, não precisamos recalcular toda a história para descobrir o estado.

Essa estratégia pode ser interessante quando o volume cresce e o custo de reconstrução completa se torna relevante.

Onde o PostgreSQL entra nessa decisão?

O banco de dados não deve ser visto apenas como uma camada passiva de persistência. O Postgres oferece recursos nativos poderosos capazes de derivar estados e manipular dimensões temporais diretamente nas consultas.:

  • Window Functions para cálculos sobre sequências;
  • CTEs para organizar etapas de derivação;
  • generate_series() para trabalhar com dimensões temporais;
  • índices para reduzir o custo de acesso aos eventos;
  • particionamento para lidar com grandes volumes temporais;
  • materialized views para cenários em que resultados derivados podem ser pré-calculados;
  • transações e mecanismos de concorrência para manter alterações consistentes;
  • constraints para proteger invariantes do modelo.

A questão, portanto, não é: “Qual função do PostgreSQL resolve meu problema?” É: “Qual representação do dado torna esse problema sustentável para o meu ambiente?”

O estado atual pode ser uma projeção do histórico

Essa distinção é particularmente importante em sistemas que precisam de rastreabilidade. Se armazenamos apenas:

current_value = 14

Sabemos o resultado, mas não necessariamente sabemos como chegamos nele. Se armazenamos:

+10
-4
+8

podemos derivar:

10 → 6 → 14

E podemos fazer perguntas sobre diferentes momentos. O histórico passa a ser a fonte de verdade, enquanto o estado pode ser entendido como uma projeção desse histórico.

Isso não significa que devemos sempre adotar event sourcing, nem que armazenar estado seja uma má prática, significa apenas que essa é uma decisão que merece ser consciente.

A pergunta que vale levar para o projeto

Quando encontramos uma tabela com algo como:

current_status
current_balance
current_quantity
current_score
current_limit

vale fazer uma pergunta: Esse valor é um fato ou é uma consequência de outros dados?

Se for um fato, armazená-lo pode ser a escolha natural.
Se for uma consequência, talvez seja interessante entender:

  • Quais eventos determinam esse valor;
  • Se esses eventos são preservados;
  • Se o estado pode ser reconstruído;
  • Qual é o custo dessa reconstrução;
  • Com que frequência o estado é consultado;
  • Quais são os requisitos de consistência;
  • E se vale a pena materializar o resultado.

Essa análise é mais importante do que escolher entre uma Window Function, uma CTE ou qualquer outra funcionalidade específica.

PostgreSQL como parte da arquitetura

Derivar tudo sob demanda pode ser custoso em grandes volumes com alta concorrência. Por isso, a escolha entre armazenar o estado, derivar sob demanda ou usar estratégias híbridas (como checkpoints e vistas materializadas) deve ser uma decisão consciente baseada em requisitos de consistência, volume e padrões de acesso, e não em preferências por uma única técnica.

O PostgreSQL possui recursos suficientes para participar ativamente da construção de estados derivados, mantendo a lógica próxima dos dados quando isso fizer sentido. A decisão entre armazenar estado, derivar estado ou combinar as duas estratégias depende do domínio, do volume, do padrão de acesso e dos requisitos de consistência.

O ponto principal é reconhecer quando estamos diante de um estado que existe por si só, e quando estamos diante de um estado que é apenas o resultado de uma história.

Quando o valor atual é consequência de eventos anteriores, talvez a pergunta mais importante não seja: “Onde guardamos o valor?” Mas: “Onde está a verdade que permite reconstruí-lo?”

 

Receba mais conteúdos como este!

Assine a nossa newsletter e acompanhe conteúdos técnicos, análises e discussões sobre PostgreSQL, arquitetura e engenharia de dados.

[Quero receber os próximos conteúdos]

Arquitetura de produção usando a extensão pgvector

By Artigos

A corrida pela adoção de Inteligência Artificial fez surgir uma nova categoria de armazenamento de dados: os bancos vetoriais. Soluções especializadas ganharam espaço ao prometer buscas semânticas rápidas e eficientes para aplicações baseadas em embeddings, RAG (Retrieval-Augmented Generation), sistemas de recomendação e mecanismos de busca inteligentes.

No entanto, à medida que os projetos avançam da prova de conceito para ambientes produtivos, muitas equipes descobrem que adicionar um banco vetorial separado também significa aumentar a complexidade operacional, introduzir novos pontos de falha e criar desafios de sincronização de dados.

Nesse contexto, o Postgres vem se consolidando como uma alternativa cada vez mais atraente. Com a extensão pgvector, é possível armazenar embeddings, executar buscas vetoriais e integrar funcionalidades de IA diretamente no banco de dados principal da aplicação, reduzindo a fragmentação da infraestrutura e simplificando a operação.

Neste artigo, vamos explorar como construir arquiteturas de produção utilizando pgvector, analisando os trade-offs entre os índices HNSW e IVFFlat e entendendo quando cada abordagem faz mais sentido.

Por que armazenar vetores no PostgreSQL?

Os dados transacionais já residem no PostgreSQL, em muitos projetos de IA.

Quando uma arquitetura adiciona um banco vetorial externo, surgem novos desafios:

  • Duplicação de dados;
  • Processos de sincronização entre sistemas;
  • Consistência entre registros e embeddings;
  • Novas rotinas de backup;
  • Monitoramento adicional;
  • Aumento dos custos operacionais.

Com o pgvector, embeddings passam a ser armazenados diretamente ao lado dos dados de negócio.

Um modelo simplificado pode ser representado da seguinte forma:

CREATE TABLEdocumentos (
    id BIGSERIAL PRIMARY KEY,
    titulo TEXT,
    conteudo TEXT,
    embedding VECTOR(1536)
);

Nesse cenário, informações estruturadas e vetores coexistem no mesmo banco de dados, permitindo consultas híbridas que combinam filtros relacionais e busca semântica.

Observe que a coluna embedding na tabela documentos utiliza o tipo VECTOR(1536). O tipo VECTOR torna-se disponível no PostgreSQL após a ativação da extensão pgvector. O valor entre parênteses (1536) especifica a dimensão do vetor, ou seja, o número de dimensões suportado. Essa dimensão varia conforme o modelo de embedding utilizado, exigindo um modelo externo para a geração dos dados vetoriais que serão inseridos nesse campo. É fundamental assegurar que a dimensão do campo corresponda exatamente à do modelo escolhido, pois não é possível armazenar um vetor de maior dimensão em um espaço menor.

Isso significa que uma aplicação pode procurar documentos semanticamente similares sem abrir mão dos recursos tradicionais do Postgres, como transações, replicação, backup e alta disponibilidade.

O desafio da busca vetorial em escala

Embora armazenar embeddings seja relativamente simples, executar buscas vetoriais em grandes volumes de dados apresenta desafios.

Uma consulta típica busca identificar os vetores mais próximos de um vetor de referência:


SELECT *
FROM documentos
ORDER BY embedding <=> '[...]'
LIMIT 10;

Sem indexação apropriada, o PostgreSQL precisa comparar o vetor consultado com todos os registros da tabela.

Esse processo, conhecido como brute force search, pode funcionar em conjuntos pequenos, mas rapidamente se torna inviável quando o volume alcança milhões de embeddings.

Para resolver esse problema, o pgvector oferece atualmente duas principais estratégias de indexação aproximada:

  • IVFFlat
  • HNSW

A escolha entre elas tem impacto direto na latência, consumo de memória, tempo de construção e precisão dos resultados.

Entendendo o índice IVFFlat

O IVFFlat (Inverted File Flat) funciona agrupando vetores semelhantes em listas.

Durante a busca, o mecanismo consulta apenas os grupos mais relevantes, reduzindo significativamente o volume de comparações necessárias.

Sua criação ocorre da seguinte forma:

CREATE INDEX idx_documentos_embedding
ON documentos
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

A principal vantagem do IVFFlat é sua eficiência operacional.

Entre seus benefícios estão:

  • Menor consumo de memória;
  • Construção mais rápida;
  • Menor impacto em operações de escrita;
  • Boa performance para grandes volumes.

Por outro lado, existe um trade-off importante: a precisão dos resultados depende da configuração utilizada.

Quanto menos listas forem consultadas durante a busca, menor será a latência, mas também menor poderá ser a taxa de acerto dos vizinhos mais próximos.

Por esse motivo, o IVFFlat costuma ser indicado para ambientes onde o volume de dados é muito elevado e pequenas perdas de precisão são aceitáveis.

Entendendo o índice HNSW

O HNSW (Hierarchical Navigable Small World) é atualmente considerado uma das estruturas mais eficientes para busca aproximada de vizinhos próximos.

Seu funcionamento é baseado em um grafo multicamadas que conecta vetores semanticamente próximos.

A criação do índice segue um modelo semelhante:

CREATE INDEX idx_documentos_embedding_hnsw
ON documentos
USING hnsw (embedding vector_cosine_ops);

A grande vantagem do HNSW está na combinação entre velocidade e precisão.

Em muitos cenários, ele consegue atingir taxas de recall extremamente altas com tempos de resposta reduzidos.

Isso faz com que seja frequentemente a escolha preferida para aplicações como:

  • Chatbots corporativos;
  • Sistemas RAG;
  • Busca documental;
  • Pesquisa jurídica;
  • Bases de conhecimento empresariais.

Entretanto, esse desempenho tem um custo.

O HNSW normalmente exige:

  • Mais memória RAM;
  • Maior tempo de construção;
  • Maior custo de manutenção;
  • Processos de indexação mais pesados.

Em bases muito grandes, esses fatores precisam ser considerados durante o planejamento da infraestrutura.

HNSW ou IVFFlat: qual escolher?

A resposta depende dos objetivos do ambiente. De forma simplificada:

Característica IVFFlat HNSW
Velocidade de construção Alta Menor
Consumo de memória Menor Maior
Velocidade de consulta Boa Excelente
Precisão (Recall) Boa Muito alta
Impacto operacional Menor Maior
Escalabilidade para

escrita intensa

Melhor Moderada

Em ambientes onde a prioridade é maximizar a qualidade dos resultados, HNSW costuma oferecer vantagens significativas.

Já em cenários com crescimento acelerado, alta taxa de inserções ou restrições de infraestrutura, IVFFlat pode representar um equilíbrio mais interessante.

A tabela é válida como regra prática, mas não deve ser interpretada como universal. O ideal é sempre homologar e comparar a utilização dos índices com dados reais, medindo principalmente:

  • latência de consulta;
  • precisão;
  • tempo de construção;
  • uso de memória;
  • custo e latência das inserções;
  • impacto de atualizações e exclusões.

Arquitetura de produção: além dos índices

Um erro comum é acreditar que a adoção de IA no PostgreSQL se resume à criação de um índice vetorial.

Em ambientes produtivos, outros componentes precisam ser considerados:

Estratégia de geração de embeddings

É necessário definir:

  • Qual modelo será utilizado;
  • Como ocorrerá a atualização dos vetores;
  • Como lidar com mudanças de versão dos modelos.

Trocar um modelo de embedding geralmente exige reprocessar todos os vetores armazenados.

Crescimento da base

Embeddings ocupam espaço significativo.

Uma coleção com milhões de documentos pode consumir dezenas ou centenas de gigabytes apenas para armazenamento vetorial.

O planejamento de capacidade deve considerar:

  • Crescimento dos dados;
  • Índices vetoriais;
  • Replicação;
  • Backups.

Monitoramento

Além das métricas tradicionais do PostgreSQL, é importante acompanhar:

  • Latência das consultas vetoriais;
  • Taxa de recall;
  • Crescimento dos índices;
  • Uso de memória;
  • Impacto nas operações de escrita.

Alta disponibilidade

Uma das vantagens do pgvector é que os mecanismos já utilizados para o PostgreSQL continuam válidos.

Recursos como:

  • Replicação física;
  • Patroni;
  • pgBackRest;
  • Failover automatizado;

continuam funcionando normalmente, reduzindo a necessidade de administrar plataformas adicionais.

O benefício estratégico de consolidar dados e IA

À medida que aplicações baseadas em IA deixam de ser iniciativas experimentais e passam a fazer parte de processos críticos de negócio, a simplicidade operacional se torna um fator cada vez mais importante.

Ao utilizar pgvector, equipes conseguem incorporar capacidades de busca semântica sem criar uma nova camada tecnológica isolada.

Em vez de manter bancos transacionais de um lado e bancos vetoriais de outro, torna-se possível centralizar dados, governança, segurança, observabilidade e recuperação em uma única plataforma.

Essa abordagem reduz custos operacionais, simplifica a arquitetura e acelera a adoção de funcionalidades baseadas em IA.

Conclusão

A extensão pgvector transformou o PostgreSQL em uma plataforma capaz de atender não apenas cargas transacionais tradicionais, mas também demandas modernas de busca semântica e aplicações de IA generativa.

A escolha entre HNSW e IVFFlat deve ser orientada pelos requisitos do negócio, considerando o equilíbrio entre precisão, desempenho, consumo de recursos e complexidade operacional.

Mais importante do que escolher o índice mais rápido é projetar uma arquitetura sustentável, capaz de crescer junto com os dados e manter a simplicidade operacional. Em muitos casos, integrar IA diretamente ao PostgreSQL pode ser o caminho mais eficiente para levar aplicações inteligentes à produção sem fragmentar a infraestrutura existente.

 

Faça parte da nossa newsletter

Query Planner: Garantindo Previsibilidade em Ambientes de Alta Complexidade

By Artigos

A escolha do banco de dados muitas vezes é tratada como uma decisão puramente de preferência ou custo imediato. No entanto, à medida que o modelo de dados evolui e as relações entre entidades se tornam mais densas, a capacidade do banco de planejar a execução de uma consulta torna-se o divisor de águas entre um ambiente estável e um sistema que sofre com picos de latência imprevisíveis.

A Estratégia por trás da Execução

Enquanto o MySQL se consolidou por sua eficiência em operações de leitura simples e alta concorrência em modelos menos complexos, o PostgreSQL foi desenhado sob uma premissa de sofisticação analítica. A grande dor de quem gerencia ambientes MySQL em escala é o momento em que o otimizador falha ao lidar com junções múltiplas (joins) ou subconsultas aninhadas, muitas vezes optando por estratégias de Nested Loop que degradam a performance de forma exponencial.

O PostgreSQL mitiga esse risco através de um Query Planner baseado em custo (CBO) que não apenas segue regras fixas, mas realiza uma análise estatística aprofundada antes da execução da consulta. Na prática, o banco mantém estatísticas atualizadas sobre a distribuição dos dados, a cardinalidade, a densidade de valores distintos e as dependências entre múltiplas colunas de uma mesma tabela, permitindo estimativas mais precisas e a escolha do plano de execução mais eficiente para cada cenário. 

Quando uma consulta chega, o planejador simula diversos caminhos de execução, atribuindo um ‘custo’ a cada um (baseado em estimativas de uso de CPU e I/O de disco). Ele avalia, por exemplo, se a seletividade de um filtro é alta o suficiente para justificar o uso de um índice ou se um Sequential Scan seria mais eficiente devido ao agrupamento físico dos dados no disco. Para o tomador de decisão técnica, isso significa que o banco possui uma capacidade maior de ‘se auto-ajustar’ à medida que o volume cresce. Desde que as estatísticas sejam mantidas atualizadas por meio do autovacuum ou de operações de ANALYZE, o PostgreSQL é capaz de recalcular automaticamente seus planos de execução conforme a distribuição dos dados evolui. 

Diversidade de Algoritmos como Redutor de Riscos

Um dos pilares da previsibilidade do Postgres é a sua versatilidade na escolha de algoritmos de junção. Ele não se limita a uma única técnica:

  • Hash Joins e Merge Joins: Diferente de estratégias mais restritas, o PostgreSQL consegue identificar quando é mais eficiente construir uma estrutura hash em memória para acelerar a localização dos registros relacionados (Hash Join) ou aproveitar conjuntos de dados previamente ordenados (Merge Join). Para o nível tático, essa flexibilidade representa uma redução significativa no consumo de I/O e um comportamento mais previsível em consultas executadas sobre grandes volumes de dados. 
  • Flattening de Subqueries: Sempre que a estrutura da consulta permite, o planner possui a inteligência para transformar subconsultas em planos de execução equivalentes e mais eficientes, integrando-as à query principal e ampliando as possibilidades de otimização. Essa abordagem reduz materializações desnecessárias e minimiza o risco de que consultas complexas gerem custos excessivos de processamento. 

Tomada de Decisão: Quando a Complexidade Exige Maturidade

Para profissionais que planejam a evolução de um ecossistema de dados, a escolha pelo PostgreSQL deve ser vista como um investimento em sustentabilidade. Um planejador de consultas robusto permite que a equipe de desenvolvimento foque na regra de negócio, enquanto o motor do banco se encarrega de encontrar o caminho de menor resistência.

Ao avaliar cenários de alta complexidade, o risco de manter um otimizador menos sofisticado é o aumento do custo técnico: mais tempo de engenharia gasto em query tuning, mais recursos de hardware desperdiçados e, principalmente, a falta de previsibilidade em relatórios ou processos críticos.

A Escolha pela Sustentabilidade Técnica

Optar pelo PostgreSQL, sob a ótica do planejamento de consultas, vai muito além de escolher um motor de armazenamento; é decidir por uma infraestrutura que respeita a complexidade e a mutabilidade dos dados modernos. Em ambientes de alta demanda, a performance não pode ser um evento inesperado ou dependente de constantes ajustes manuais nas consultas. Ela deve ser o resultado de uma arquitetura que possui inteligência para se adaptar.

Para o DSE, essa é uma decisão estratégica que prioriza a consistência e a inteligência estrutural. Ao garantir que o sistema continue performático mesmo sob pressão e alta complexidade, reduz-se o custo de manutenção a longo prazo e minimizam-se os riscos de degradação súbita em produção. No fim, escolher o PostgreSQL é garantir que a tecnologia acompanhe a evolução do negócio, sustentando de forma eficiente os patamares de escala que o futuro certamente exigirá.

Faça parte da nossa newsletter

Como decisões sobre Shared Buffers impactam performance, custos e escalabilidade

By Artigos

Existe uma recomendação que acompanha administradores de PostgreSQL há muitos anos: configurar o parâmetro shared_buffers com aproximadamente 25% da memória disponível no servidor.

Embora essa orientação continue sendo um bom ponto de partida para diversos cenários, ela também criou um hábito perigoso. Diante de problemas de desempenho, muitos profissionais assumem que aumentar a quantidade de memória destinada ao cache do Postgres necessariamente resultará em ganhos de desempenho.

Na prática, a realidade é mais complexa.

Em muitos ambientes, aumentar agressivamente o valor de shared_buffers gera benefícios limitados. Ao mesmo tempo, amplia custos de infraestrutura, aumenta o volume de páginas sujas em memória e modifica a dinâmica de processos internos como o Background Writer e os checkpoints.

Mais importante do que saber qual valor configurar é entender como defender tecnicamente essa decisão. Afinal, à medida que um profissional evolui na carreira, espera-se que ele não apenas ajuste parâmetros, mas também consiga justificar investimentos, antecipar impactos operacionais e alinhar decisões técnicas aos objetivos do negócio.

O que são Shared Buffers?

O shared_buffers é a principal área de cache do PostgreSQL.

Sempre que uma página de dados é acessada, o Postgres tenta encontrá-la primeiro nesse cache antes de recorrer ao armazenamento físico.

O objetivo é simples: reduzir operações de leitura em disco e melhorar os tempos de resposta.

Quando uma página já está presente no cache, ocorre um cache hit. Quando não está, o PostgreSQL precisa buscar a informação no armazenamento, gerando um cache miss.

Em teoria, aumentar o tamanho do cache parece uma decisão óbvia. Quanto mais memória disponível, mais dados podem permanecer armazenados para reutilização futura. Mas essa lógica possui limites claros.

O equívoco de associar memória diretamente à performance

Um dos erros mais comuns em ambientes PostgreSQL é tratar a memória como solução universal para problemas de desempenho.

Quando uma aplicação apresenta lentidão, frequentemente surgem recomendações como:

  • Aumentar shared_buffers;
  • Adicionar mais RAM ao servidor;
  • Migrar para uma instância maior na nuvem.

Embora essas ações possam trazer benefícios em determinados cenários, elas não atacam necessariamente a causa raiz do problema.

Se uma consulta executa um Sequential Scan desnecessário em uma tabela de centenas de milhões de linhas, aumentar o cache não corrige a estratégia inadequada de acesso aos dados. Da mesma forma, gargalos relacionados a:

  • Índices mal projetados;
  • Consultas ineficientes;
  • Estatísticas desatualizadas;
  • Contenção de bloqueios;
  • Problemas de modelagem;

continuarão existindo independentemente da quantidade de memória disponível.

É importante entender que memória é um recurso que potencializa uma arquitetura saudável, não um substituto para ela.

Quando aumentar Shared Buffers faz sentido?

Existem cenários legítimos onde ampliar o cache pode trazer ganhos significativos. Por exemplo:

  • Ambientes com conjuntos de dados frequentemente reutilizados;
  • Sistemas com alto volume de leitura;
  • Aplicações que apresentam baixa taxa de cache hit;
  • Bancos executando sobre armazenamentos mais lentos.

Nesses casos, um cache maior pode reduzir a necessidade de leituras físicas e melhorar a experiência dos usuários.

O ponto central é que a decisão deve ser baseada em métricas, não em suposições. Antes de aumentar o parâmetro, é importante avaliar indicadores como:

SELECT
    sum(blks_hit) AS hits,
    sum(blks_read) AS reads,
    round(
        100 * sum(blks_hit)::numeric /
        (sum(blks_hit) + sum(blks_read)),
        2
    ) AS hit_ratio
FROM pg_stat_database;

Uma taxa de cache hit elevada pode indicar que o banco já está aproveitando adequadamente a memória disponível.

Nesse cenário, aumentar ainda mais o cache pode gerar pouco ou nenhum benefício perceptível.

O impacto silencioso sobre o Background Writer

Quando uma página é modificada, ela não é gravada imediatamente em disco.

Primeiro, ela permanece em memória como uma página suja (dirty page). Posteriormente, processos internos do Postgres são responsáveis por persistir essas alterações. Um deles é o Background Writer.

Sua função é antecipar gravações e reduzir a pressão sobre os processos de backend.

O que muitos profissionais não percebem é que aumentar significativamente o valor de shared_buffers também aumenta o potencial volume de páginas modificadas mantidas em memória.

Consequentemente:

  • Mais páginas precisam ser gerenciadas;
  • Mais dados podem ser acumulados antes da gravação;
  • Checkpoints podem se tornar mais intensos;
  • Picos de I/O podem aumentar.

Em alguns cenários, o resultado é justamente o oposto do esperado: mais memória disponível, mas maior instabilidade no comportamento do armazenamento.

A relação entre Shared Buffers e Checkpoints

Checkpoints representam momentos em que o PostgreSQL precisa garantir que as alterações realizadas em memória sejam persistidas em disco.

Quando há grandes volumes de páginas modificadas acumuladas, o processo de checkpoint pode gerar rajadas significativas de escrita. Isso afeta diretamente:

  • Latência das aplicações;
  • Consumo de IOPS;
  • Utilização do armazenamento;
  • Tempo de recuperação após falhas.

Ambientes que ampliam agressivamente o cache sem revisar parâmetros relacionados a checkpoints frequentemente observam comportamentos inconsistentes durante períodos de carga elevada.

Por isso, qualquer discussão sobre shared_buffers deveria considerar também:

  • checkpoint_timeout
  • max_wal_size
  • checkpoint_completion_target
  • Métricas de escrita observadas no sistema

Avaliar um parâmetro isoladamente raramente produz os melhores resultados.

O custo financeiro da memória

Em ambientes on-premises, o desperdício de memória representa investimento subutilizado. Na nuvem, ele se traduz diretamente em custos recorrentes.

Imagine um ambiente que aumenta de 64 GB para 128 GB de RAM apenas para elevar o valor de shared_buffers. Se os ganhos reais forem mínimos, a empresa passa a pagar continuamente por recursos que não estão resolvendo o problema original.

Esse é um ponto importante para profissionais que desejam participar de decisões estratégicas.

Lideranças não estão interessadas apenas em desempenho. Elas precisam entender:

  • Qual problema será resolvido;
  • Qual é o impacto esperado;
  • Qual o custo associado;
  • E qual o retorno sobre o investimento.

A capacidade de responder essas perguntas diferencia um executor técnico de um profissional que influencia decisões de negócio.

O papel do sistema operacional

Outro aspecto frequentemente ignorado é que o PostgreSQL não opera sozinho. O sistema operacional também possui mecanismos avançados de cache de arquivos.
Quando o valor de shared_buffers cresce excessivamente, reduz-se a quantidade de memória disponível para o cache do próprio sistema operacional.

Em determinados cenários, isso pode gerar um efeito contrário ao desejado. Em vez de melhorar a eficiência global do ambiente, ocorre apenas uma redistribuição dos recursos de memória entre diferentes camadas da pilha.

Por isso, o dimensionamento ideal busca equilíbrio, não maximização.

O que os profissionais devem analisar?

Antes de recomendar mais memória, profissionais com visão arquitetural costumam investigar:

  • Taxa de cache hit;
  • Volume real de leituras físicas;
  • Perfil das consultas;
  • Eficiência dos índices;
  • Comportamento dos checkpoints;
  • Atuação do Background Writer;
  • Consumo de I/O;
  • Custos da infraestrutura;
  • Crescimento projetado do ambiente.

A partir dessas informações, a discussão deixa de ser “quanto de memória devemos adicionar?” e passa a ser “qual é o gargalo que estamos tentando resolver?”.

Essa mudança de perspectiva gera decisões mais sustentáveis e economicamente justificáveis.

Conclusão

A configuração de shared_buffers vai muito além de seguir uma regra de bolso ou reservar uma porcentagem fixa da memória disponível.

Trata-se de uma decisão que afeta diretamente a dinâmica de cache, o comportamento do Background Writer, os checkpoints, a utilização do armazenamento e os custos da infraestrutura.

Profissionais que evoluem para funções de maior responsabilidade aprendem que performance não é resultado da maximização de recursos, mas do entendimento profundo dos mecanismos envolvidos.

Mais memória pode ser a solução em alguns cenários. Em outros, representa apenas uma forma cara de mascarar problemas que continuarão existindo.

A diferença está na capacidade de identificar qual dessas situações está ocorrendo antes de solicitar a próxima expansão de infraestrutura.

 

Faça parte da nossa newsletter

Definindo Critérios de Rollback (RBEC) em Grandes Migrações de PostgreSQL

By Artigos

Em migrações de larga escala no PostgreSQL, é comum que o foco das equipes de engenharia convirja quase inteiramente para o caminho feliz (happy path): a automação, a validação de esquemas e a sincronização. Contudo, em ambientes de alta transacionalidade, a verdadeira maturidade de uma virada de chave não reside na perfeição do plano A, mas na robustez do plano de contingência

É aqui que entra o conceito de RBEC (Rollback Criteria Based on Evidence / Critérios de Rollback Baseados em Evidências). Em ecossistemas Postgres com múltiplos terabytes, alta concorrência e dependências estritas de latência, a decisão de abortar uma migração e retornar ao estado anterior não pode ser baseada no sentimento da equipe técnica durante a janela de manutenção. Ela deve responder a limiares (thresholds) matemáticos e arquiteturais previamente acordados.

Abaixo, analisamos os pilares para estruturar critérios de rollback previsíveis, mitigando riscos antes que o ambiente atinja o ponto de não retorno.

O Conceito do ponto de não retorno (PoNR)

O Ponto de Não Retorno (PoNR) é a linha invisível que separa uma migração gerenciável de uma crise operacional. Antes dele, o rollback é uma manobra técnica; depois dele, o rollback torna-se uma operação complexa de reconstrução, envolvendo reconciliação de dados “reconciliation”, data replay e, fatalmente, períodos de indisponibilidade estendidos. O RBEC serve como o seu “sistema de freios” para garantir que a decisão de abortar ocorra sempre antes de cruzar essa fronteira.”

Pilares do RBEC: O que monitorar na janela de virada

Para evitar avaliações subjetivas sob a pressão do cronômetro, o framework de RBEC para Postgres deve considerar quatro categorias de métricas críticas:

1. Saturação de Recursos Críticos (Saturating Thresholds)

Logo após a abertura do tráfego para o novo cluster PostgreSQL, o comportamento do sistema operacional e do subsistema de armazenamento deve ser avaliado contra limites estritos:

  • IOPS e Latência de Disco: O volume de leitura/escrita pós-migração estabilizou ou está consumindo mais de 85% da capacidade nominal do storage? Um gargalo em operações de I/O devido a planos de execução ruins (como a mudança repentina para Sequential Scans) pode inviabilizar a operação.
  • Saturação de CPU por Locks ou Concorrência: O crescimento abrupto no uso de CPU causado por disputas em catálogos (lwlock ou hwlock) indica falhas que testes sintéticos raramente capturam.

2. Comportamento Lógico e Degradação do Otimizador

Muitas regressões em migrações de PostgreSQL derivam da reconfiguração ou defasagem do catálogo de estatísticas. Os critérios de RBEC devem prever:

  • Fila de Queries Acumuladas: Monitoramento contínuo através da pg_stat_activity. Se o número de conexões ativas em estado active aumentar exponencialmente, há um indicativo claro de regressão generalizada de planos de execução. Contudo, é fundamental considerar que o “aquecimento” (warm-up) do buffer cache em um novo ambiente pode demandar um tempo maior, elevando o I/O e gerando lentidões transitórias enquanto os dados são carregados em memória. Por isso, a janela de observação deve ser calibrada para distinguir esse comportamento de cold start de uma falha real de performance.
  • Aumento de Latência no Percentil Alto (P99): Se a latência média geral parecer estável, mas o P99 das transações críticas do core do negócio quadruplicar, a operação está sob risco.

3. Estabilidade da Replicação e Conectividade

Em arquiteturas distribuídas ou migrações que envolvem replicação lógica (como via pglogical ou recursos nativos para grandes atualizações):

  • Lag de Replicação Crescente: Se a réplica de salvaguarda ou o mecanismo de fallback apresentar um lag em bytes que cresce linearmente sem capacidade de convergência, a segurança do ambiente pós-virada está comprometida.

4. Definindo a Matriz de Gatilhos de Rollback

Um checklist técnico de upgrade eficiente deve conter uma matriz explícita de causa e efeito. Exemplo de parametrização de gatilhos:

Métrica Avaliada Limiar de Alerta (Investigar) Limiar de Rollback (Acionar Contingência) Janela de Observação
Latência P99 do Core > 1.5x da Baseline Histórica > 3x da Baseline Histórica por mais de 5 min Primeiros 15 min de tráfego
Conexões Ativas Solicitando CPU > 50% do max_connections > 80% do max_connections com contenção de Lock Imediato após liberação
Uso de Disco (I/O Wait) > 20% de CPU em I/O wait > 40% de CPU em I/O wait persistente Primeiros 10 min de tráfego

 

Se qualquer um dos limiares de Rollback for atingido dentro da janela de observação estabelecida, a liderança técnica aciona o plano de retorno imediatamente, sem espaço para debates em cenários de crise.

Grandes migrações de PostgreSQL exigem mais do que excelência na execução 

Grandes migrações exigem planejamento técnico, mas, acima de tudo, governança de risco. Adotar um framework como o RBEC transforma a tensão de uma janela de manutenção em um processo previsível e puramente guiado por dados. No fim do dia, a verdadeira resiliência de um ecossistema de alta transacionalidade não é medida apenas pela audácia de seguir em frente, mas pela maturidade analítica de saber exatamente o momento certo de frear.

Conte Conosco!

Precisa de apoio para elevar a maturidade técnica dos seus ambientes PostgreSQL?

[Fale com a Timbira]

pgBackRest: SSH vs TLS – Qual a melhor escolha para o seu PostgreSQL?

By Artigos

Quando um ambiente Postgres expande sua operação e cruza a fronteira dos Terabytes, a gestão de infraestrutura sofre uma mudança de fase. O que antes era uma rotina automatizada e silenciosa passa a ser um dos indicadores mais críticos de continuidade de negócios: as métricas de RTO (Recovery Time Objective) e RPO (Recovery Point Objective). Em cenários de alta escala, cada minuto economizado na janela de backup ou na restauração reflete diretamente na resiliência de toda a operação.

O diagnóstico de senso comum dita que, se a janela de backup está se estendendo além do aceitável, a solução imediata é investir em hardware: provisionar discos com maiores taxas de IOPS, migrar para volumes NVMe ou contratar links de rede com maior largura de banda. No entanto, em infraestruturas modernas que já contam com redes de 10Gbps ou 40Gbps, muitas equipes se deparam com um teto de vidro. Mesmo com recursos de hardware sobrando, a taxa de transferência estagna.

Existe um gargalo invisível na camada de transporte de dados. A grande maioria dos ambientes adota a combinação do utilitário pgBackRest operando sobre o protocolo SSH, devido sua simplicidade e o caminho de menor resistência na configuração inicial. Contudo, quando o volume de dados escala de forma massiva, o protocolo SSH pode impor um overhead considerável a depender do ambiente , tornando-se o principal limitador do throughput do backup.

Por que o SSH “gargala” em ambientes robustos?

Para compreender a subutilização da infraestrutura de rede durante os backups, é preciso analisar como o protocolo SSH interage com o sistema operacional sob cargas de trabalho intensas. Não se trata de uma limitação do pgBackRest, mas sim da arquitetura de software projetada para o tráfego de dados.

O Custo da Criptografia no Espaço do Usuário (User Space)

O SSH foi desenhado originalmente para garantir canais seguros para sessões interativas e transferências de arquivos genéricas. Para assegurar essa comunicação, ele executa uma rotina pesada que envolve criptografia, verificação de integridade e, frequentemente, compressão de pacotes. Todo esse processamento ocorre no espaço do usuário.

Quando o pgBackRest tenta empurrar fluxos contínuos e massivos de arquivos de WAL ou tabelas gigantescas através do canal SSH, o daemon do SSH (sshd) passa a consumir ciclos severos de processamento. Em ambientes de produção, é comum observar um núcleo inteiro de CPU travado em 100% de utilização apenas para realizar o envelopamento e a cifragem desse tráfego, criando um funil que impede o aproveitamento total da banda disponível.

Multiplexação e Controle de Fluxo Duplicado

O pgBackRest possui uma arquitetura altamente eficiente para gerenciar concorrência e paralelismo através do parâmetro process-max, distribuindo a carga de leitura do banco de dados em múltiplos processos. No entanto, ao rodar essa estrutura sobre o SSH, cria-se uma disputa oculta na pilha de rede.

O SSH tenta impor seu próprio controle de fluxo e gerenciar suas janelas de recepção de pacotes sobre uma massa de dados que o pgBackRest já está ativamente tentando otimizar. Essas camadas adicionais de controle, buffers e processos podem introduzir uma latência a mais na camada de transporte. O sistema operacional gasta tempo coordenando os dois mecanismos concorrentes, resultando na subutilização da largura de banda da rede.

O Overhead de Context Switching (Troca de Contexto)

O tráfego de dados via SSH impõe um caminho complexo dentro do servidor. Cada bloco de informação que sai do banco de dados precisa ser transferido do processo do pgBackRest para o daemon do SSH (mudança de contexto no espaço do usuário). Em seguida, o dado passa para o kernel do sistema operacional para ser entregue à placa de rede. No servidor de repositório, todo esse caminho reverso é executado.

Em volumes massivos de dados, essa constante troca de contexto no processador gera uma perda de eficiência severa. Trata-se de um desperdício invisível nos gráficos de monitoramento tradicionais, que não acusam falhas de rede ou de disco, mas subtraem a capacidade de vazão do sistema.

Por que o TLS Nativo (mTLS) desbloqueia a escala?

A virada de chave para contornar esse teto de desempenho sem comprometer a segurança da informação está na alteração do protocolo de transporte do pgBackRest, substituindo o túnel SSH pela comunicação nativa baseada em TLS mútuo (mTLS).

Comunicação Direta via Sockets TCP

Ao configurar o pgBackRest para utilizar TLS nativo (repo1-host-type=tls), elimina-se a figura do intermediário, o daemon do SSH. A aplicação passa a abrir conexões diretas via sockets TCP com o servidor de destino. A criptografia e a validação de identidade passam a ser tratadas diretamente na camada de rede da própria aplicação. Sem intermediários no espaço do usuário, o caminho do dado até a placa de rede torna-se linear e desobstruído.

Eficiência de CPU e Descarregamento por Hardware (Hardware Offloading)

Os protocolos TLS modernos (com destaque para o TLS 1.3) foram otimizados para a internet de alta velocidade. Além da evolução do software, a maioria dos processadores modernos adotados em servidores possui instruções nativas em nível de hardware (como o conjunto AES-NI) dedicadas a acelerar algoritmos criptográficos.

Ao migrar o transporte do pgBackRest para TLS, o processamento deixa de ser uma tarefa genérica de software e passa a usufruir do descarregamento por hardware (hardware offloading). Como consequência, a carga de CPU no servidor de banco de dados despenca drasticamente durante a janela de backup, preservando a capacidade computacional para o processamento de queries e transações da aplicação.

Previsibilidade e Linearidade de Performance

Com a remoção dos gargalos de concorrência e o alívio no processamento, o throughput (taxa de transferência) do backup passa a escalar de forma linear, respondendo diretamente à capacidade real dos discos e da rede. Se a infraestrutura dispõe de um link de 10Gbps, a comunicação via TLS é capaz de saturar essa banda de forma muito mais estável do que o SSH. Cenários reais de migração demonstram reduções drásticas no tempo total de execução, transformando janelas de backup que duravam horas em procedimentos concluídos em poucos minutos.

Sustentabilidade e Gestão de Capacidade

A otimização da camada de transporte de dados vai além do ganho técnico de performance; ela reflete diretamente nos indicadores de eficiência de recursos e na previsibilidade de custos operacionais de longo prazo.

  • Redução de falsos positivos no monitoramento: O pico de consumo de CPU gerado pelo processamento do SSH durante a madrugada frequentemente ultrapassa os limites de alerta em plataformas de observabilidade. Esses falsos positivos geram alertas desnecessários para os times de plantão (on-call), mascarando incidentes reais e causando fadiga de alertas. A normalização do consumo de recursos trazida pelo TLS devolve a estabilidade ao monitoramento.
  • Prevenção de upgrades desnecessários de hardware: É comum que equipes decidam realizar o upgrade de instâncias de banco de dados em ambientes de nuvem para classes de máquinas maiores e significativamente mais caras sob a justificativa de que a CPU atinge o limite máximo durante a madrugada. Identificar que o gargalo reside no transporte via SSH permite solucionar o problema de performance otimizando a configuração de software, gerando economia real e estendendo o ciclo de vida da infraestrutura atual com custo zero de hardware.

A Tomada de Decisão

A evolução da infraestrutura de banco de dados exige reavaliar continuamente as camadas de software que sustentam a operação. Para determinar se o seu ambiente atingiu o limite do modelo tradicional, recomendam-se duas ações práticas:

  1. O diagnóstico: Durante a próxima execução do backup principal pelo pgBackRest, analise os gráficos de consumo detalhado de CPU do servidor de banco de dados. Verifique se há um pico acentuado de consumo associado especificamente aos processos ssh ou sshd. Se um ou mais núcleos estiverem saturados por esses processos enquanto o throughput de rede permanece abaixo da capacidade nominal, seu ambiente atingiu o teto do SSH.
  2. A recomendação: Para ambientes que gerenciam bancos de dados PostgreSQL que já operam ou estão entrando na escala de Terabytes, ou onde o RTO precisa ser minimizado ao extremo, migrar o transporte do pgBackRest de SSH para TLS com certificados digitais não é apenas uma boa prática de segurança. É uma decisão de engenharia de performance indispensável para garantir a sustentabilidade e a previsibilidade da operação de dados.

Otimizar o backup em larga escala vai muito além de comprar mais hardware ou contratar links de rede mais velozes. Trata-se de remover os intermediários invisíveis da arquitetura de software para garantir que cada ciclo de processamento e cada Megabit contratado sejam convertidos em eficiência, segurança e disponibilidade real para o negócio. 

Quer receber conteúdos sobre engenharia e performance de PostgreSQL?

 

[Assine nossa newsletter]

Segurança e Performance no Judiciário: O impacto do Health Check Recorrente no TJPR

By Artigos

Como a automação estratégica e a engenharia da Timbira estão garantindo a estabilidade de um dos maiores parques PostgreSQL do judiciário brasileiro.

1. Visão Geral do Projeto

O Tribunal de Justiça do Paraná (TJPR) é uma instituição pilar do setor governamental, lidando com volumes massivos de dados críticos. Para sustentar a operação de suas múltiplas instâncias PostgreSQL, o TJPR buscou a Timbira para implementar uma camada de inteligência e observabilidade que fosse além do suporte reativo.

  • Cliente: Tribunal de Justiça do Paraná (TJPR)
  • Setor: Judiciário / Governamental
  • Escopo: 26 instâncias PostgreSQL de alta criticidade
  • Solução: Health Check Recorrente (HC 2.0)

2. O Desafio: Complexidade em Larga Escala

Gerenciar um ambiente com dezenas de instâncias de bancos de dados exige mais do que monitoramento em tempo real. O TJPR enfrentava um cenário de:

  • Falta de Visibilidade Profunda: Necessidade de uma análise contínua que identificasse gargalos silenciosos antes que se tornassem incidentes.
  • Desafio de Padronização: Manter a conformidade técnica e de segurança em um parque tecnológico vasto e heterogêneo.
  • Sobrecarga Operacional: A equipe interna precisava de um braço de engenharia especializado que trouxesse recomendações priorizadas e prontas para execução, permitindo foco na estratégia.

3. A Solução: Health Check Recorrente (Inteligência sob Demanda)

A Timbira implementou o Health Check Recorrente, um produto exclusivo que une a precisão da automação com o conhecimento em PostgreSQL de todo o nosso time.

A Abordagem Técnica:

  • Varreduras Bi-semanais: Coletas automatizadas 2x por semana para capturar flutuações de performance e segurança.
  • Análise Multicamadas: Avaliação do Sistema Operacional, configuração do Cluster PostgreSQL e integridade das Bases de Dados.
  • Ciclo de Melhoria Contínua: O TJPR passou a receber um Score de Conformidade mensal, com ações priorizadas por nível de criticidade.

“O modelo de análise recorrente preencheu uma lacuna na gestão do ambiente PostgreSQL que não conseguíamos cobrir sozinhos.” — Liderança Técnica do TJPR

4. Ganhos Estratégicos e Maturidade Tecnológica

Na etapa inicial, a Timbira realizou um diagnóstico em 12 instâncias críticas. O foco não foi apenas técnico, mas voltado à governança e à sustentabilidade do ecossistema de dados do Tribunal.

Os principais avanços alcançados incluíram:

  • Reforço no Ciclo de Atualizações: Direcionamento de um cronograma proativo de atualizações de versão, garantindo que o TJPR opere sempre com os patches de performance e segurança mais recentes da comunidade PostgreSQL.
  • Aprimoramento da Governança de Acessos: Recomendações de refinamento da estrutura de privilégios de usuários, aplicando o princípio do “menor privilégio” para fortalecer as camadas de segurança lógica e o controle de acessos da instituição.
  • Padronização e Previsibilidade: Implementação de um fluxo de análise periódica que transformou a gestão do banco de dados em uma atividade preditiva. A equipe técnica do TJPR passou a contar com subsídios técnicos antecipados, otimizando o planejamento de janelas de manutenção.
  • Eficiência Operacional: A introdução do Score de Conformidade permitiu que a liderança tivesse uma visão clara e executiva da saúde do ambiente, facilitando a priorização de investimentos e esforços humanos.

Impacto Consolidado: A primeira fase não apenas estabilizou o ambiente, mas estabeleceu um novo padrão de qualidade para a gestão de dados dentro do Tribunal,  assegurando a continuidade e integridade técnica para as operações judiciais.

5. O Próximo Nível: Expansão e Modernização

O sucesso da primeira fase consolidou o Health Check Recorrente como o padrão de observabilidade do TJPR. Com a Fase II já em curso, o produto tem como objetivo os seguintes benefícios:

  • Ampliar o Health Check Recorrente para todas as instâncias PostgreSQL, classificando cada servidor em um catálogo de criticidade que orienta quais ambientes devem ser priorizados na sequência de intervenções.
  • Criar um histórico de score de conformidade, permitindo monitorar a evolução da saúde dos bancos ao longo do tempo.
  • Gerar recomendações cruzadas que consideram tanto a condição da base de dados quanto do sistema operacional, facilitando decisões mais completas e proativas.

O resultado:  garantia de disponibilidade contínua, redução de intervenções manuais e uma infraestrutura preparada para sustentar o crescimento futuro.

6. O Veredito do Cliente

O sucesso da Timbira no TJPR demonstra como o monitoramento preditivo traz eficiência operacional contínua e tranquilidade à liderança:

“Era exatamente isso que estávamos precisando. O resultado foi além do esperado. A clareza na priorização das ações facilita muito a nossa tomada de decisão interna.” — Equipe Técnica, TJPR

Troque a sustentação reativa pela sustentabilidade do seu PostgreSQL, levando a inteligência proativa do Health Check Recorrente para a sua empresa.

Quero falar com a Timbira