Se abre en una pestaña nueva
0% comisión por venta. Sin letra chica Tú vendes, nosotros nos encargamos de todo lo demás Implementación guiada según alcance y plan

Laboratorio

Probamos Chatwoot en Hetzner y Netcup: CPU, RAM y respuesta con 60 agentes simulados

Dos instancias ARM64 y un perfil sintético de Chatwoot. Publicamos respuesta, recursos y colas con repeticiones, método y límites.

Explorar más guías
Portada de la prueba de Chatwoot en Hetzner y Netcup con 60 agentes simulados y una captura de demostración de su interfaz en español.

Volver al Laboratorio · Laboratorio SuperPyme / Aplicaciones / Chatwoot

En las dos instancias ARM64 probadas, Hetzner respondió más rápido y empleó menos CPU en el control adicional. La RAM máxima muestreada fue muy parecida. Aumentar los trabajadores ayudó a las colas de Netcup, pero no mejoró todas las operaciones por igual.

Ensayo: 21 de octubre de 2026 · Chatwoot Community 4.18.0 · Datos sintéticos

¿Basta mirar cuántas vCPU y cuánta memoria anuncia un servidor para elegir dónde alojar Chatwoot? La pregunta tiene una consecuencia concreta: una instalación compartida combina procesos web, trabajos de fondo, PostgreSQL y Redis. Más memoria disponible no implica que esa aplicación responda antes, y dar más CPU a un proceso tampoco equivale a iniciar más procesos.

En nuestra comparación de servidores del 19 de octubre publicamos compresión y hashing con un máximo de dos hilos. Aquellas muestras se conservan. No medían Chatwoot y no permiten convertir sus resultados en una cantidad de empresas alojadas. Esta nueva serie añade evidencia de aplicación, con solicitudes HTTP, notificaciones, recursos y colas.

El aporte de esta comparación es mostrar qué cambió al variar los trabajadores y después ampliar conjuntamente los límites de PostgreSQL y Redis. Publicamos las dos repeticiones de cada ajuste, el timeout registrado y el alcance de las notificaciones observadas.

El resultado del control adicional

El control mantuvo cuatro procesos Sidekiq y seis procesos Puma. Se amplió el tope de PostgreSQL a 2 vCPU y el de Redis a 1 vCPU, en ambos servidores. Cada instancia ejecutó dos rondas de 60 segundos nominales de carga y 20 segundos de observación de la cola. Esta tabla combina las respuestas HTTP satisfactorias de ambas rondas.

Control adicional, dos repeticiones por host. Percentiles HTTP sobre todas las respuestas satisfactorias, no media de percentiles.
MétricaNetcup ARM 8000Hetzner CAX41Base del cálculo
Listar conversaciones, p952,496 s0,805 s120 respuestas 2xx por host
Leer mensajes, p950,303 s0,104 s720 respuestas 2xx por host
Escribir sin archivo, p950,810 s0,314 s336 respuestas 2xx por host
CPU media muestreada3,258 vCPU2,000 vCPUMedia de las dos medias por ronda
RAM máxima muestreada4,397 GiB4,383 GiBMayor suma simultánea en las muestras
Errores HTTP001.200 solicitudes por host en el control
Pendientes tras 20 s de drenaje00Máximo entre las dos rondas

En ese control, Hetzner empleó 38,6 % menos CPU media muestreada que Netcup. Los p95 de listar, leer y escribir fueron entre 61,2 % y 67,7 % menores. Es una reducción de esos tiempos y de ese consumo, no un porcentaje de capacidad total ni una velocidad universal del servidor.

p95 de listado, lectura y escritura, con los valores combinados y las dos repeticiones de ambos servidores.
Figura 1. El rombo representa el p95 combinado, el círculo la primera repetición y el triángulo la segunda. Los puntos separados hacen visible la variación.

El p95 es un punto de una distribución: aproximadamente el 95 % de las respuestas satisfactorias quedan en ese tiempo o por debajo. No describe la respuesta más lenta. Tampoco incluye el timeout como si hubiera sido una respuesta rápida: los errores se contabilizan aparte.

CPU media 3,258 frente a 2,000 vCPU y RAM máxima muestreada 4,397 frente a 4,383 GiB, Netcup y Hetzner respectivamente.
Figura 2. Las barras resumen el control y los puntos conservan las dos rondas. La memoria incluye la caché contabilizada por cgroup.

Dos ARM64 de 16 vCPU, con diferente capacidad de memoria

Recursos y condiciones de las instancias del ensayo del 21 de octubre. GB nominales y GiB detectados se muestran por separado.
Instancia públicavCPU del invitadoRAM nominal / detectadaModelo virtual / kernelCondición de fondo
Netcup ARM 80001664 GB / 62,65 GiBNeoverse-N1 / 7.0.0-38-genericServicios productivos con poca carga de fondo.
Hetzner CAX411632 GB / 30,53 GiBNeoverse-N1 / 7.0.0-30-genericServidor nuevo, sin servicios productivos.

Ambos invitados reportaban Neoverse-N1. Esto acredita el modelo virtual expuesto al sistema invitado, no la identidad o disponibilidad exclusiva del procesador físico. No es una comparación de ARM frente a AMD. Netcup tenía servicios productivos con poca carga de fondo; Hetzner estaba vacío. Los kernels diferían en revisión. Estas condiciones impiden atribuir toda la diferencia a una sola característica del hardware.

Usamos las mismas imágenes ARM64 de Chatwoot Community 4.18.0, PostgreSQL 16 con pgvector y Redis, fijadas por digest. Las referencias exactas están en el protocolo y datos descargables, ZIP. La CPU y la RAM publicadas pertenecen a los contenedores sintéticos; no suman todas las aplicaciones productivas del host.

Configuración del control. La serie inicial conserva la RAM y cambia PostgreSQL a 0,75 vCPU y Redis a 0,25 vCPU.
ComponenteProcesos e hilosTope de CPUTope de RAM
Web6 procesos Puma; 5 hilos por proceso6 vCPU3,500 GiB
Sidekiq, cada trabajador1 proceso; 5 hilos1 vCPU1,500 GiB
PostgreSQL, controlshared_buffers=256MB; max_connections=802 vCPU2,000 GiB
Redis, controlmaxmemory=192mb; noeviction1 vCPU0,250 GiB
Total con cuatro SidekiqTopes sumados, sin reserva física13 vCPU11,750 GiB

Los topes del control sumaban 13 vCPU y 11,75 GiB. Son límites configurados, no una reserva de núcleos físicos ni el consumo observado. El conjunto consumió aproximadamente 4,4 GiB de RAM como máximo muestreado en ambos equipos. La documentación de cgroup v2 define los contadores de CPU y memoria usados para esta lectura.

La RAM adicional de Netcup seguía siendo capacidad disponible para otras cargas o crecimiento. En este perfil, esa capacidad no se tradujo en una ventaja de respuesta. Esto tampoco demuestra que 32 GB basten para cualquier instalación de Chatwoot.

Qué hicieron los 60 agentes simulados

La base inicial equivalente contenía 10 cuentas sintéticas, 60 agentes, 10.000 conversaciones y 50.000 mensajes históricos. Cada ronda comenzó desde una restauración de esa base y un Redis de ensayo limpio, después del calentamiento previsto. No se utilizaron conversaciones ni datos de clientes.

El generador se ejecutó dentro de cada host. Los 60 agentes iniciaban su actividad repartidos en los primeros diez segundos y seguían ciclos de diez segundos. Cada uno rotaba sobre seis conversaciones de la base, leía mensajes y escribía en los ciclos previstos. El listado consultaba la primera página con una fase distribuida; no se recorría uniformemente todo el histórico. Parte de las escrituras incorporaba un archivo sintético de 2 MiB; la mitad de los agentes que recibían el mensaje de prueba esperaba 200 ms y respondía por API como un bot determinista.

Registramos 600 solicitudes del perfil por ronda: 60 listados, 360 lecturas, 168 escrituras sin archivo y 12 adjuntos. En ocho rondas por host sumaron 4.800 solicitudes por servidor y 9.600 entre ambos. El conteo no incluye las comprobaciones de salud, la preparación de datos o los intercambios de conexión de ActionCable.

La duración es nominal. El generador dejaba de iniciar ciclos a los 60 segundos, pero completaba la secuencia que ya había comenzado. Por eso algunas solicitudes terminaron después: el último cierre HTTP registrado fue aproximadamente a los 61,25 segundos. Conservamos todas esas solicitudes; CPU y RAM usan las muestras dentro de la ventana nominal, con su cobertura indicada. El detalle por ronda incluye su último final HTTP.

El agente espera la respuesta antes de continuar su secuencia. Es un perfil interactivo temporizado, no una llegada abierta independiente de la latencia. El número de agentes virtuales no equivale al número de empresas que puede atender un servidor. El bot tampoco representa inferencia de IA, Meta, correo o entrega de webhooks externos.

Más trabajadores mejoraron las colas, pero no todo el HTTP

La serie inicial recorrió 1, 2, 4, 4, 2 y 1 procesos Sidekiq por host. Cada proceso tuvo cinco hilos y un tope de 1 vCPU. Web permaneció en seis procesos Puma, cinco hilos y un límite de 6 vCPU. PostgreSQL se limitó a 0,75 vCPU y Redis a 0,25 vCPU.

Dos repeticiones por ajuste. El timeout no se incorpora al p95 de respuestas 2xx. Pendientes: mayor valor tras el drenaje.
Instancia y ajusteListar p95Leer p95Escribir p95Adjunto p95CPU media, vCPURAM máx., GiBErrores HTTPPendientes
Netcup ARM 8000 · 1 proceso · serie inicial2,836 s0,434 s1,228 s2,010 s3,7892,6800447
Netcup ARM 8000 · 2 procesos · serie inicial6,030 s0,611 s1,674 s4,945 s3,9282,80000
Netcup ARM 8000 · 4 procesos · serie inicial7,250 s1,068 s2,650 s5,881 s4,0533,74610
Netcup ARM 8000 · 4 procesos · control DB/Redis2,496 s0,303 s0,810 s5,269 s3,2584,39700
Hetzner CAX41 · 1 proceso · serie inicial0,860 s0,112 s0,354 s0,404 s2,0692,64900
Hetzner CAX41 · 2 procesos · serie inicial0,820 s0,098 s0,308 s0,416 s1,9592,64100
Hetzner CAX41 · 4 procesos · serie inicial0,775 s0,096 s0,296 s0,489 s1,7263,67700
Hetzner CAX41 · 4 procesos · control DB/Redis0,805 s0,104 s0,314 s0,310 s2,0004,38300

En Netcup, el p95 combinado de listado subió de 2,836 s con un trabajador a 7,250 s con cuatro bajo esos límites de base de datos y Redis. A la vez, las notificaciones mejoraron y la cola se redujo: una de las rondas con un trabajador conservó 447 trabajos pendientes después del drenaje; con cuatro no quedaron trabajos pendientes al terminar esa observación.

Ese contraste es parte del resultado. Añadir procesos no produjo una mejora uniforme. La documentación de configuración de Chatwoot describe cómo procesos web, concurrencia de Sidekiq y conexiones a la base de datos deben ajustarse conjuntamente. Dar cuatro vCPU a un único proceso no es la misma configuración que ejecutar cuatro procesos con un tope de una vCPU cada uno.

Listado HTTP, notificaciones y pendientes con uno, dos y cuatro Sidekiq y con el control de PostgreSQL y Redis ampliados.
Figura 3. Las tres señales responden de manera diferente. El listado de Netcup empeoró en la serie inicial al añadir trabajadores, mientras las notificaciones y la cola mejoraron.

Después hicimos el control de cuatro trabajadores ampliando PostgreSQL de 0,75 a 2 vCPU y Redis de 0,25 a 1 vCPU. El p95 de listado de Netcup bajó a 2,496 s. Cambiaron dos límites a la vez, en una serie posterior: no aislamos cuánto del efecto corresponde a PostgreSQL, a Redis o a las condiciones de esa ronda.

En Hetzner, el listado ya se mantenía por debajo de un segundo de p95 combinado en las configuraciones iniciales. El control no mejoró todas sus métricas respecto a la configuración anterior. Tampoco debe presentarse como un ajuste óptimo definitivo para cualquier base de datos o instalación.

Las repeticiones y las notificaciones cambian la interpretación

En las dos rondas del control, el p95 de listado de Netcup fue 4,090 s y 1,631 s; en Hetzner, 0,783 s y 0,841 s. El combinado fue 2,496 s y 0,805 s respectivamente. El p95 combinado no es la media de esos p95: lo recalculamos desde las respuestas individuales de ambas rondas, con rango más próximo ceil(0,95 × n).

Ambas rondas del control. Estos p95 no se promedian para construir el combinado.
Instancia / rondaListar p95Leer p95Escribir p95CPU media, vCPURAM máx., GiB
Netcup ARM 8000 · R14,090 s0,510 s1,888 s3,7714,397
Netcup ARM 8000 · R21,631 s0,153 s0,541 s2,7453,305
Hetzner CAX41 · R10,783 s0,111 s0,305 s2,1024,383
Hetzner CAX41 · R20,841 s0,099 s0,317 s1,8983,322
Curvas de CPU por intervalo y memoria muestreada en ambas repeticiones del control, separadas por ronda.
Figura 4. Se muestran las dos rondas, con sus tiempos relativos. Son muestras de la pila sintética; no incluyen todo el consumo productivo.

Hubo un timeout de listado en Netcup, en la segunda ronda de cuatro trabajadores de la serie inicial. El control adicional registró cero errores HTTP en ambos hosts. La ausencia de errores HTTP en ese control no certifica entrega perfecta de eventos ni corrección completa de todos los canales reales.

Eventos propios marcados observados dentro de la ventana. El rango es entre dos p95, no un intervalo de confianza ni un p95 combinado.
Instancia y ajustep95 de eventos por rondaEventos observados / previstosPendientes después del drenaje
Netcup ARM 8000 · 1 proceso · serie inicial29,176 s a 36,386 s236 / 240447
Netcup ARM 8000 · 2 procesos · serie inicial7,137 s a 7,968 s240 / 2400
Netcup ARM 8000 · 4 procesos · serie inicial1,749 s a 2,137 s239 / 2400
Netcup ARM 8000 · 4 procesos · control DB/Redis0,319 s a 2,105 s238 / 2400
Hetzner CAX41 · 1 proceso · serie inicial7,796 s a 8,351 s239 / 2400
Hetzner CAX41 · 2 procesos · serie inicial0,202 s a 0,356 s240 / 2400
Hetzner CAX41 · 4 procesos · serie inicial0,165 s a 0,175 s240 / 2400
Hetzner CAX41 · 4 procesos · control DB/Redis0,142 s a 0,144 s239 / 2400

Durante el control se observaron 238 de 240 eventos previstos en Netcup y 239 de 240 en Hetzner dentro de las ventanas registradas. El p95 de ActionCable varió entre 0,319 y 2,105 s en Netcup, frente a 0,142 y 0,144 s en Hetzner. Estos percentiles se conservan por ronda: no disponemos de sus duraciones individuales para combinarlos. Un evento previsto no observado en ventana no prueba por sí solo la pérdida de un mensaje persistido.

Adjuntos sintéticos de 2 MiB, enviados desde el mismo host. Solo 12 muestras por ronda y 24 por host en el control.
InstanciaMuestras de adjuntosp95 R1p95 R2p95 combinado
Netcup ARM 8000246,459 s0,739 s5,269 s
Hetzner CAX41240,310 s0,758 s0,310 s

Los adjuntos del control tienen solo 24 muestras por host. Su p95 combinado fue 5,269 s en Netcup y 0,310 s en Hetzner. Los incluimos para conservar el resultado completo, pero esa cola de pocos archivos no será un titular universal sobre almacenamiento, subidas desde clientes o rendimiento de red.

Ver las 16 rondas, sus errores y el consumo muestreado
Las 16 rondas. CPU entre primera y última muestra dentro de los 60 s; el intervalo cubierto puede variar. Fin HTTP: última solicitud completada, relativo al inicio del generador.
Instancia / serie / ordenSidekiqRondaListar p95CPU media, vCPURAM máx., GiBSteal del hostMuestras / coberturaFin HTTP relativoErroresEventosPendientes
Netcup ARM 8000 · inicial · 1112,386 s3,6112,6804,69 %12 / 58,3 s61,25 s0119/1200
Netcup ARM 8000 · inicial · 2215,144 s3,7452,8004,79 %11 / 53,7 s61,01 s0120/1200
Netcup ARM 8000 · inicial · 3416,906 s4,0313,7464,47 %11 / 55,1 s61,12 s0120/1200
Netcup ARM 8000 · inicial · 4427,755 s4,0753,4094,53 %11 / 54,9 s61,07 s1119/1200
Netcup ARM 8000 · inicial · 5226,142 s4,1102,5905,46 %11 / 54,7 s61,05 s0120/1200
Netcup ARM 8000 · inicial · 6123,541 s3,9672,0695,80 %11 / 54,9 s61,23 s0117/120447
Netcup ARM 8000 · control · 1414,090 s3,7714,3972,85 %11 / 54,3 s60,86 s0119/1200
Netcup ARM 8000 · control · 2421,631 s2,7453,3050,63 %12 / 58,6 s60,58 s0119/1200
Hetzner CAX41 · inicial · 1110,909 s2,0492,6490,00 %11 / 52,8 s60,34 s0120/1200
Hetzner CAX41 · inicial · 2210,835 s1,9002,6410,00 %11 / 53,8 s60,35 s0120/1200
Hetzner CAX41 · inicial · 3410,825 s1,7233,6770,00 %11 / 52,8 s60,32 s0120/1200
Hetzner CAX41 · inicial · 4420,765 s1,7293,4430,00 %11 / 54,2 s60,32 s0120/1200
Hetzner CAX41 · inicial · 5220,767 s2,0172,4650,00 %12 / 58,1 s60,39 s0120/1200
Hetzner CAX41 · inicial · 6120,815 s2,0882,0470,00 %11 / 54,0 s60,36 s0119/1200
Hetzner CAX41 · control · 1410,783 s2,1024,3830,00 %11 / 54,1 s60,35 s0119/1200
Hetzner CAX41 · control · 2420,841 s1,8983,3220,00 %11 / 52,8 s60,36 s0120/1200

Qué podemos concluir y qué sigue sin medirse

En estas dos instancias, con este perfil sintético de Chatwoot, Hetzner respondió más rápido y utilizó menos CPU en el control adicional. Netcup mejoró sus colas al ampliar trabajadores y mejoró la respuesta HTTP al ampliar conjuntamente el margen de PostgreSQL y Redis. La RAM máxima muestreada fue muy similar. Estos datos respaldaron nuestra decisión concreta de migración; no acreditan que la migración esté completada ni validan otras aplicaciones.

Se observó más tiempo steal en Netcup y variación entre rondas. El kernel define este contador como tiempo de CPU sustraído en un entorno virtualizado; la definición primaria de Linux permite interpretar el dato. No hemos aislado toda la causa física de la diferencia y el contador no prueba por sí solo una condición comercial o una política del proveedor.

  • Son muestras breves de dos instancias, con dos repeticiones por ajuste. No certifican estabilidad durante días ni representan a todos los servidores de Hetzner o Netcup.
  • No agotamos los 16 vCPU ni medimos el máximo de cuentas, agentes humanos o empresas. No hay una conversión válida de “38,6 % menos CPU media” a “38,6 % más clientes”.
  • El generador compite por recursos dentro de cada host y la carga de fondo no era idéntica. No se midió la experiencia desde Santiago, la red pública, Meta, correo ni IA.
  • El consumo de la pila sintética no es el de todas las aplicaciones del servidor. Los topes de recursos tampoco equivalen a recursos físicos reservados.
  • Los ensayos usaron un Redis efímero. Esa configuración de laboratorio no es una recomendación de persistencia o recuperación para producción.
  • No comparamos costes actuales en este artículo. Las tarifas históricas del Laboratorio conservan su fecha y no se reutilizan como precios vigentes.

Para repetir una decisión operativa, primero hay que fijar el perfil, los objetivos de respuesta y error, los límites y la recuperación del entorno aislado. Después se valida con los datos y medios reales del proyecto, con los canales y emisores productivos controlados. La capacidad nominal de RAM aporta margen; la elección final necesita saber cómo responde la aplicación.

Datos saneados y método para revisar los resultados

El paquete conserva las 9.600 solicitudes con su operación, duración, estado y tiempo relativo; las muestras de recursos y colas; y los resúmenes originales de eventos por ronda. Los hosts tienen alias públicos. Los originales con accesos e identificadores operativos se mantienen privados.

La descarga contiene las 9.600 solicitudes saneadas en JSON, los resúmenes por ronda, el protocolo, los scripts de cálculo y las figuras PNG/SVG. No contiene credenciales, datos de clientes ni planes editoriales internos.

La CPU de cada ronda se obtiene de la diferencia de contadores cgroup entre la primera y la última muestra de la ventana, dividida por el tiempo cubierto. Para el resumen se promedian las dos medias. La RAM se calcula como el máximo de la suma simultánea, no como la suma de máximos individuales de procesos. Los tiempos y la cobertura del muestreo están en la descarga.

La generación de gráficos y el análisis offline no ejecutan tráfico. Una repetición del ensayo necesita recrear un entorno sintético aislado y revisar su autorización, versiones y perfil. El protocolo no convierte estos resultados en un tamaño máximo de servidor o en un nivel de servicio contratado.

El aprendizaje amplía el método de CPU publicado y el método propuesto para WooCommerce. Los resultados de aquellas entradas permanecen intactos; la evidencia de Chatwoot pertenece a esta nueva serie.

Cómo recalcular los resultados sin generar tráfico

Descomprime la descarga y ejecuta python scripts/analizar.py. Usa solo la biblioteca estándar de Python y reconstruye el resumen desde todas las muestras HTTP y los contadores. Para regenerar figuras, instala las dependencias de scripts/requirements.txt en un entorno virtual y ejecuta python scripts/graficos.py.

Los scripts leen archivos locales y no conectan con los servidores del ensayo. El protocolo conserva el perfil, las imágenes por digest, el orden, los topes y los límites de reproducción. Los p95 de eventos se conservan por ronda; no se combinan sin sus duraciones individuales.

Siguiente paso recomendado

Convierte lo aprendido en un sitio que genere oportunidades

Cuéntanos qué debe lograr tu web, qué contenido ya tienes y cuál es el siguiente paso que esperas de tus visitantes.

Quiero evaluar mi sitio

Sigue aprendiendo

Más guías que le sirven a tu pyme

WooCommerce en temporada alta: qué medir antes de escalar, con las cuatro etapas del método de SuperPyme: observar, perfilar, reproducir y decidir.
Laboratorio

Cómo medir WooCommerce en temporada alta antes de cambiar de servidor

Qué observar durante una campaña y cómo construir un perfil reproducible antes de comparar capacidad, memoria…

Leer guía
Portada sobre Ensayo propio · ARM y AMD: Depende de la tarea. Hashing: figura original, con una gráfica original del ensayo de SuperPyme.
Laboratorio

ARM o AMD: por qué el servidor más rápido cambia según la tarea

El ganador de compresión no coincide con el de SHA-256. Explicamos qué significa para una aplicación…

Leer guía
Portada sobre Método del Laboratorio: Medir para repetir. Un ensayo revisable: Versión y parámetros, Carga y condiciones, Muestras, Mediana y rango.
Laboratorio

Cómo comparamos servidores sin convertir una cifra aislada en una promesa

Un protocolo versionado con binarios verificados, tres repeticiones, mediana y límites de carga. Incluye el script…

Leer guía