Ir al contenido principal
Laravel, shipping fast.

Capitulo 6

Rendimiento y optimizacion

Julian Beaujardin

Las APIs lentas pierden usuarios. Una respuesta de 500 ms se siente instantánea. Una de tres segundos hace que quien la consume se pregunte si algo está roto, y reintente.

«Ya lo haremos rápido luego» no funciona. Optimizar una arquitectura lenta es exponencialmente más difícil que construir una rápida, porque para cuando va lenta ya hay tres servicios que dependen de la forma que tiene. Este capítulo cubre cómo saber qué es lento de verdad, el error de consulta con el que te toparás primero, cachear sin mentirte sobre la frescura, la paginación como decisión y no como valor por defecto, qué columnas necesitan índices, por qué el tamaño de la carga también es latencia y cómo confirmar que el arreglo funcionó.

No puedes optimizar lo que no has medido. Todo este capítulo se deriva de esa frase.

Mide antes de optimizar

Una verdad incómoda: la mayor parte del trabajo de rendimiento es adivinar disfrazado de ingeniería. Alguien nota que un endpoint va lento, añade un índice por aquí, una caché por allá, lo publica y nunca confirma cuál de los dos cambios (si alguno) hizo algo. Seis meses después nadie recuerda por qué existe esa caché, y nadie está seguro de que ayude.

No tienes derecho a adivinar, porque no hace falta. Toda petición autenticada de la License API ya pasa por LogApiRequestsMiddleware, que cronometra la petición y registra el resultado antes de que hayas escrito una sola optimización:

// api-infrastructure/src/Middleware/LogApiRequestsMiddleware.php
final readonly class LogApiRequestsMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        $startTime = microtime(true);
        $response = $next($request);

        defer(function () use ($request, $response, $startTime) {
            // ...
            SendToLogsJob::dispatch(
                // ...
                execution_time: microtime(true) - $startTime,
                request_size: $requestSize,
                response_size: $responseSize,
                // ...
            );
        });

        return $response;
    }
}

$startTime = microtime(true): capturado antes de construir la respuesta, así que incluye todo lo que viene después: el controlador, la facade, la llamada HTTP del driver.

defer(): el cronometraje y el registro ocurren después de que la respuesta ya se haya enviado. Medir no cuesta nada en el camino crítico.

execution_time: el número que compararás antes y después de cada cambio de este capítulo. Si no puedes señalar que ese campo bajó, no optimizaste nada: reorganizaste código.

«Mide primero» no es un paso que te saltas bajo presión de plazos. La medición ya existe; saltártela significa ignorar datos que ya estás pagando por recoger.