Rust 2026-10-15·Ievgenii Svyryd

Benchmark, ronda 2: Rust, Go y los frameworks de Rust, perfilados

Go y siete aplicaciones Rust (axum, actix-web, Rocket, Loco, Cot y Rustango sobre axum y actix) con las mismas reglas, con solo la aplicación bajo prueba en marcha, y los perfiles de CPU, syscalls y red que muestran en qué gasta su tiempo cada una.

Benchmark, ronda 2: Rust, Go y los frameworks de Rust, perfilados

Esta es la ronda 2 del benchmark justo. La ronda 2 cubre solo las aplicaciones compiladas: Go y siete aplicaciones Rust. Añade tres frameworks de Rust (Rocket, Loco, Cot) y perfiles de CPU, syscalls y red que muestran en qué gasta su tiempo cada aplicación.

Medido el 14 de octubre de 2026 en un Apple M3 Pro (VM de Docker con 12 CPU y 16 GB).

  • 441/s recolecciones de basura de Go en el índice en caché
  • 3 vs 9 viajes de ida y vuelta a Postgres por página de detalle: Go vs sqlx con el ping al adquirir
  • +45% Rustango en actix, página de índice, con una porción del pool por worker
  • 6.3–22.8 MiB memoria bajo carga, las ocho aplicaciones
  • 0 errores o respuestas no 200 en 144 ejecuciones

La configuración

El mismo blog que en la ronda 1: 10 autores, 30 etiquetas, 1 000 artículos, 2 600 enlaces artículo-etiqueta y 10 000 comentarios. Seis rutas: el índice (los últimos 20 artículos), una página de detalle de artículo con todos sus comentarios, una página de etiqueta, el índice y la página de detalle desde una caché de páginas en Redis, y /compute (suma de los primos menores que 20 000, sin base de datos).

Ocho aplicaciones:

  • Go: net/http de la stdlib, pgx v5, go-redis
  • axum + sqlx y actix + sqlx: sqlx puro con el texto SQL de Go, plantillas Tera
  • Rocket: rocket_db_pools (sqlx) y rocket_dyn_templates (Tera)
  • Rustango sobre axum y sobre actix-web: el ORM de Rustango y su caché de páginas
  • Loco: SeaORM, Tera
  • Cot: el ORM de Cot, plantillas askama

Las reglas:

  • La aplicación recibe 4 CPU (fijadas a los núcleos 0–3) y 2 GB de RAM, con 4 workers. PostgreSQL 16 y Redis 7 corren en los núcleos 4–7, el generador de carga oha en los núcleos 8–11.
  • Solo corre la aplicación bajo prueba; las demás están detenidas. Entre aplicaciones, el número de conexiones de Postgres vuelve a su valor base.
  • Pools: 16 conexiones máx., 4 mín.
  • Antes de cualquier carga, cada página de cada aplicación se compara con el HTML de Go. Una discrepancia detiene la ejecución.
  • Sin compresión. 5 s de calentamiento y luego tres ejecuciones de 20 s por endpoint con 50 conexiones; cuenta la mediana.

El banco de pruebas

DOCKER NETWORK · NO COMPRESSION oha load generator 8 9 10 11 CORES 8–11 App under test 4 CPUs · 2 GB · 4 workers 0 1 2 3 CORES 0–3 · PINNED Databases Postgres · MySQL · Redis 4 5 6 7 CORES 4–7 HTTP 50 conns SQL · cache 16 conns ✓ HTML parity vs Go, before any load PER ENDPOINT 5 s run 1 · 20 s run 2 · 20 s run 3 · 20 s WARM-UP → MEDIAN OF 3 · HTTP 200 ONLY DOCKER NETWORK oha load generator CORES 8–11 8 9 10 11 HTTP 50 conns ✓ HTML parity vs Go App under test 4 CPUs · 2 GB · 4 workers CORES 0–3 0 1 2 3 SQL · cache · 16 conns Databases PostgreSQL · MySQL · Redis CORES 4–7 4 5 6 7 PER ENDPOINT 20 s 20 s 20 s 5 S WARM-UP → MEDIAN OF 3

El mismo banco de pruebas que en la ronda 1. La ronda 2 usa solo PostgreSQL y Redis (sin MySQL).

Versiones

  • Go 1.25.14, pgx v5.7.2, go-redis v9.7.0
  • rustc 1.99.0; axum 0.8.9, actix-web 4.16.0, tokio 1.53, sqlx 0.8.6, Tera 1.20.1
  • Rocket 0.5.1 (sqlx 0.7.4, hyper 0.14)
  • Loco 1.2.0 (SeaORM 2.0.4, sqlx 0.9.0)
  • Cot 0.7.0 (sqlx 0.9.0, askama 0.16.1)
  • Rustango sin ping al adquirir, con una caché de páginas que guarda bytes sin procesar y una conexión del pool por petición (hallazgo 5)

Ajustes que no se pudieron igualar

AjusteAplicacionesPor qué
El pool hace ping a Postgres en cada préstamo (sqlx test_before_acquire)Rocket, Loco, CotNo hay ajuste para desactivarlo. Está desactivado en axum + sqlx, actix + sqlx y Rustango.
10 conexiones de pool en lugar de 16CotCot no tiene ajustes de pool.
Una porción del pool por worker (4 de las 16 conexiones) y una conexión de Redis por workeractix + sqlx, Rustango · actixUn pool compartido es más lento en actix-web (ver hallazgo 6).
sqlx 0.7.4 y hyper 0.14RocketFijados por Rocket 0.5.1.
5, 5 y 7 consultas por página de índice, detalle y etiqueta en lugar de 3, 3 y 4CotSu API de consultas no puede expresar las consultas de Go (ver hallazgo 9).
askama en lugar de TeraCotEl motor de plantillas de Cot.

Resultados

Peticiones por segundo, más es mejor.

Páginas sin caché

Mismo HTML, 50 conexiones, PostgreSQL en cada petición

req/s · higher is better
  • Go
  • Rust
  • Rustango
  • Loco
  • Cot
Índice
Go 8 741 req/s
axum + sqlx 14 140 req/s
actix + sqlx 14 408 req/s
Rocket 13 316 req/s
Rustango · axum 14 686 req/s
Rustango · actix 17 401 req/sfastest
Loco 10 290 req/s
Cot 2 018 req/s
Detalle
Go 22 607 req/s
axum + sqlx 22 842 req/s
actix + sqlx 21 630 req/s
Rocket 24 561 req/s
Rustango · axum 25 788 req/s
Rustango · actix 27 292 req/sfastest
Loco 15 635 req/s
Cot 9 282 req/s
Etiqueta
Go 6 386 req/s
axum + sqlx 6 467 req/s
actix + sqlx 6 628 req/s
Rocket 6 836 req/s
Rustango · axum 7 090 req/sfastest
Rustango · actix 7 056 req/s
Loco 5 604 req/s
Cot 3 065 req/s

Mediana de tres ejecuciones de 20 s con 50 conexiones. Solo corría la aplicación bajo prueba. 0 respuestas no 200, 0 errores.

Páginas en caché

Servidas desde una caché de páginas en Redis, sin SQL

req/s · higher is better
  • Go
  • Rust
  • Rustango
  • Loco
  • Cot
Índice, en caché
Go 91 839 req/s
axum + sqlx 198 669 req/s
actix + sqlx 226 887 req/s
Rocket 138 224 req/s
Rustango · axum 174 501 req/s
Rustango · actix 231 975 req/sfastest
Loco 153 243 req/s
Cot 190 245 req/s
Detalle, en caché
Go 141 574 req/s
axum + sqlx 214 871 req/s
actix + sqlx 240 161 req/s
Rocket 155 691 req/s
Rustango · axum 192 897 req/s
Rustango · actix 242 609 req/sfastest
Loco 170 158 req/s
Cot 203 119 req/s

Mediana de tres ejecuciones de 20 s con 50 conexiones. Solo corría la aplicación bajo prueba. 0 respuestas no 200, 0 errores.

Cómputo

Primos menores que 20 000, sin base de datos

req/s · higher is better
  • Go
  • Rust
  • Rustango
  • Loco
  • Cot
Go 16 580 req/sfastest
axum + sqlx 14 963 req/s
actix + sqlx 14 578 req/s
Rocket 14 696 req/s
Rustango · axum 14 799 req/s
Rustango · actix 14 710 req/s
Loco 14 184 req/s
Cot 15 330 req/s

Mediana de tres ejecuciones de 20 s con 50 conexiones. Solo corría la aplicación bajo prueba. 0 respuestas no 200, 0 errores.

Latencia, p50 / p99 en ms:

AplicaciónÍndiceDetalleEtiquetaÍndice, en cachéDetalle, en cachéCómputo
Go5.50 / 9.961.91 / 5.027.61 / 11.720.35 / 2.730.24 / 2.052.37 / 10.75
axum + sqlx3.49 / 4.712.14 / 3.607.42 / 13.890.24 / 0.530.22 / 0.513.35 / 6.07
actix + sqlx3.32 / 6.382.21 / 4.307.23 / 13.230.20 / 0.500.19 / 0.453.41 / 4.97
Rocket3.66 / 5.831.97 / 3.587.14 / 11.550.34 / 0.700.30 / 0.673.40 / 6.14
Rustango · axum3.28 / 5.651.83 / 3.556.90 / 11.180.27 / 0.590.25 / 0.523.38 / 6.09
Rustango · actix2.80 / 4.511.77 / 3.376.91 / 11.530.20 / 0.480.19 / 0.453.41 / 3.96
Loco4.62 / 10.842.99 / 6.348.67 / 14.520.30 / 0.790.28 / 0.623.48 / 6.90
Cot23.35 / 50.365.28 / 8.0215.57 / 27.060.25 / 0.500.23 / 0.523.27 / 5.85

Memoria

Memoria bajo carga

Memoria residente del contenedor de la aplicación en el índice sin caché

MiB · lower is better
  • Go
  • Rust
  • Rustango
  • Loco
  • Cot
Go 22.8 MiB
axum + sqlx 7.6 MiB
actix + sqlx 7.2 MiB
Rocket 8.7 MiB
Rustango · axum 6.9 MiB
Rustango · actix 6.3 MiBlowest
Loco 12.0 MiB
Cot 22.6 MiB

docker stats, la muestra con mayor CPU de seis tomadas durante la primera ejecución del índice.

Go y Cot son los que más usan. El índice de Cot carga los 1 000 artículos con su contenido en cada petición (hallazgo 9).

Hallazgos

Cada hallazgo indica qué se midió, por qué ocurre y cómo se demostró. Los perfiles son ejecuciones únicas de 25 s en el mismo banco de pruebas, una aplicación a la vez, así que sus req/s difieren un poco de la ejecución justa de arriba. Cuando una causa no está probada, se indica.

1. Cómputo: Go es un 8–17% más rápido

Qué. Go sirve 16 580 req/s en /compute; las aplicaciones Rust sirven 14 184–15 330.

Por qué. Ambos bucles compilados tienen 8 instrucciones, un sdiv de 64 bits y una comprobación de división por cero. La diferencia está en el orden de las instrucciones que elige LLVM. Qué detalle microarquitectónico de la CPU hace más lento ese orden está sin probar: la VM de Docker no tiene contadores de hardware.

Cómo se demostró. El bucle solo, en un núcleo, fuera de HTTP:

Bucle de primos, una llamada

Un solo núcleo, sin HTTP

microsegundos · lower is better
  • Go
  • Rust
Go 194 microsegundoslowest
Rust 224 microsegundos
Rust, orden de instrucciones de Go 194 microsegundoslowest

Rust con exactamente el orden de instrucciones de Go tarda lo mismo que Go. El resto de cada petición es más barato en Rust: 8 µs frente a los 14 µs de Go.

Latencia. Go tiene el p50 más bajo pero el p99 más alto. La latencia media es 50 / req/s para cada aplicación, así que las medias siguen al rendimiento; la diferencia está en la dispersión. Go atiende las peticiones fuera de orden: p10 0.56 ms, p99 10.75 ms. Las aplicaciones Rust atienden casi en orden de llegada: axum + sqlx p10 1.85 ms, p99 6.07 ms. Por qué el p99 de Go ronda los 10 ms está sin probar.

2. Páginas en caché: el recolector de basura de Go

Qué. En el índice en caché Go sirve 91 839 req/s; axum + sqlx sirve 198 669.

Por qué. Go ejecuta 441 recolecciones de basura por segundo en esta ruta, y las pausas stop-the-world suman cerca del 10% del tiempo. El resto es CPU por petición: 27.2 µs en Go frente a 14.6 µs en axum + sqlx.

Cómo se demostró. Subir GOGC elimina la mayor parte de la diferencia:

Go, índice en caché, GC ajustado

Antes: GOGC=100 por defecto. Ejecuciones de perfilado.

beforeafter
GOGC=400, req/s 97 289 req/s 144 083 req/s +48%
GC casi desactivado, req/s 97 289 req/s 159 734 req/s +64%
GC casi desactivado, p99 2.48 ms 0.90 ms −64%

A dónde va la CPU restante, por petición en el índice en caché:

Goaxum + sqlx
CPU de la aplicación27.2 µs14.6 µs
Ruta de escritura del kernel10.6 µs6.9 µs
Syscalls10.7 (6.6 read, 2.9 write)4.8 (2.0 recvfrom, 1.4 writev)
CPU de Redis6.8 µs2.5 µs
Tráfico de Redisgo-redis: un GET por peticiónuna conexión, GET de muchas peticiones agrupados en un solo pipeline

Go: CPU por petición en caché

27.2 µs en total

  • 39%Ruta de escritura del kernel, 10.6 µs
  • 61%Todo lo demás, 16.6 µs

axum + sqlx: CPU por petición en caché

14.6 µs en total

  • 47%Ruta de escritura del kernel, 6.9 µs
  • 53%Todo lo demás, 7.7 µs

3. Página de detalle: viajes de ida y vuelta a Postgres

Qué. Página de detalle: Go 22 607, axum + sqlx 22 842, Rocket 24 561, Rustango · axum 25 788 req/s. Todas envían las mismas tres consultas.

Por qué. El número de viajes de ida y vuelta a Postgres es distinto. pgx envía uno por consulta. sqlx añade uno cuando se toma una conexión del pool (el ping al adquirir) y otro cuando vuelve. axum + sqlx toma una conexión por consulta, así que paga en cada consulta; Rocket y Rustango toman una conexión por página, así que pagan una sola vez. Cada viaje extra cuesta unos 10 µs de CPU de Postgres.

Cómo se demostró. Captura del protocolo de Postgres durante la carga, contando los mensajes ReadyForQuery por página:

Viajes de ida y vuelta a Postgres por página de detalle

Captura de red, las mismas tres consultas; ping = ping al adquirir de sqlx

viajes de ida y vuelta · lower is better
  • Go
  • Rustango
  • Rust
Go · pgx 3 viajes de ida y vueltalowest
Rustango 4 viajes de ida y vuelta
Rocket 5 viajes de ida y vuelta
axum + sqlx, ping desactivado 6 viajes de ida y vuelta
axum + sqlx, ping activado 9 viajes de ida y vuelta

La página de índice muestra las mismas cifras.

axum + sqlx: ping al adquirir desactivado

Ejecuciones de perfilado

beforeafter
Detalle, req/s 18 222 req/s 23 472 req/s +29%
Detalle, CPU de Postgres 166.6 µs/req 134.3 µs/req −19%
Índice, req/s 12 140 req/s 14 419 req/s +19%
Índice, CPU de Postgres 237.9 µs/req 208.5 µs/req −12%

Tres viajes menos ahorran 29–32 µs de CPU de Postgres por página: unos 10 µs cada uno.

Go hace menos viajes de ida y vuelta pero aquí no es el más rápido: su recolector de basura lo detiene cerca del 9% del tiempo en esta ruta.

4. Página de índice: GC y renderizado de plantillas

Qué. Página de índice: Go 8 741 req/s, axum + sqlx 14 140.

Por qué. Dos causas medidas. Otra vez el recolector de basura de Go (las pausas suman cerca del 8% del tiempo en esta ruta), y el renderizado de plantillas: html/template de Go usa reflexión y cuesta 167 µs por petición; serde + Tera en Rust cuestan 72 µs.

Cómo se demostró.

Go, índice sin caché, GC ajustado

Antes: GOGC=100 por defecto. Ejecuciones de perfilado.

beforeafter
GOGC=400, req/s 9 359 req/s 12 848 req/s +37%
GC casi desactivado, req/s 9 359 req/s 13 967 req/s +49%

Renderizado de plantillas, página de índice

CPU por petición, según el perfil de CPU

microsegundos · lower is better
  • Go
  • Rust
Go · html/template 167 microsegundos
Rust · serde + Tera 72 microsegundoslowest

En qué gasta CPU axum + sqlx en el índice, según su perfil (las partes se solapan: las asignaciones ocurren dentro de sqlx y Tera):

  • sqlx: unos 112 µs por petición, de los cuales unos 25 µs son el ping cuando una conexión vuelve al pool
  • malloc de glibc: unos 56 µs
  • sendto del kernel: 38 µs

5. Rustango: qué cambiaron las correcciones

Qué. Los perfiles de Rustango antes de estas correcciones mostraban cuatro costes. Tres están corregidos:

Coste antesParte de CPUCorrección
Un préstamo del pool por cada consulta19–35%Una conexión del pool por petición: detalle +26%
Ping a Postgres en cada préstamo8–16%Ping desactivado por defecto
CachePageLayer guarda las páginas como JSON + base64~12–20% por acierto de cachéPáginas guardadas como bytes sin procesar
Querysets reconstruidos y compilados en cada petición~2%Aún sin corregir

Rustango · axum, antes → después de las correcciones

Ejecuciones de perfilado, una aplicación a la vez

beforeafter
Índice, req/s 11 215 req/s 15 849 req/s +41%
Detalle, req/s 17 267 req/s 28 097 req/s +63%
Índice, CPU de la aplicación 286.6 µs/req 220.8 µs/req −23%
Detalle, CPU de la aplicación 164.7 µs/req 110.4 µs/req −33%

En la ejecución justa, Rustango sobre actix-web y sobre axum son las dos aplicaciones más rápidas en las tres páginas sin caché.

Pendiente. En el índice en caché Rustango · axum sirve 174 501 req/s frente a los 198 669 de axum + sqlx. Esta diferencia aún no se ha perfilado.

6. actix-web: un pool compartido es lento

Qué. En la ronda 1 las aplicaciones actix-web quedaban por detrás de axum en las páginas sin caché y usaban menos del 300% de su presupuesto de CPU del 400%.

Por qué. Con un único pool compartido, cada consulta despierta un hilo de otro runtime. Dar a cada worker de actix su propia porción del pool (4 de las 16 conexiones) y su propia conexión de Redis lo soluciona. El mecanismo, que un socket lo gestiona el runtime que lo abrió, es una inferencia; el efecto está medido.

Cómo se demostró. Mismas aplicaciones, pool compartido frente a porciones por worker:

Pool compartido → una porción del pool por worker

Ejecuciones de perfilado

beforeafter
actix + sqlx
Índice 11 094 req/s 15 108 req/s +36%
Detalle 18 080 req/s 23 330 req/s +29%
Índice, en caché 192 604 req/s 238 884 req/s +24%
Rustango · actix
Índice 12 052 req/s 17 454 req/s +45%
Detalle 23 032 req/s 28 693 req/s +25%
Índice, en caché 190 889 req/s 237 962 req/s +25%
Cambios de contexto por peticiónPool compartidoPool por worker
actix + sqlx, índice4.041.45
actix + sqlx, detalle3.571.64
Rustango · actix, índice2.700.81
Rustango · actix, detalle2.341.03

Unas 2.5× menos cambios de contexto por petición. Más workers no ayudan: 8 workers con un pool compartido alcanzan 11 904 req/s en el índice de actix + sqlx (4 workers, compartido: 11 094).

7. Rocket: fuerte en páginas con base de datos, el más lento en caché

Qué. Rocket: detalle 24 561 req/s, por delante de Go y de las aplicaciones con sqlx puro; índice en caché 138 224, el resultado de Rust más lento.

Por qué. En las páginas con base de datos Rocket toma una conexión por página y hace 5 viajes de ida y vuelta (hallazgo 3). En las páginas en caché gasta 24.1 µs de CPU por petición frente a los 14.6 µs de axum + sqlx, con 8.1 syscalls por petición frente a 4.8. El perfil muestra un writev extra (2.24 por petición frente a 1.36) y contención en malloc; las llamadas a futex son 2.88 por petición frente a 0.91.

Cómo se demostró. Contabilidad de CPU, recuento de syscalls y perfiles de CPU en el índice en caché.

8. Loco

Qué. Loco: índice 10 290, detalle 15 635, índice en caché 153 243 req/s.

Por qué. SeaORM envía el mismo número de consultas que Go. En las páginas en caché Loco gasta 21.0 µs por petición: 2.4 µs más en malloc y 1.2 µs más en middleware que axum + sqlx. En las páginas con base de datos el ping al adquirir no se puede desactivar (el hallazgo 3 muestra su coste en sqlx).

Cómo se demostró. Contabilidad de CPU y perfiles de CPU en el índice en caché. Las páginas con base de datos de Loco no se perfilaron, así que cuánto de esa diferencia explica el ping está sin probar.

9. Cot: la API de consultas marca el límite

Qué. Cot: índice 2 018, detalle 9 282, etiqueta 3 065 req/s, pero índice en caché 190 245.

Por qué. La API de consultas de Cot solo tiene filter, limit y offset: no hay ORDER BY, JOIN, IN ni COUNT. Para mostrar los últimos 20 artículos, el índice carga los 1 000 artículos con su contenido. Las páginas necesitan 5, 5 y 7 consultas en lugar de 3, 3 y 4. La memoria bajo carga es de 22.6 MiB. Las páginas en caché no tocan el ORM y son rápidas: 16.4 µs de CPU por petición.

Cómo se demostró. Recuento de consultas a partir del código, memoria de la ejecución justa, contabilidad de CPU en el índice en caché.

10. Memoria

Ver el gráfico de memoria de arriba. Seis de las aplicaciones Rust usan 6.3–12.0 MiB bajo carga. Go usa 22.8 MiB. Cot usa 22.6 MiB; su índice carga todos los artículos en cada petición (hallazgo 9).

11. Costes compartidos

Dos costes aparecen en todas las aplicaciones Rust y no pertenecen a ningún framework:

  • Renderizado con Tera: cerca del 18–20% de la CPU en las páginas sin caché
  • malloc de glibc: cerca del 12%

Un asignador más rápido como mimalloc o jemalloc podría reducir el segundo. Esto está sin probar.

Limitaciones

  • Un solo equipo: un Apple M3 Pro. Otras CPU pueden ordenar los resultados de otra manera, sobre todo en cómputo (hallazgo 1).
  • Una carga de solo lectura: sin escrituras ni transacciones.
  • Las aplicaciones corren en la VM de Docker en macOS, no en Linux bare-metal. La VM no tiene contadores de rendimiento por hardware.

Conclusión: por qué Rustango en actix-web se volvió mucho más rápido

Rustango · actix, página de índice

Tres ejecuciones: la ronda 1, una ejecución de perfilado y la ejecución justa de esta ronda

req/s · higher is better
Ronda 1 (0.60.6) 6 341 req/s
Correcciones, pool compartido 12 052 req/s
Correcciones, pool por worker 17 401 req/sfastest

Dos cambios, en dos sitios.

1. Correcciones en Rustango. Ayudan tanto en axum como en actix-web:

  • Cada columna se decodifica una sola vez, según su tipo. Antes, la decodificación ocupaba el 46% de la CPU.
  • Sin ping antes de cada préstamo del pool: un viaje de ida y vuelta a Postgres menos por consulta.
  • Una conexión del pool por petición: las consultas de una página comparten una conexión, en lugar de un préstamo y un ping de devolución cada una.

2. La configuración de actix-web. axum ejecuta un único runtime de Tokio compartido y multihilo. actix-web ejecuta un runtime de un solo hilo por worker. Con un pool compartido por todos los workers, el socket de una conexión sigue gestionado por el runtime que lo abrió, así que cuando otro worker usa esa conexión, cada lectura y escritura despierta al otro hilo. La aplicación hace entonces 2.5× más cambios de contexto y usa cerca del 280% de sus 4 CPU. Una porción del pool (4 de las 16 conexiones) y una conexión de Redis por worker eliminan estos saltos entre hilos:

  • Rustango · actix: índice 12 052 → 17 454, detalle 23 032 → 28 693, índice en caché 190 889 → 237 962 req/s
  • actix + sqlx: índice 11 094 → 15 108 req/s
  • 8 workers con un pool compartido no ayudaron: 11 904 req/s en el índice de actix + sqlx

La mejora de velocidad y la caída de los cambios de contexto están medidas. La propiedad de los sockets es la mejor explicación, pero no está probada directamente. axum no tiene este problema, porque todas sus tareas corren en un único runtime compartido.

En la práctica: en actix-web, crea el pool de base de datos dentro de cada worker, no una sola vez para todos los workers.

Contacto →