Alojar PostgreSQL num VPS: dimensionar a memória e o disco

Uma base PostgreSQL rápida é uma base cujos dados consultados com frequência cabem em memória. Todo o dimensionamento parte daí: o volume da base, a parte que trabalha realmente, o número de ligações, e depois o disco e a sua margem. Este guia apresenta o método, as definições de partida para 4, 8 e 16 GB de memória, e as consultas que medem uma base existente.

Publicado a 29 de outubro de 2026 Por Leitura: 10 minutos

Todos os guias

O essencial

  1. Meça o volume da base e dos seus índices, e depois a parte consultada com frequência: é essa que tem de caber em memória.
  2. Ponto de partida: shared_buffers a 25 % da memória, effective_cache_size a 75 %, random_page_cost = 1.1 em SSD NVMe.
  3. Cada ligação é um processo: acima de algumas dezenas de ligações ativas, coloque o PgBouncer à frente da base.
  4. Disco: dados e índices a um ano, mais pelo menos 30 % de margem. Um disco cheio faz parar o PostgreSQL.
  5. A taxa de leitura em cache deve ficar acima de 99 %: abaixo disso, falta memória à base.
  6. Faça uma cópia de segurança diária com pg_dump, fora do servidor, e restaure-a com regularidade para a verificar.

Partir do volume útil

A memória de um servidor de base de dados serve antes de mais de cache: uma página lida em memória é servida muito mais depressa do que uma página lida em disco, mesmo NVMe. A pergunta não é, por isso, apenas «quanto pesa a base?», mas «que parte é lida com frequência?». Uma base de 50 GB da qual só os últimos doze meses são consultados trabalha talvez sobre 8 GB.

Numa base existente, duas consultas dão o volume total e as maiores tabelas, índices incluídos:

SQL (psql)
SELECT pg_size_pretty(pg_database_size(current_database()));

SELECT relname AS nome,
       pg_size_pretty(pg_total_relation_size(relid)) AS tamanho_com_indices
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 10;

Para uma base futura, estime tabela a tabela: número de linhas esperadas a um ano × tamanho médio de uma linha, e depois acrescente os índices, que pesam habitualmente de 30 a 100 % dos dados. Exemplo: 2 milhões de linhas por mês, de 500 bytes cada, fazem 12 GB de dados a um ano, e 18 a 24 GB com os índices.

A memória: as definições de partida

O PostgreSQL guarda as páginas lidas em dois níveis: a sua própria cache (shared_buffers) e a cache de ficheiros do sistema. A sua documentação recomenda partir de 25 % da memória para shared_buffers num servidor dedicado, e observa que acima de 40 % o ganho se torna raro: o resto beneficia a cache do sistema e as ordenações.

Parâmetro4 GB8 GB16 GBFunção
shared_buffers1 GB2 GB4 GBA cache própria do PostgreSQL
effective_cache_size3 GB6 GB12 GBA cache total estimada, que orienta a escolha dos planos de consulta
work_mem8 MB16 MB32 MBA memória de cada ordenação ou hash, por ligação: a multiplicar pelas consultas simultâneas
maintenance_work_mem256 MB512 MB1 GBA criação dos índices e o VACUUM
random_page_cost1.11.11.1O custo estimado de uma leitura aleatória: 4 por predefinição, muito acima do custo real em SSD NVMe

Estes valores pressupõem uma base de dados sozinha no servidor. Se a aplicação correr ao lado, retire primeiro a memória dela (processos, cache, compilação) e aplique as percentagens ao resto: um servidor de 8 GB que corre uma aplicação de 3 GB ajusta-se como uma base de 5 GB.

postgresql.conf, para um servidor de 8 GB dedicado à base de dados
shared_buffers = 2GB
effective_cache_size = 6GB
work_mem = 16MB
maintenance_work_mem = 512MB
random_page_cost = 1.1

shared_buffers só produz efeito quando o PostgreSQL reinicia; os outros parâmetros recarregam-se sem interrupção, com SELECT pg_reload_conf();.

Para saber se a memória chega, leia a taxa de leitura em cache. Numa aplicação de gestão ou num site, fica acima de 99 %:

SQL (psql)
SELECT round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 2) AS taxa_cache
FROM pg_stat_database
WHERE datname = current_database();

As ligações: um processo cada

O PostgreSQL abre um processo por ligação, e aceita 100 por predefinição (max_connections). Cada processo ocupa alguns megabytes em repouso, mais quando ordena ou faz hash de dados (work_mem, por vezes várias vezes na mesma consulta). Subir max_connections para 500 para acompanhar uma aplicação que abre muitas ligações é expor o servidor à falta de memória no primeiro pico.

A resposta certa é um agregador de ligações: o PgBouncer, em modo transaction, faz com que algumas dezenas de ligações reais sejam partilhadas por centenas de ligações da aplicação. As frameworks têm também o seu próprio pool (SQLAlchemy, Prisma, HikariCP): ajuste o seu tamanho ao número de vCPU do servidor da base de dados, e não ao número de utilizadores.

O disco: volume, margem e registo de transações

O disco de um servidor PostgreSQL guarda mais do que as tabelas:

A regra: o volume a um ano, mais pelo menos 30 % de margem. Não é uma questão de conforto: quando o disco que guarda o registo de transações se enche, o PostgreSQL interrompe o serviço para proteger os seus dados. Vigie a ocupação, e aumente o disco antes dos 80 %.

Do lado do desempenho, cada confirmação de transação espera pela escrita do registo em disco: a latência do armazenamento define o débito de escrita. É aí que um SSD NVMe faz a diferença, muito mais do que nas leituras, que a memória já serve.

O processador: uma consulta, um núcleo

Uma consulta PostgreSQL executa-se num único núcleo, exceto as grandes leituras que o motor paraleliza. O número de vCPU define portanto o número de consultas pesadas tratadas ao mesmo tempo: 2 vCPU chegam para uma aplicação de gestão no lançamento, 4 a 8 servem as bases muito solicitadas e os relatórios pesados.

Antes de acrescentar vCPU, procure as consultas que os consomem. A extensão pg_stat_statements ordena-as por tempo total:

postgresql.conf, e depois reinício
shared_preload_libraries = 'pg_stat_statements'
SQL (psql)
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

SELECT calls, round(total_exec_time) AS ms_total,
       round(mean_exec_time::numeric, 1) AS ms_medio, query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

O mesmo servidor que a aplicação, ou um servidor separado?

No lançamento, a base de dados no mesmo servidor que a aplicação é a escolha certa: nenhuma latência de rede entre as duas, uma ligação por socket Unix, um único servidor para copiar e vigiar. Separa-se quando as duas disputam os recursos: uma compilação ou um pico de tráfego que esvazia a cache da base, uma base que precisa de toda a memória para os seus dados, ou exigências de cópia de segurança diferentes.

Segurança e cópias de segurança

Terminal: exportação comprimida, e depois restauro numa base de teste
pg_dump -Fc -d minha_base -f minha_base-$(date +%F).dump
createdb minha_base_teste
pg_restore -d minha_base_teste minha_base-2026-10-29.dump

Uma base PostgreSQL rápida, no servidor certo

O VPS Pro corre com processadores Intel Xeon, memória ECC que corrige os erros em tempo real e SSD NVMe em espelho, com cada bloco de dados verificado por soma de controlo e uma cópia de segurança cifrada todas as noites, fora da máquina. A Assistência integral está incluída: quando a sua base abranda, analisamos as consultas lentas e os índices, e depois indicamos-lhe as definições que devolvem à sua aplicação toda a sua rapidez.

Descobrir o VPS Pro

Perguntas frequentes

Quanta RAM para o PostgreSQL?

A suficiente para que os dados consultados com frequência caibam em memória. Para uma aplicação de gestão no lançamento, 4 GB chegam, base e aplicação incluídas. Depois, meça a taxa de leitura em cache: enquanto ficar acima de 99 %, a memória chega.

Que valor para shared_buffers?

25 % da memória num servidor dedicado à base de dados, como recomenda a documentação do PostgreSQL: 1 GB em 4 GB, 2 GB em 8 GB, 4 GB em 16 GB. Acima de 40 %, o ganho torna-se raro, porque a cache do sistema faz o resto.

Quantas ligações PostgreSQL pode aceitar um VPS?

O PostgreSQL aceita 100 por predefinição, e cada ligação é um processo que consome memória. Em vez de subir esse teto, coloque um agregador como o PgBouncer à frente da base: algumas dezenas de ligações reais servem então centenas de ligações da aplicação.

É preciso separar a base de dados da aplicação?

No lançamento, não: no mesmo servidor, a base responde sem latência de rede e o conjunto copia-se de uma só vez. Separa-se quando uma prejudica a outra, por exemplo quando uma compilação ou um pico de tráfego esvazia a cache da base.

Contacte-nos