Software Architect · Módulo 13

Performance no es la sensación de que el código va rápido. Son objetivos medibles, profiling y un precio claro por cada optimización.

Latency · throughput · profiling · caching · budget

§ 01

Hay que optimizar el bottleneck — no el lugar que simplemente se ve feo.

Latency y throughput son cosas distintas

Un taxi lleva rápido a una persona. El metro mueve a miles. Compararlos con una sola palabra — "rápido" — no tiene sentido.

Latency es el tiempo de respuesta de una operación. Throughput es cuántas operaciones procesa el sistema en un período. Podés bajar la latency de un request y empeorar el throughput de todo el sistema — por ejemplo, con un parallelism agresivo que no controla los recursos.

El arquitecto tiene que formular el performance requirement de forma concreta: p95 response time, p99 tail latency, requests per second, batch duration, cold start, memory budget. "Tiene que ser rápido" no es un requisito.

Un cache es responsabilidad sobre la obsolescencia

La copia del menú en la vidriera sirve mientras los precios coincidan con la caja. Después se vuelve fuente de discusiones.

Caching acelera las lecturas, pero suma invalidation, TTL, un modelo de consistency y el riesgo de stale data. Antes de meter un cache, hay que preguntar: qué exactamente es caro, con qué frecuencia cambia, se puede mostrar un valor desactualizado, cómo invalidamos el cache cuando cambia la source of truth.

Cachear sin entender el modelo de datos es peligroso: podés acelerar la respuesta equivocada.

§ 02

Una buena optimización empieza con una medición y termina verificando el resultado.

Ejemplo: un endpoint lento resuelto con profiling

El médico hace primero el diagnóstico, no opera de entrada porque el paciente dijo "me duele algo".

El endpoint /dashboard tiene un p95 de 2.8 segundos. El tracing muestra que el 80% del tiempo se va en queries N+1 contra la base y en la falta de un índice sobre workspace_id, created_at. El equipo agrega eager loading, el índice y un performance test.

Resultado: el p95 baja a 380 ms. La solución es puntual, medible y no agrega complejidad arquitectónica extra.

Antiejemplo: reescribir en Go sin un profile

Cambiar el motor no sirve de nada si el auto está parado en un atasco porque cerraron la calle.

El equipo decide reescribir el servicio en otro lenguaje porque "Python es lento". Más tarde se descubre que el 90% del tiempo se iba en APIs externas y en SQL queries mal diseñadas.

El lenguaje puede ser un bottleneck, pero hay que demostrarlo. Si no, la optimización se convierte en un refactor caro sin impacto en el negocio.

Autoevaluación
  • ¿Qué métrica de performance importa acá específicamente? - ¿Dónde está el bottleneck según el profiler/tracing? - ¿Qué budget se considera aceptable? - ¿Qué se va a romper cuando metas un cache?