Antigüedad media de los tickets: el indicador que nadie mide en GLPI

La antigüedad media de los tickets revela el backlog olvidado que el tiempo medio de resolución no ve. Descubre de dónde sale el número en GLPI, por qué la media engaña, cómo separar antigüedad de estancamiento con SQL y cómo automatizar la revisión semanal del backlog.

El tiempo medio de resolución mide a quien ya salió de la cola. La antigüedad media de los tickets mide a quien sigue en ella - y ahí es donde se esconde el backlog olvidado. Esta guía muestra de dónde sale el número en GLPI, por qué la media sola engaña, cómo separar antigüedad de estancamiento y cómo convertirlo en una rutina semanal de revisión de backlog en los entornos que mantenemos.

Qué mide la antigüedad media - y qué esconde

La antigüedad media de los tickets es la media de días entre la apertura y hoy, contando solo los tickets que siguen abiertos. A diferencia del TMR, que solo ve lo ya resuelto, fotografía el estado actual de la cola. El problema es que la media, por sí sola, es un pésimo resumen de una cola real: un backlog típico es bimodal - decenas de tickets nuevos con pocas horas de vida conviven con una cola de tickets parados desde hace semanas. La masa de tickets nuevos empuja la media hacia abajo y esconde justamente los antiguos, que son los que necesitas encontrar. Por eso la media nunca va sola: viene acompañada de la distribución y de la mediana.

De dónde sale el número en GLPI

Todo vive en la tabla glpi_tickets. La antigüedad usa la columna date (fecha de apertura); el recorte de "abierto" usa status. Los estados que importan:

  • 1 - Nuevo (aún sin clasificar)
  • 2 - En curso (asignado)
  • 3 - En curso (planificado)
  • 4 - Pendiente (esperando a un tercero)
  • 5 - Resuelto y 6 - Cerrado (fuera del backlog)

El error más común aquí es meter todo lo que no es 5 ni 6 en el mismo saco. Los tickets en Pendiente (estado 4) están legítimamente parados esperando a un proveedor, al cliente o a una pieza - inflan la antigüedad media sin que nadie haya olvidado nada. Segmentar por estado es el primer filtro honesto:

-- Antigüedad media por estado (segmentar: "Pendiente" infla la media)
SELECT
  status,
  ROUND(AVG(DATEDIFF(NOW(), date)), 1) AS dias_antiguedad_media,
  COUNT(*)                             AS total
FROM glpi_tickets
WHERE status NOT IN (5, 6)   -- excluye Resuelto y Cerrado
  AND is_deleted = 0
GROUP BY status
ORDER BY dias_antiguedad_media DESC;
-- estado: 1 Nuevo, 2 asignado, 3 planificado, 4 Pendiente

Antigüedad no es lo mismo que estancamiento

Un ticket abierto hace 40 días pero con una tarea registrada ayer es muy distinto de uno abierto hace 40 días sin que nadie lo toque. La antigüedad (desde la apertura) mide veteranía; el estancamiento (desde la última acción humana) mide abandono - y es el estancamiento el que señala el ticket olvidado.

En el mantenimiento, el error que ya vimos costar caro fue usar date_mod como "última acción". La columna date_mod del ticket se actualiza por cualquier cosa: una notificación enviada, un seguidor añadido, el cron de SLA recalculando un plazo, una regla de negocio disparándose. Es decir, da la ilusión de movimiento en tickets que nadie trabajó de verdad. La última acción humana real está en el seguimiento y en la tarea - glpi_itilfollowups y glpi_tickettasks. Cuando cambiamos date_mod por la fecha máxima de esas dos tablas, la lista de estancados de un cliente saltó de 3 a 17 tickets: los otros 14 parecían vivos solo porque una automatización los rozaba cada día.

-- Estancamiento real: días desde la última interacción humana
-- date_mod no sirve (notificaciones, seguidores y cron lo actualizan)
SELECT
  t.id,
  t.name,
  DATEDIFF(NOW(), t.date) AS dias_antiguedad,
  DATEDIFF(NOW(), GREATEST(
      t.date,
      COALESCE(MAX(f.date), t.date),
      COALESCE(MAX(k.date), t.date)
  ))                       AS dias_parado
FROM glpi_tickets t
LEFT JOIN glpi_itilfollowups f
       ON f.itemtype = 'Ticket' AND f.items_id = t.id
LEFT JOIN glpi_tickettasks k
       ON k.tickets_id = t.id
WHERE t.status NOT IN (4, 5, 6)   -- excluye Pendiente, Resuelto, Cerrado
  AND t.is_deleted = 0
GROUP BY t.id, t.name, t.date
HAVING dias_parado >= 7
ORDER BY dias_parado DESC;

Distribución, no solo la media

Antes de reaccionar a una media que subió, mira la forma de la cola. La consulta de abajo divide el backlog en rangos de antigüedad y revela la cola larga que la media aplana:

-- Distribución del backlog por rango de antigüedad
SELECT
  CASE
    WHEN DATEDIFF(NOW(), date) <= 3  THEN '0-3 días'
    WHEN DATEDIFF(NOW(), date) <= 7  THEN '3-7 días'
    WHEN DATEDIFF(NOW(), date) <= 15 THEN '7-15 días'
    WHEN DATEDIFF(NOW(), date) <= 30 THEN '15-30 días'
    ELSE '30+ días'
  END        AS rango,
  COUNT(*)   AS tickets
FROM glpi_tickets
WHERE status NOT IN (4, 5, 6)
  AND is_deleted = 0
GROUP BY rango
ORDER BY MIN(DATEDIFF(NOW(), date));

Como rango de referencia honesto (días corridos, no días hábiles): por debajo de 3 días es saludable, de 3 a 7 días es aceptable, de 7 a 15 días enciende la alerta y por encima de 15 días pide revisión ticket a ticket. No son metas universales - el número justo depende del contrato y del tipo de operación.

Del número a la acción: matriz de decisión

Antigüedad alta no es un problema; es un síntoma con varias causas. Lo que lo resuelve es leer la señal técnica y clasificar antes de actuar:

Señal técnicaClasificaciónAcción
estado 1 (Nuevo) y antigüedad > 3 díasSin clasificarAsignar responsable/grupo ya
dias_parado alto, sin seguidor externoOlvidadoReasignar y reclamar
estado 4 (Pendiente) con retorno vencidoBloqueo expiradoReclamar al tercero o reabrir
antigüedad alta y dias_parado bajoLegítimo (complejo)Revisar SLA / alcance
antigüedad alta y categoría recurrenteCandidato a problemaAbrir Problema / artículo de KB

Un caso silencioso que vale la pena destacar: tickets atascados en Nuevo porque la regla de negocio de asignación no coincidió con la categoría y nunca puso un grupo. Envejecen invisibles - desaparecen de los paneles por grupo y solo salen cuando miras la antigüedad media sin filtro de grupo.

Automatizando la revisión semanal

Correr la consulta a mano no escala. Guardamos la consulta de estancamiento en un archivo .sql y la programamos en el cron del sistema, leyendo credenciales de un archivo .cnf (chmod 600) para nunca dejar la contraseña en la línea de comandos. El resultado es un CSV semanal que se convierte en la agenda de la revisión de backlog:

# /etc/cron.d/glpi-idade  ->  cada lunes 07:30, como www-data
# Genera la lista de tickets estancados (7+ días) para la revisión de backlog
30 7 * * 1 www-data /usr/bin/mysql --defaults-file=/etc/glpi/kpi-ro.cnf glpi \
  < /opt/glpi-kpi/estagnados.sql \
  > /var/log/glpi-kpi/estagnados-$(date +\%Y-\%m-\%d).csv 2>&1

Errores comunes de campo

  • Mirar solo la media: aplana la cola. Sigue siempre la distribución y, cuando sea posible, la mediana.
  • Mezclar Pendiente en el saco: el estado 4 es una espera legítima; por sí solo eleva la media y genera falsa alarma.
  • Usar date_mod como última acción: las automatizaciones lo actualizan. Usa las fechas de seguimiento y de tarea.
  • Comparar entidades con calendarios distintos: DATEDIFF cuenta días corridos; entidades con jornadas distintas no son comparables una a una.
  • Olvidar is_deleted = 0: la papelera de GLPI no sale de la tabla y contamina cualquier media.

Próximo paso

Combina la antigüedad media con el resto de tus KPIs de Service Desk y móntalo todo en un panel en Metabase o Grafana con filtro por entidad y grupo. Así la antigüedad deja de ser un número a fin de mes y pasa a ser una alerta que se dispara cuando todavía se puede actuar.

En NexTool, la antigüedad y el estancamiento del backlog entran en el informe mensual de mantenimiento que entregamos a los clientes, junto con la lista de tickets a recuperar. Si quieres ese seguimiento en tu GLPI, conoce nuestro servicio de soporte y mantenimiento.


Este contenido se produjo con ayuda de inteligencia artificial y fue revisado por el equipo de Nextool Solutions.

Preguntas Frecuentes

Es la media de días entre la fecha de apertura (la columna date) y hoy, contando solo tickets abiertos (estado distinto de 5 Resuelto y 6 Cerrado). Fotografía el estado actual de la cola, a diferencia del tiempo medio de resolución, que solo mide tickets ya cerrados.

Porque el backlog suele ser bimodal: muchos tickets nuevos conviven con una cola de antiguos. La masa de nuevos empuja la media hacia abajo y esconde los pocos parados desde hace semanas. Por eso necesita la distribución por rango y, cuando es posible, la mediana.

La antigüedad es el tiempo desde la apertura; el estancamiento es el tiempo desde la última acción humana (un seguimiento o una tarea). Un ticket antiguo trabajado ayer no está olvidado; uno antiguo y sin interacción sí. El estancamiento es la señal que apunta al abandono.

Porque date_mod se actualiza por notificaciones, seguidores añadidos, el cron de SLA y reglas de negocio - movimientos automáticos que no son trabajo humano. Usa la fecha máxima en glpi_itilfollowups y glpi_tickettasks para saber cuándo el ticket fue tocado de verdad por alguien.

Como rango de referencia en días corridos: por debajo de 3 días es saludable, de 3 a 7 aceptable, de 7 a 15 enciende la alerta y por encima de 15 pide revisión ticket a ticket. No es una meta universal - depende del contrato, del calendario laboral y del tipo de operación.

No directamente. El módulo de Estadísticas ayuda en consultas puntuales, pero no guarda la serie histórica ni separa antigüedad de estancamiento. Para eso se usa SQL con un usuario de solo lectura o un panel en Metabase/Grafana alimentado por estas consultas.

?Necesitas ayuda?