Holded Mobile — State of the Nation
mobile-next-gen · production)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.
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.
reportFullyDisplayed())reportFullyDisplayed().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.
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=es | 527 ms | 1 660 ms |
GET /internal/mobile/version | 496 ms | 1 637 ms |
GET /internal/mobile/feature-flag/sign_up | 517 ms | 1 631 ms |
GET /api/in/v1/widgets?…summary_finance | 1 049 ms | 1 111 ms |
GET /api/in/v1/widgets?…barchart_revenue | 1 035 ms | 1 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 |
|---|---|---|
| SignIn | 32,6 % | 0 % |
| DocumentViewer | 21,4 % | 0 % |
| AppStack | 8,7 % | 0 % |
| DocumentPdfViewer | 5,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.
-
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
Purchasesantes de configurar el SDK. Mover la llamada deconfigure()al arranque, antes de cualquier hook que consumaPurchases.getSharedInstance().Sigue en 3.5.1+5003.4.0+487 445 762 3.5.0+498 7 945 3.5.1+500 409 003 -
Cerrar
useCurrencycurrencies 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 ensrc/shared/modules/account/ui/shared/hooks/useCurrency.ts.Ya resuelto en releases recientes3.4.0+487 0 3.5.0+498 0 3.5.1+500 0 -
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 recientes3.4.0+487 0 3.5.0+498 0 3.5.1+500 0 -
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, activaCold 3.4.0+487 4 010 ms Cold 3.5.1+500 4 019 ms -
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 -
Investigar
EXC_BAD_ACCESSnativo en iOS (MOBILE-NEXT-GEN-1PR). 1 273 usuarios únicos en una crash nativa que apunta afacebook::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 -
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 devolvernullcuando 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 -
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 ensrc/modules/inbox/application/get-incoming-documentsestá 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 -
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 recientes3.5.0+498 146 3.4.0+487 0 3.5.1+500 0 -
Cerrar
get-feature-flag sign_uptimeouts (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 recientes3.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).