Hola a todos. Recientemente realicé un benchmark exhaustivo para responder una pregunta clásica en equipos de backend: ¿tiene sentido migrar a Go, o alcanza con NestJS?
No hay respuesta mágica, pero los datos ayudan a decidir. Aquí les dejo un resumen de los hallazgos más importantes.
🏗️ El Escenario
Comparé dos arquitecturas típicas corriendo en Docker sobre la misma máquina (M4 Pro):
- NestJS (Node 22) + Prisma v6 (Enfoque productividad)
- Go (1.24) + GORM (Enfoque rendimiento)
Ambos conectados a PostgreSQL 15 y sometidos a pruebas de estrés (gRPC y HTTP) simulando un entorno real.
🧪 Metodología: ¿Qué medimos?
Para entender realmente las diferencias, dividí las pruebas en dos escenarios clave:
Small Data (1x1 Insert):
Simula el tráfico transaccional típico de una API REST/gRPC. Recibimos un objeto, lo validamos y lo guardamos. Aquí medimos la latencia base del framework.Large Data (Batch Insert de 1000 elementos):
Simula procesos de carga masiva, ETLs o ingestión de eventos. Enviamos arrays de 1000 objetos que deben ser deserializados, validados y guardados en una sola transacción. Aquí es donde la CPU y el Garbage Collector sufren más.
📊 Los Resultados
1. Small Data: La sorpresa
En escenarios de baja carga o inserciones unitarias, la diferencia fue mínima. Go obtuvo una mejora de latencia de apenas un ~10% sobre NestJS.
Conclusión: Para operaciones CRUD estándar, NestJS es increíblemente eficiente y la diferencia de rendimiento rara vez justifica perder la productividad de TypeScript.
2. Large Data: El punto de quiebre
La historia cambia drásticamente cuando procesamos lotes masivos (arrays de 1000 elementos) bajo alta concurrencia.
Escenario: 100 RPS constantes (Bulk Inserts)
| Servicio | Throughput Real | P95 Latency | Success Rate |
|---|---|---|---|
| Go gRPC | 85 RPS | 71.88 ms | 100% |
| NestJS gRPC | 78 RPS | 98.44 ms | ~85% |
¿Qué pasó aquí?
- Serialización: Node.js (V8) tiene un costo mayor al serializar/deserializar grandes volúmenes de JSON comparado con los Structs de Go y Protobuf.
- Connection Pool: Bajo presión extrema, el pool de conexiones de Prisma comenzó a saturarse (errores
P2024), provocando que NestJS perdiera el ~15% de los requests. - Estabilidad: Go mantuvo el 100% de éxito y latencias más predecibles, gracias a su manejo de goroutines y un GC más eficiente para este tipo de carga.
⚖️ Conclusión: ¿Cuándo usar cuál?
Basado en los datos, aquí está mi recomendación pragmática:
✅ Quédate con NestJS si:
- Estás construyendo un MVP o validando producto.
- Tu equipo ya conoce TypeScript y valoras la velocidad de desarrollo.
- La carga es moderada (< 300 RPS) y operaciones CRUD estándar (Small Data).
- BFF (Backend for Frontend): Si solo necesitas orquestar llamadas a pocos servicios y la carga de serialización es baja.
🚀 Migra a Go si:
- BFF Complejo: Si tu BFF necesita llamar a muchos microservicios, agregar lógica pesada, serializar grandes volúmenes de datos y hacer fan-out masivo, Go manejará la concurrencia mucho mejor.
- Tu sistema realiza Bulk Operations / ETL masivos constantemente (Large Data).
- Necesitas manejar miles de conexiones concurrentes (ej. Gateways, Websockets masivos).
- Tienes SLAs de latencia muy estrictos donde los picos del Garbage Collector de Node son inaceptables.
📖 Lee el análisis completo
Este post es un resumen. El análisis detallado (con todas las tablas, gráficos, configuración de hardware y análisis de errores) es público y gratuito.
👉 Leer el artículo completo en Buy Me a Coffee
💌 Agradecimientos Especiales
A una chica que, sin saberlo, me empujó a seguir creando y programando en mi tiempo libre. A quien alguna vez fue mi chispa: para “YLP”, con gratitud… y con cicatrices que también enseñan.
Si te sirve este tipo de análisis, ¡cualquier feedback es bienvenido!
Top comments (0)