postgresql.conf de forma predeterminada no está roto, es prudente: está dimensionado para ejecutarse en una máquina mínima sin provocar que falle una instalación, no para manejar su tráfico de producción. Pasar de estos valores de compatibilidad a valores de producción se mide, no se puede adivinar. Para conocer el protocolo de medición en sí (carga realista, p50/p95/p99, resultados reproducibles), consulte nuestra metodología de referencia de backend . Este artículo detalla las configuraciones en sí, en el orden que más importan.
- Cinco proyectos, en orden: conexiones/agrupación, memoria, vacío automático, índices/consultas lentas, puntos de control/WAL.
max_connectionsyshared_buffersrequieren un reinicio completo del servidor; la mayoría de las demás configuraciones se cargan en caliente.- Nunca desactive el vacío automático en producción: el riesgo real no es la lentitud, sino el ajuste del ID de la transacción.
pg_stat_statementsdebe aparecer enshared_preload_librariesantes de que un simpleCREATE EXTENSIONrecopile algo.- El Advisor integrado en Aurabase Studio ya aplica parte de esta lista de verificación automáticamente: solicitudes que duran más de 150 ms, claves externas no indexadas, grupo de conexiones que supera el 80% de saturación.
Por qué los valores predeterminados de Postgres nunca son suficientes
postgresql.conf, en su estado predeterminado, está diseñado para no fallar nunca en una instalación, no para absorber su tráfico. El valor histórico de shared_buffers, 128 MB, permite que Postgres se inicie en una máquina mínima sin reservar recursos críticos. max_connections al 100 cabe en un pequeño servidor compartido. Ninguno de los dos fue elegido para su carga real.
Así que el problema no es que Postgres esté mal configurado de forma predeterminada: es que nunca estuvo configurado para usted. Las siguientes secciones repasan las configuraciones en el orden en que dan mejores resultados, desde el cuello de botella más común (las conexiones) hasta el más lento en aparecer (el WAL).
Tamaño max_connections y pooling antes que nada
El primer proyecto no es la memoria, son las conexiones. Cada conexión de Postgres abre un proceso de servidor dedicado que consume RAM y tiempo de CPU de contexto, incluso si está inactivo. Aumentar max_connections para evitar errores del tipo "demasiadas conexiones" cambia el problema: más allá de un cierto número de conexiones activas simultáneas, la contención de la CPU degrada la latencia de todas las solicitudes, incluidas las más rápidas.
El enfoque correcto invierte el orden habitual: escalar max_connections en la concurrencia real del servidor, luego absorber la concurrencia del lado de la aplicación con un pooler como PgBouncer en pool_mode=transaction. El pooler multiplexa cientos de conexiones de clientes en un puñado de conexiones de servidores realmente activas. Nuestro artículo dedicado detalla el mecanismo del modo de transacción y sus límites (declaraciones preparadas, ESCUCHAR/NOTIFY), y una comparación entre PgBouncer, Supavisor y PgCat para elegir la implementación.
max_connections es un parámetro de contexto "postmaster": cambiarlo requiere un reinicio completo del servidor, no una simple recarga. En instancias de Postgres dedicadas de Aurabase (planes Pro y Enterprise, un clúster CNPG por proyecto), esta configuración se configura por nivel de plan en lugar de dejarse en su valor predeterminado. Un reinicio no es una operación trivial para repetir en producción, lo que justifica esta elección por etapas en lugar de un valor fijo. La fórmula para elegir su propio valor, con sus límites, es tema de un artículo aparte: size max_connections.
Cuatro configuraciones de memoria pesan más que todas las demás combinadas: shared_buffers, effective_cache_size, work_mem y maintenance_work_mem. Los primeros tres determinan cuántos datos mantiene Postgres en la memoria antes de regresar al disco; el cuarto determina la velocidad de creación de un VACÍO o índice.
shared_buffers establece el caché interno compartido por todas las conexiones. El punto de referencia comúnmente documentado por el proyecto PostgreSQL es aproximadamente el 25% de la RAM disponible en un servidor de base de datos dedicado. Más allá de eso, las ganancias disminuyen y el caché del disco del sistema operativo toma el control. effective_cache_size no asigna nada: es una estimación, dada al planificador de consultas, de la memoria total disponible para el caché (Postgres y OS combinados). Su tamaño insuficiente empuja al programador hacia escaneos secuenciales, mientras que un índice almacenaría en gran medida en caché; el punto de referencia actual está entre el 50 y el 75% de RAM.
work_mem es la trampa más común. Este no es un límite global. Cada operación de clasificación o hash en una consulta puede consumir su propia parte y una consulta con múltiples combinaciones puede reservar su propia parte varias veces. Un valor demasiado generoso combinado con un max_connections alto puede agotar la RAM del servidor bajo carga simultánea, incluso si cada solicitud tomada de forma aislada parece razonable. maintenance_work_mem, por el contrario, puede ser mucho más generoso: sólo se aplica a las operaciones de mantenimiento (VACÍO, CREAR ÍNDICE), que rara vez son concurrentes entre sí.
Sólo shared_buffers requiere reiniciar. Los otros tres se recargan en caliente, incluso para una sesión aislada: SET work_mem = '64MB'; durante la duración de una única solicitud codiciosa, sin afectar la configuración global.
Autovacuum: ajusta los umbrales, nunca lo desactives
Nunca desactive el vacío automático en producción, ni siquiera temporalmente para "liberar recursos" durante una carga máxima. Postgres usa MVCC: cada ACTUALIZACIÓN y cada ELIMINACIÓN deja una línea muerta que solo el vacío puede recuperar. Sin él, las tablas se hinchan, los índices se degradan y los planes de ejecución se deterioran gradualmente, sin errores visibles hasta que es tarde.
El peligro más grave de una aspiradora automática deshabilitada o de tamaño insuficiente no es el rendimiento, sino la envoltura de ID de transacción. Después de un umbral, Postgres cambia toda la base de datos a solo lectura para evitar la corrupción de datos, hasta que se ejecuta un VACUUM manual. Se trata de un incidente de producción que es totalmente evitable mediante una configuración correcta.
El valor predeterminado deautovacuum_vacuum_scale_factor (20% de filas muertas antes de la activación) es adecuado para una tabla pequeña, no para una tabla de varios millones de filas que requiere mucha escritura. En una tabla de 10 millones de filas, este 20% representa 2 millones de filas muertas acumuladas antes del primer paso. Reduzca este umbral tabla por tabla en lugar de cambiar el valor general de toda la base de datos.
El Advisor integrado en Aurabase Studio comprueba esta configuración en cada análisis del proyecto, al igual que las tablas sin claves primarias o claves foráneas no indexadas. Se trata de una señal explícita y no de una degradación silenciosa descubierta demasiado tarde.
Índice antes de agregar RAM
La mayoría de los problemas de latencia en producción no provienen ni de la CPU ni de la RAM: provienen de un índice ausente o mal elegido. Antes de tocar un solo parámetro de postgresql.conf, EXPLAIN (ANALYZE, BUFFERS) en la consulta en cuestión sigue siendo el diagnóstico más confiable. Reduce mucho la latencia de las solicitudes de Postgres antes de agregar recursos.
Un Seq Scan en una tabla de varios millones de filas, donde se esperaba un Index Scan, casi siempre indica un problema de índice. Con mayor frecuencia surgen tres causas: un índice faltante, un tipo de columna incompatible con el índice existente o estadísticas obsoletas después de una importación masiva sin ANALYZE. Agregar RAM o aumentar work_mem a veces oculta este síntoma en un pequeño volumen de datos; el problema reaparece tan pronto como la mesa crece.
Para localizar estas solicitudes sin buscarlas una por una, pg_stat_statements agrega las estadísticas de ejecución de todas las solicitudes del servidor. Un error común: la extensión primero debe aparecer en shared_preload_libraries, un parámetro de contexto "postmaster" que requiere un reinicio. Sin este paso, CREATE EXTENSION pg_stat_statements; tiene éxito silenciosamente pero no recopila nada.
Este es exactamente el error que devuelve el backend de Aurabase cuando esta extensión está ausente: un mensaje explícito en lugar de una lista vacía y silenciosa, que podría confundirse con "sin consulta lenta". Studio Advisor va más allá: clasifica automáticamente cualquier solicitud con un tiempo promedio superior a 150 ms como advertencia y superior a 500 ms como crítica. Estos umbrales se basan en las mismas estadísticas pg_stat_statements.
Puntos de control y WAL: suavizar la carga en lugar de sufrirla
Un punto de control obliga a Postgres a escribir en el disco todas las páginas modificadas en la memoria desde la anterior. Por defecto, este escrito puede centrarse en un período de tiempo demasiado corto. El resultado es un aumento notable en la latencia del disco en el lado de la aplicación, el tipo de desaceleración periódica que es difícil de relacionar con una solicitud específica.
checkpoint_completion_target controla la extensión de esta escritura en el intervalo entre dos puntos de control. Un detalle que falta en las listas de verificación anteriores: PostgreSQL 14, lanzado en 2021, cambió su valor predeterminado de 0,5 a 0,9. En una instancia de PostgreSQL 16, como los clústeres de inquilinos dedicados de Aurabase, esta configuración ya es correcta de forma predeterminada; ajustarlo manualmente solo tiene sentido en una versión anterior a la 14. Consulte nuestra comparación PostgreSQL 16 vs 17 vs 18 para ver otros cambios de versión que afectan el ajuste.
max_wal_size actúa en la misma dirección: un valor demasiado bajo activa puntos de control más frecuentes de lo esperado, incluso cuando aún no se alcanza checkpoint_timeout. Aumentarlo reduce la frecuencia de los puntos de control, a costa de un mayor tiempo de recuperación después de un accidente, ya que hay más WAL para reproducir. Un compromiso que se decidirá según su tolerancia a la indisponibilidad, no un valor universal.
El seguimiento no es un paso, es el bucle que cierra la lista de control
Esta lista de verificación no es una auditoría única que se debe verificar una vez antes de entrar en producción. Una base que duplica su volumen o un tráfico que triplica hace que los benchmarks elegidos al inicio queden obsoletos, muchas veces sin error explícito, sólo una degradación progresiva de la latencia p95.
Hay tres señales que merecen un seguimiento continuo. pg_stat_statements identifica solicitudes que se degradan con el tiempo. pg_stat_activity informa consultas bloqueadas o de ejecución anormalmente larga, y la proporción de conexiones activas con max_connections anticipa la saturación antes de que produzca errores en el lado de la aplicación.
La pestaña Observabilidad de Studio cubre parte de esta base para cualquier proyecto de Aurabase, sin necesidad de instalar herramientas de terceros. Enumera solicitudes lentas, le permite cancelar o finalizar una solicitud activa mediante PID y muestra un indicador de saturación del grupo que entra en advertencia por encima del 80 % de uso. En una instancia autohospedada, este mismo monitoreo se crea manualmente, con pg_stat_statements activado y una herramienta de monitoreo externa conectada.
Hoja de trucos: la lista de verificación completa
Ocho configuraciones, en el orden en que rinden más, con lo que necesita saber antes de tocarlas.
| conexiones_max | Reiniciar | Tamaño basado en competencia real, no en un número redondo; absorber el resto a través de un pooler en modo de transacción. |
|---|---|---|
| buffers_compartidos | Reiniciar | ≈ 25% de RAM dedicada a Postgres. |
| tamaño_caché_efectivo | caliente | ≈ 50 a 75% de RAM (Postgres + caché del sistema operativo combinados). |
| memoria_trabajo | Caliente / sesión | Cauteloso por defecto; pruebe hacia arriba consulta por consulta con SET. |
| mantenimiento_trabajo_mem | caliente | Más generoso que work_mem; acelera el VACÍO y CREAR ÍNDICE. |
| autovacuum_vacuum_scale_factor | Caliente, por mesa | Baje en tablas grandes con mucha escritura, nunca globalmente. |
| checkpoint_completion_target | caliente | 0.9 por defecto desde PostgreSQL 14; para comprobar especialmente en una versión anterior. |
| bibliotecas_precargadas_compartidas | Reiniciar | Debe incluir pg_stat_statements antes de cualquier análisis de consulta lento. |
Los umbrales citados aquí, como los 150 ms y el 80 % de saturación del grupo que monitorea Aurabase Studio Advisor, son un punto de partida verificado por código, no una verdad universal. Su cargo real sigue siendo el único juez final. Para dimensionar con precisión max_connections en lugar de seguir una regla general, el artículo dedicado detalla la fórmula y sus límites.
Preguntas frecuentes
Tres preguntas que surgen sistemáticamente una vez que se aplica la lista de verificación por primera vez.