magento

PHP Profiling en Magento 2 con php-spx: workflow para encontrar la causa raíz

Guía de flujo de trabajo para pasar de 'la página está lenta' a causa raíz usando php-spx en Magento 2: Wall vs CPU, Flat Profile, Flame Graph y métricas del Zend Engine.

10/2/2026|
magento2adobe-commercephpperformanceprofilingzend-engineflame-graphphp-spx

PHP Profiling en Magento 2 con php-spx

Guía de flujo de trabajo: de lentitud a causa raíz

Introducción

No optimices a ojo. En Magento 2 eso casi siempre termina en cambios caros con poco impacto.

Cuando notes lentitud, sigue este flujo: medir -> aislar -> explicar -> corregir.

Ubicación visual sugerida (inicio): coloca aquí la captura general de SPX para contexto.

Métricas disponibles en Zend Engine SPX

Quick Start

Quieres datos rápido. Haz una corrida de profiling antes de tocar código.

En Warden, SPX ya viene dentro de las imágenes de PHP: es un superpoder dormido que solo hay que encender.

  1. Activa SPX en tu .env:
    • WARDEN_PHP_SPX=1
  2. Aplica cambios en los contenedores:
    • warden env up -d
  3. Abre tu sitio Magento y el panel de SPX por Traefik:
    • app: https://yourdomain.test
    • panel: https://spx.yourdomain.test
  4. En el panel, activa captura automática cuando necesites cazar lentitud intermitente (ideal para llamadas AJAX en Magento).
  5. Repite 2-3 veces el mismo flujo para evitar falsos positivos por warmup.

Profiling por CLI en Warden (bin/magento)

También puedes perfilar comandos de consola para detectar cuellos fuera del request HTTP.

  1. Entra al contenedor PHP:
    • warden shell
  2. Ejecuta el comando con SPX habilitado:
    • SPX_ENABLED=1 bin/magento <comando>
  3. Revisa el resultado en https://spx.yourdomain.test y compara runs similares.

Pro Tip: perfila con cache warm y cache cold por separado. Los patrones cambian mucho en Magento.

Fase 1: Diagnóstico de Superficie (Wall Time vs CPU Time)

Este es siempre el primer paso.

  • Wall Time: tiempo real total (incluye esperas de DB, disco, red).
  • CPU Time: tiempo real de ejecución de CPU en PHP.

Lógica Si/Entonces

  • Si Wall Time es alto y CPU Time es bajo: el cuello está fuera del CPU PHP.
    • Revisa DB lenta, locking, Redis, filesystem, HTTP externo, DNS.
  • Si Wall Time y CPU Time son altos: el problema está en código PHP/arquitectura.
    • Revisa loops, N+1, repositorios llamados en cascada, observers/plugins excesivos.

En Magento 2, este filtro te evita perder horas optimizando código cuando el problema real era query/I/O.

Pro Tip: si ves ProductRepository::getById() cientos de veces en una sola request, sospecha N+1 de catálogo inmediatamente.

Fase 2: Identificando al Culpable (Flat Profile)

Con el diagnóstico de superficie listo, pasa a identificar qué función consume tiempo.

Ubicación visual sugerida: coloca aquí la captura de Flat Profile.

Flat Profile en php-spx

El Flat Profile ordena funciones por costo. Aquí decides qué optimizar primero.

Qué mirar

  • Exclusive Time: tiempo propio de la función (su lógica interna).
  • Inclusive Time: tiempo de la función + todo lo que llama.
  • Calls: cantidad de invocaciones.

Decisión práctica

  • Exclusive alto -> esa función es el problema directo.
  • Inclusive alto + Exclusive bajo -> el problema está en funciones hijas.
  • Calls alto -> posible problema de diseño (N+1, loops, falta de memoización/cache).

Ejemplos típicos en Magento:

  • Magento\Catalog\Model\ProductRepository::getById
  • Magento\Framework\Event\Manager::dispatch
  • Magento\Framework\Interception\PluginList (cadenas de plugins)

Pro Tip: prioriza primero funciones con alto impacto total (inclusive + calls), no solo la más lenta por ejecución individual.

Fase 3: Entendiendo el Contexto (Flame Graph)

Ya sabes el culpable principal. Ahora necesitas el contexto de ejecución.

Ubicación visual sugerida: coloca aquí la captura de Flame Graph.

Flame Graph en php-spx

El Flame Graph muestra el stack visual:

  • ancho = costo en tiempo
  • altura = profundidad de llamadas

Qué buscar en Magento

  • Bloques anchos repetidos: misma operación invocada desde muchos lugares.
  • Jerarquías muy profundas: exceso de capas (plugins/observers/interceptores).
  • Ramas paralelas similares: patrón duplicado en layout blocks/view models.

Aquí detectas patrones de diseño ineficientes, no solo funciones lentas.

Pro Tip: si una función aparece en muchos caminos del gráfico, no la optimices localmente: corrige el punto de orquestación que la dispara.

Fase 4: El Deep Dive (Métricas del Zend Engine & I/O)

Esta es la investigación forense. Ahora respondes por qué esa función/ruta es lenta.

Usa estas métricas cuando ya identificaste el hotspot en Fase 2.

Memoria y objetos

  • Allocated bytes / allocation count: presión de memoria.
  • Free count / freed bytes: ritmo de liberación.
  • Process RSS: memoria real del proceso.

Interpretación:

  • Si suben allocations + RSS: exceso de objetos/arrays temporales.
  • En Magento, suele pasar con colecciones grandes, hydration innecesaria y transformaciones repetidas.

Garbage Collector (GC)

  • GC root buffer length
  • GC collected cycle count

Interpretación:

  • GC muy activo = demasiada rotación de objetos.
  • Revisa factories/DTOs creados dentro de loops y conversiones redundantes.

Includes, funciones y opcodes

  • Included files / executed lines
  • User classes/functions/objects
  • Opcode count

Interpretación:

  • picos de includes/clases en una request puntual suelen indicar módulos/código ejecutándose sin necesidad.

I/O

  • I/O read bytes / write bytes

Interpretación:

  • I/O alto con CPU bajo = espera externa clara.
  • Revisa logs excesivos, lecturas de disco, sesiones, integraciones, cache backend.

Pro Tip: en Adobe Commerce, un Event/Observer que serializa payloads grandes puede disparar CPU + memoria + I/O al mismo tiempo.

Conclusión y Performance Cheat Sheet

Flujo recomendado:

  1. Wall vs CPU para clasificar el tipo de problema.
  2. Flat Profile para encontrar la función ofensora.
  3. Flame Graph para entender contexto y diseño.
  4. Zend/I/O para explicar la causa técnica exacta.

Performance Cheat Sheet

Síntoma observadoMétrica SPX a revisarLectura probableAcción inicial
Página lenta, CPU bajaWall Time alto + CPU Time bajoEspera externa (DB/I/O/red)Revisar queries, Redis, FS, APIs
CPU disparadaCPU Time altoCódigo PHP pesadoRevisar loops y cálculos redundantes
Función "inocente" aparece arribaInclusive alto, Exclusive bajoCosto heredado de hijasBajar por stack y aislar subllamada
Mucha memoria consumidaAllocated Bytes + RSSExceso de objetos/datosReducir hydration, paginar, lazy-load
GC muy activoGC root buffer / collected cyclesDemasiados objetos temporalesEvitar creación de objetos en loops
Llamadas repetidasCalls alto en Flat ProfileN+1 / diseño repetitivoCache local, batch (getList), refactor de flujo
Jerarquía profundaFlame Graph alto/profundoCadena compleja (plugins/observers)Simplificar puntos de extensión
Disco/red saturadoI/O read/write altoCuello en I/OReducir escrituras y dependencias externas
Profiling falla por memoriaRun incompleto + RSS/Allocated Bytes al límiteLímite de memoria bajo en entorno localSubir WARDEN_PHP_MEMORY_LIMIT en .env y ejecutar warden env up -d

Si quieres performance real en Magento 2: mide primero, optimiza después.