Separar trabajo de CPU y tiempo de espera

Una API Go lenta necesita un diagnóstico medible antes de una reescritura. Registra percentiles de latencia, volumen de solicitudes y errores con una carga definida. Después investiga el recurso que explica la demora. Los perfiles de CPU ayudan a estudiar cómputo activo; las trazas y los tiempos de dependencias ayudan a explicar esperas. Verifica cada cambio con la misma carga y una comprobación independiente del comportamiento.

Yo comenzaría por la operación que experimenta la persona: qué endpoint, qué entrada, qué percentil y cuánta concurrencia. Un promedio saludable puede ocultar solicitudes que esperan mucho más. Describir ese grupo permite evaluar el resultado de un cambio.

Definir una referencia reproducible

Elige tamaños de solicitud representativos y un intervalo fijo. Registra la revisión de la aplicación, versión de Go, límites de CPU y memoria, réplicas y condiciones de las dependencias. Conserva los errores en la medición. Reducir la latencia devolviendo más errores no mejora el servicio.

Empieza con una hipótesis. Una respuesta grande puede generar más asignaciones de memoria; las solicitudes también pueden esperar una conexión disponible a la base de datos. Compara tráfico equivalente antes y después. Si cambian la carga o los límites de recursos, documenta esa diferencia.

Mide la latencia completa del endpoint por separado del microbenchmark. Un benchmark compara un detalle de implementación, pero no reproduce colas de red, contención en bases de datos ni reintentos. Cada resultado debe indicar el alcance de su medición.

  • Identificar endpoint, tamaño de entrada y concurrencia.
  • Registrar percentiles de latencia, volumen y errores.
  • Conservar versión de Go, revisión y límites de recursos.
  • Definir el comportamiento esperado antes de modificar el código.

Elegir la herramienta según el síntoma

Con CPU saturada, captura un perfil durante trabajo representativo e inspecciona las rutas costosas. Ante presión de memoria, revisa asignaciones y actividad del recolector. Si las solicitudes tardan con CPU disponible, observa las dependencias, esperas por conexiones, deadlines y sincronización.

Un perfil responde una pregunta más acotada que “por qué está lenta la API”. Una función puede consumir una gran proporción de CPU y explicar poco del tiempo esperando otro servicio. Si no aparece un punto costoso, revisa la hipótesis antes de añadir concurrencia.

Cuando sea posible, captura perfiles por separado: las herramientas de diagnóstico tienen coste y pueden interferir entre sí. La documentación oficial de Go explica los perfiles y sus límites. En producción, acuerda primero el alcance, los accesos y el coste aceptable de la captura.

Caso demostrativo: construcción repetida de cadenas

Esta demostración educativa es independiente. No representa un cliente ni afirma resultados de producción. El archivo Go descargable compara concatenación repetida con strings.Builder. Ambas funciones construyen la misma salida separada por comas. Las pruebas comparan sus resultados con strings.Join e incluyen entradas vacías, valores vacíos y Unicode.

El benchmark utiliza dos tamaños de entrada y reporta asignaciones. Guarda el resultado en una variable del paquete para que no se descarte simplemente. Ejecuta varias muestras y revisa tiempo y memoria. El ejemplo aísla una operación; no simula una solicitud HTTP.

Los comandos requieren Go instalado. No publicamos cifras de benchmark inventadas. Ejecuta el ejemplo localmente antes de sacar conclusiones. Guarda el archivo enlazado en un directorio independiente para separar los perfiles y binarios generados.

# Save the linked encode_test.go in an empty working directory.
go version
go test -run TestOutput -bench BenchmarkEncode -benchmem -count=5 encode_test.go
# Capture one profile type at a time.
go test -run '^$' -bench 'BenchmarkEncode/concatenate/1024$' -benchtime=3s -cpuprofile=cpu.out encode_test.go
go tool pprof -top cpu.out
go test -run '^$' -bench 'BenchmarkEncode/concatenate/1024$' -benchtime=3s -memprofile=heap.out encode_test.go
go tool pprof -alloc_space -top heap.out

Interpretar el ejemplo sin prometer una mejora del endpoint

Si tus mediciones muestran menos asignaciones o tiempo con strings.Builder para una entrada concreta, tienes evidencia para esa operación y esa carga. No demuestra que una API mejorará en la misma proporción. El endpoint puede dedicar casi todo su tiempo a otro trabajo.

En un servicio, confirma primero que la construcción de respuestas aparece en la evidencia. Conserva una prueba del formato, realiza un cambio pequeño y repite la carga del endpoint. Compara percentiles altos, errores y recursos. Documenta también cuando no aparece una mejora relevante.

Una entrega útil describe la condición observada, el cambio, la verificación y las incertidumbres. Incluye los datos originales además de cualquier porcentaje. Otra persona debería poder repetir el diagnóstico y revisar si la decisión sigue siendo válida después de una nueva versión.

Expectativas independientes para pruebas en Go

Mantener el diagnóstico fuera del acceso público

Si utilizas net/http/pprof, mantén sus handlers en un listener controlado explícitamente o una ruta administrativa. Un puerto diferente no constituye control de acceso. Confirma dirección de escucha, reglas de red y autenticación antes de capturar perfiles.

Los perfiles y trazas pueden revelar detalles internos. Limita accesos y retención y captura solo lo necesario. El ejemplo descargable genera perfiles mediante go test; no inicia un servidor HTTP ni expone endpoints de diagnóstico.

Definir una colaboración de ingeniería concreta

Para conversar sobre consultoría, comparte el endpoint afectado, una carga de ejemplo sin información sensible, las mediciones disponibles y el resultado que necesitas. Con ese contexto podemos definir si el alcance es diagnóstico, implementación o apoyo al proceso de medición de tu equipo.

Este trabajo encaja con mi enfoque en backends Go y plataformas Kubernetes. Mi disponibilidad es limitada por mi empleo a tiempo completo; debemos acordar alcance y plazos antes de implementar. La página de consultoría describe mi experiencia laboral relevante y el proceso de colaboración.

Guía relacionada: reconciliación observable en Kubernetes

Referencias y lecturas adicionales

¿Necesitas apoyo con tu backend Go?

Colaboro con equipos de ingeniería en proyectos concretos de Go y plataformas Kubernetes, con disponibilidad limitada.

Ver servicios de consultoría Go