Go + Postgres: ¿pgx directo o database/sql? (y cómo manejan el pool)
Camilo Restrepo@camilo_parce
Parce, sigo aprendiendo Go con tincho (gracias maestro) y ya estoy pasando un servicio pequeño de Node a Go. Tengo dudas con Postgres:
- ¿Usan
pgxdirecto (pgxpool) odatabase/sqlcon el driverpgx/v5/stdlib? Leí que pgx directo es más rápido pero no sé si vale la pena. - ¿Cuántas conexiones ponen en el pool? En Node tenía
max: 10en pg y no sé si en Go es igual. - ¿sqlc o escribir las queries a mano?
El servicio es una API de reservas, poco tráfico (unos 20 requests por segundo en pico, 4 réplicas). Lo que llevo:
pool, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer pool.Close()
¡Gracias pues!
Accepted answer
Buenísimo que estés migrando! Te respondo en orden:
1. Si es un servicio nuevo y solo Postgres, pgx directo con pgxpool. Tenés mejor soporte de tipos de Postgres (arrays, jsonb, uuid), COPY, LISTEN/NOTIFY y errores más claros. database/sql te conviene solo si querés poder cambiar de base o usás una librería que lo pide.
2. El pool: pgxpool por defecto usa el mayor entre 4 y la cantidad de CPUs. Para 20 rps sobra. Yo lo configuro en la URL:
postgres://user:pass@host:5432/reservas?pool_max_conns=10&pool_max_conn_idle_time=5m
Y ojo: pool_max_conns es POR INSTANCIA. Con tus 4 réplicas son 40 conexiones contra Postgres. Si después metés un pooler tipo PgBouncer en modo transaction, revisá el tema de los prepared statements.
3. sqlc, sin dudas. Escribís SQL de verdad, te genera el código Go tipado, y si cambiás una columna no compila. Para queries dinámicas (filtros opcionales) a veces escribo a mano.
Y pasale el ctx del request a todas las queries, como en el post de context 😉
Get the best of #codigo_en_espanol weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to commentAccepted answer
Martín Ferraro@tincho_go
Buenísimo que estés migrando! Te respondo en orden:
1. Si es un servicio nuevo y solo Postgres, pgx directo con pgxpool. Tenés mejor soporte de tipos de Postgres (arrays, jsonb, uuid), COPY, LISTEN/NOTIFY y errores más claros. database/sql te conviene solo si querés poder cambiar de base o usás una librería que lo pide.
2. El pool: pgxpool por defecto usa el mayor entre 4 y la cantidad de CPUs. Para 20 rps sobra. Yo lo configuro en la URL:
postgres://user:pass@host:5432/reservas?pool_max_conns=10&pool_max_conn_idle_time=5m
Y ojo: pool_max_conns es POR INSTANCIA. Con tus 4 réplicas son 40 conexiones contra Postgres. Si después metés un pooler tipo PgBouncer en modo transaction, revisá el tema de los prepared statements.
3. sqlc, sin dudas. Escribís SQL de verdad, te genera el código Go tipado, y si cambiás una columna no compila. Para queries dinámicas (filtros opcionales) a veces escribo a mano.
Y pasale el ctx del request a todas las queries, como en el post de context 😉
Camilo Restrepo@camilo_parce
Uff maestro, lo de 'por instancia' no lo había pensado. Ya mismo bajo el max. Y sqlc lo pruebo mañana. Gracias pues!! 🙌
Danny Cho@danny_cho_la
Translated. All correct. One more: set statement_timeout on the role so one bad query can't hold a pool connection forever. ALTER ROLE app SET statement_timeout = '5s'; has saved us more than once.
Felipe Araya@pipe_sre
desde el lado SRE, cachai: miren las conexiones activas en Postgres (pg_stat_activity) antes de subir el pool. la mitad de los incidentes que veo es alguien que subió el max a 100 'por si acaso'
Javier Montero@javi_montero
En Java se llama HikariCP y son los mismos errores. Lo de réplicas por conexiones se lo explico cada año a un equipo nuevo, ya me lo sé de memoria.