Holded Mobile — State of the Nation

Informe de salud de la app móvil (Sentry · mobile-next-gen · production)
Fecha: 2026-04-24 Ventana: últimos 30 días Release actual: com.holdedmobile@3.5.1+500 Release anterior: com.holdedmobile@3.4.0+487

1 · Vitals

Dashboard agregado — Sessions, Mobile Vitals, Distribución de plataforma y HTTP — con comparativa release actual (3.5.1+500) vs anterior (3.4.0+487) para detectar regresiones entre versiones.

Session Health & Adopción

Una sesión en Sentry es el tiempo que la app está en primer plano entre dos backgrounds. Estas métricas miden la fiabilidad percibida por el usuario: cuántas sesiones o usuarios se encuentran con un crash, y cuánta gente ha instalado la última release.

Crash-free sessions
99,89 %
Muy por encima del umbral 99,5 %
Porcentaje de sesiones de app que terminan sin un crash nativo o JS. Benchmark de industria: >99,5 % es bueno, >99,9 % es excelente.
Crash-free users
98,25 %
~1,75 % de usuarios ha visto al menos un crash
Porcentaje de usuarios únicos que no han visto ningún crash en el periodo. Más estricto que sessions: un solo crash "contamina" al usuario durante 30d.
Adopción 3.5.1+500 (Android)
31,1 %
Sesiones · 15,0 % usuarios únicos
% de sesiones/usuarios sobre la base total en 3.5.1+500 (Android). Si sumamos también 3.5.1+489 (iOS), la adopción combinada de v3.5.1 llega al 43,6 % de sesiones.
Sesiones totales 30d
2,66 M
2 661 993 sesiones
Número bruto de sesiones en la ventana. Sirve de denominador para contextualizar los porcentajes y detectar caídas de uso.

Rollout en curso: 3.4.0+487 todavía representa el 35,8 % de sesiones (más que 3.5.1+500 al 31,1 %), y 3.4.1-rc.1+478 iOS el 14,0 %. Es decir, la mayoría del tráfico aún está en la release anterior — las métricas de 3.5.1 deben interpretarse sabiendo que todavía tiene menos exposición.

Vitals globales (Dashboard Mobile Vitals, 30d)

Métricas que Sentry captura automáticamente en mobile. Las cuatro primeras miden cuánto tarda el usuario en poder interactuar; las dos últimas miden fluidez del render.

Avg Cold App Start
3,89 s
p75 por release: 4,0–4,3 s
Tiempo desde que el usuario toca el icono con la app descargada de memoria hasta que aparece la primera frame interactiva. Peor escenario.
Avg Warm App Start
2,28 s
p75 por release: 2,7–2,8 s
Igual que cold pero con la app ya en memoria (segundo plano). Métrica más frecuente en el día a día del usuario.
Avg TTID
898 ms
media global; AppStack es el outlier (p75 5,2 s)
Time To Initial Display: tiempo desde que navegas a una pantalla hasta que aparece algún contenido en pantalla. Mide "cuándo deja de parecer roto".
Avg TTFD
No instrumentado (requiere reportFullyDisplayed())
Time To Full Display: tiempo hasta que la pantalla está realmente usable (datos cargados, no skeleton). Hay que instrumentarlo llamando a reportFullyDisplayed().
Slow Frame Rate
13,6 %
Moderado — gating al upgrade a ProMotion/120 Hz
% de frames que tardan más de 16 ms en renderizarse (en pantallas a 60 Hz). Se perciben como "jank" o tirones leves. En 120 Hz el listón baja a ~8 ms.
Frozen Frame Rate
0,28 %
Excelente — no hay bloqueos del hilo UI
% de frames que tardan más de 700 ms en renderizarse. El usuario los percibe como la app "congelada". Suele indicar bloqueo del hilo principal.

Mobile Vitals — N vs N‑1

p75 (percentil 75) = el 75 % de las veces la métrica estuvo por debajo de este valor. Se usa en lugar de la media porque no se deja arrastrar por un puñado de usuarios con devices muy viejos o redes muy malas. Un valor "p75 cold = 4 s" significa "3 de cada 4 arranques fríos tardaron menos de 4 s".

Métrica 3.4.0+487 3.5.1+500 Δ Estado
App start cold p75 4 010 ms 234 352 muestras 4 019 ms 197 154 muestras +0,2 % estable
App start warm p75 2 755 ms 32 557 muestras 2 849 ms 29 181 muestras +3,4 % estable
TTID AppStack p75 agregado 30d, no hay breakdown por release 5 160 ms · 3 714 muestras alto

Umbrales: ok |Δ|<5 % · warn 5–15 % · bad >15 %. La release 3.5.0+498 intermedia subió cold a 4 251 ms (+6 %) pero se ha recuperado en 3.5.1.

Distribución OS / Device

Dónde se concentran los errores por plataforma y por modelo de dispositivo. Sirve para decidir dónde invertir QA: si un device concentra el 30 % de los errores pero sólo el 5 % de la base de usuarios, tenemos un bug específico de ese hardware.

Errores Android (30d)
897 047
~44× más que iOS
Errores iOS (30d)
20 598
estable
Errores Android release actual
415 039
release anterior: 454 338 (−8,6 %)
Releases iOS vs Android
+489 / +500
Mismo semver, build number distinto por plataforma

Android concentra ~44× más errores que iOS → priorizar QA en dispositivos Android. Nota: los release IDs de iOS y Android difieren aun siendo la misma versión semántica (3.5.1 iOS = build +489, Android = build +500).

HTTP / Requests top latencia (3.5.1+500)

Latencias de las peticiones HTTP que hace el cliente mobile, agrupadas por endpoint. p75 = el 75 % de las llamadas fueron más rápidas que este valor (caso típico). p95 = sólo el 5 % superan este valor (cola lenta). Un p95 mucho mayor que el p75 indica varianza alta (timeouts, redes lentas, servidor intermitente).

Endpoint p75 p95
GET /api/public/v1/config?lang=es527 ms1 660 ms
GET /internal/mobile/version496 ms1 637 ms
GET /internal/mobile/feature-flag/sign_up517 ms1 631 ms
GET /api/in/v1/widgets?…summary_finance1 049 ms1 111 ms
GET /api/in/v1/widgets?…barchart_revenue1 035 ms1 091 ms

Excluyendo pings clients3.google.com/generate_204 (connectivity check de Android, no llamadas reales). Latencias sanas (<2 s p95) — los widgets del dashboard son el cuello principal a ~1 s constante. En 3.4.0+487 aparecían picos a ~6 s en /internal/document/find con rangos de fecha desde 2010, pero son casos edge (1 muestra/endpoint), no representativos.

2 · App Start (p75)

Tiempo desde que el usuario abre la app hasta la primera frame interactiva. Comparativa release actual vs release anterior.

Métrica 3.4.0+487 3.5.1+500 Δ Estado
Cold start p75 4 009 ms 4 018 ms +0,2 % estable
Warm start p75 2 755 ms 2 849 ms +3,4 % estable
Muestras warm (3.5.1+500) 29 181  

Contexto: la release 3.3.0+476 tuvo un pico a ~5,3 s (tanto cold como warm). Desde 3.4 se recuperó el baseline. Umbral de alerta propuesto para el informe: regresión >10 % vs release anterior.

3 · Screen Loads & Frames

Pantallas más lentas en cargar (p75 TTID) y con peor ratio de slow frames. Sólo pantallas con muestra significativa.

Pantalla TTID p75 Muestras Estado
AppStack pantalla raíz post-login 5 160 ms 3 714 alto
SignIn 3 107 ms 178 a vigilar
Dashboard 5 898 ms 22 poca muestra
LockedSession 4 507 ms 24 poca muestra
Pantalla Slow frames rate Frozen frames rate
SignIn32,6 %0 %
DocumentViewer21,4 %0 %
AppStack8,7 %0 %
DocumentPdfViewer5,3 %0 %

Frozen frames prácticamente a 0 % en todos los routes: no hay bloqueos del hilo UI visibles para el usuario. El dolor está en slow frames, concentrado en SignIn y DocumentViewer.

4 · Top Issues por usuarios afectados

Issues sin resolver en producción, ordenados por número de usuarios únicos impactados en los últimos 30 días.

# Issue Usuarios Eventos Culprit
1 MOBILE-NEXT-GEN-266
RevenueCat: "There is no singleton instance"
21 127 1 545 199 tryCallOne · index.android
2 MOBILE-NEXT-GEN-256
ErrorBoundary TypeError: Cannot read property 'currencies' of undefined
5 354 21 499 useCurrency
3 MOBILE-NEXT-GEN-29T
unexpected/no-global-data in startTracker
5 067 18 386 startTracker
4 MOBILE-NEXT-GEN-29A
TypeError: Network request failed
4 903 17 049 anonymous · index.android
5 MOBILE-NEXT-GEN-24E
TypeError: Network request failed
3 919 27 871 anonymous · main
6 MOBILE-NEXT-GEN-298
get-feature-flag sign_up | Network request failed
3 542 70 081 http-global-repository
7 MOBILE-NEXT-GEN-29E
unexpected/no-global-data in startTracker (variant)
3 515 6 736 startTracker
8 MOBILE-NEXT-GEN-202
absences-summary · HTTP 404 Not Found
2 830 50 731 AbsencesSummary
9 MOBILE-NEXT-GEN-2PY
RevenueCat singleton (variant)
2 749 18 588 E · index.android
10 MOBILE-NEXT-GEN-1QG
TypeError: Network request failed (fetch polyfill)
2 637 18 359 whatwg-fetch

Segmentación "nuevo en esta release vs arrastrado" pendiente — requiere cruce con firstRelease del issue; automatizable en el siguiente ciclo.

5 · Acciones sugeridas

Prioridad por impacto (usuarios afectados) × esfuerzo estimado.

  1. Arreglar inicialización de RevenueCat. 21 127 usuarios únicos y 1,5 M de eventos — es con diferencia el issue de mayor alcance. Se usa Purchases antes de configurar el SDK. Mover la llamada de configure() al arranque, antes de cualquier hook que consuma Purchases.getSharedInstance().
    Sigue en 3.5.1+500
    3.4.0+487 445 762 3.5.0+498 7 945 3.5.1+500 409 003
  2. Cerrar useCurrency currencies of undefined. Aparentemente ya no reproduce: en la ventana de 30 días no hay eventos en releases 3.4/3.5, sólo eventos residuales en builds rc viejos (3.0.x/3.1.x). Recomendación: marcar como resolved en Sentry y monitorizar. Si vuelve, el fix sigue siendo añadir guarda en src/shared/modules/account/ui/shared/hooks/useCurrency.ts.
    Ya resuelto en releases recientes
    3.4.0+487 0 3.5.0+498 0 3.5.1+500 0
  3. Cerrar startTracker / no-global-data. Mismo patrón que el anterior: no reproduce en releases 3.4/3.5 dentro de la ventana 30d (últimos eventos en 3.0–3.2). Recomendación: cerrar como obsoleto, validar en la próxima release y bajar prioridad del triage.
    Ya resuelto en releases recientes
    3.4.0+487 0 3.5.0+498 0 3.5.1+500 0
  4. Optimizar TTID de AppStack. p75 a 5,2 s con 3 714 muestras (agregado 30d) — es la pantalla raíz post-login, la ve todo el mundo. Revisar trabajo síncrono en el primer render; candidatos típicos: bootstrap de stores, fetchs bloqueantes, imágenes pesadas.
    Métrica alta, activa
    Cold 3.4.0+487 4 010 ms Cold 3.5.1+500 4 019 ms
  5. Triage de absences-summary 404. 2 830 usuarios impactados por un 404 en un endpoint que debería existir — probable desfase de permisos/plan. Alinear con backend o dejar de llamar cuando el usuario no tiene el módulo contratado.
    Sigue en 3.5.1+500 (Android y iOS)
    3.4.0+487 3 386 3.5.1+489 (iOS) 4 813 3.5.0+498 90 3.5.1+500 2 516
  6. Investigar EXC_BAD_ACCESS nativo en iOS (MOBILE-NEXT-GEN-1PR). 1 273 usuarios únicos en una crash nativa que apunta a facebook::react::concreteComponentDescriptorConstructor<T>. Típicamente implica race condition en la bridge de React Native o un componente registrado dos veces. Revisar componentes custom recientes y orden de registro.
    Activo en 3.5.1+489 (iOS)
    3.4.1-rc.1+478 369 3.5.1+489 (iOS) 342 3.5.0+487 35
  7. Arreglar TimeService.calculateTimeDifference. ~600 usuarios sumando variantes (25N, 25M, 26J, 29Y, 2A2, 2A1). Lanza "Both openedTime and closedTime must be set before calculating the difference". Es un bug claro: el método asume ambos timestamps presentes pero se llama en estado parcial. Añadir guarda o devolver null cuando falta alguno.
    Activo en 3.5.1+489 (iOS)
    3.5.1+489 (iOS) 58 3.4.1-rc.1+478 38 3.5.0+487 2
  8. Validación de documentos en inbox (MOBILE-NEXT-GEN-2M2). 303 usuarios y 3 666 eventos con "Invalid documents were found in inbox". El parseo/validación en src/modules/inbox/application/get-incoming-documents está rechazando documentos con esquema distinto al esperado — o el backend envía un shape inesperado, o la validación es demasiado estricta. Revisar payloads de los eventos en Sentry para detectar el patrón.
    Activo en 3.5.1+489 (iOS)
    3.4.1-rc.1+478 1 473 3.5.1+489 (iOS) 842 3.5.0+487 63 3.6.0-rc.0+490 12
  9. Cerrar network errors del cluster fetch failed (29A, 24E, 1QG). ~11 500 usuarios únicos sumando las 3 variantes, pero sin eventos en 3.4/3.5 recientes. Posiblemente ya no reproducen tras algún cambio en capa de red o retry. Recomendación: cerrar como resolved en Sentry y crear alerta si vuelve a dispararse en 3.6.0+.
    Ya resuelto en releases recientes
    3.5.0+498 146 3.4.0+487 0 3.5.1+500 0
  10. Cerrar get-feature-flag sign_up timeouts (298, 259, 20B). 3 542 usuarios afectados históricamente por timeouts al endpoint /internal/mobile/feature-flag/sign_up. Ya no hay volumen en 3.5.1 (sí 84 eventos en 3.5.0+498). Con el p95 actual de ese endpoint en 1,6 s, el timeout ya no debería disparar. Cerrar y monitorizar.
    Ya resuelto en releases recientes
    3.5.0+498 84 3.4.0+487 0 3.5.1+500 0

Cada pastilla muestra el count de eventos del issue en esa release dentro de los últimos 30 días. Tag bad = sigue apareciendo en 3.5.1+500; ok = sin eventos en releases 3.4/3.5 (candidato a cerrar). iOS y Android comparten versión semántica pero distinto build number (p.ej. 3.5.1+489 iOS · 3.5.1+500 Android).