Versión del documento 2026-05-29 · Objetivo: que el único VPS actual aguante hasta 100 mil MAU sin caerse y que la aplicación se mude a una CDN sin costuras cuando llegue el momento.
| Metric | Valor | Source |
|---|---|---|
| MAU | 100,000 | el objetivo |
| DAU | 30,000 | 30 % del MAU, normal en una aplicación utilitaria |
| WS simultáneos | 10 000 (pico 15 mil) | ~10 % del MAU durante el día, 15 % en el pico |
| Acciones al día | 90,000 | 3 aperturas o llamadas por usuario diario |
| Peticiones de la API HTTP por segundo (media) | 3-5 | sobre todo key_create, host_sync y crash_report |
| Peticiones de la API HTTP por segundo (pico) | 30-50 | tras una publicación masiva que actualiza los números |
count=1 — un único proceso PHP mantiene TODAS las conexiones WebSocket en los arreglos $hosts, $guests, $calls in-memory.File: HostService.kt:1424-1432. Hoy syncPendingHostKeys() se llama cada 60 s y golpea Api.keyCreate por cada clave pendiente sin espera alguna.
Guardar en Prefs per-localId: attempt_at_id y attempt_count_id. Espera: 30 s → 60 s → 2 min → 5 min → 15 min → 30 min (tope). Se reinicia al tener éxito.
File: Vault.kt:213. La misma lógica.
File: GuestConn.kt (5+ lugares). Comparar el nuevo parseNumbers con el anterior, por hash o directamente. Si coinciden, no incrementar AppState.overridesVersion. Esto elimina las oleadas de recomposición —80 lecturas de SharedPreferences × 20 tarjetas— en cada inicialización del WebSocket.
In server.php case 'host_hello' / 'guest_hello': si el mismo device_id / user_key envió un hello hace menos de N segundos, cerrar la conexión sin tocar la base. N = 5 s.
Protección por si un cliente con la lógica rota envía cien hellos por segundo.
In enqueueHostMsg: si este host_id ya tiene más de 200 filas, borrar la más antigua con DELETE FROM pending_host_msgs WHERE host_id=? ORDER BY id ASC LIMIT 1. Protección frente al crecimiento sin fin de la cola ante actividad maliciosa.
In _config.php:
$GLOBALS['apk_url'] = 'https://entrixy.com/entrixy.apk';
$GLOBALS['download_page_url'] = 'https://entrixy.com/download';
In api/version_check.php: 'download_url' => $GLOBALS['apk_url'].
Cuando llegue la mudanza a la CDN, cambiará exactamente una línea en _config.php to https://apk.entrixy.com/entrixy.apk (Cloudflare R2 con dominio propio). No hace falta publicar la aplicación.
El cliente ya verifica la firma del APK al descargarlo (almacén de depuración, véase build.gradle.kts:23-29). Para una CDN eso basta: aunque un nodo de la CDN cambie el archivo, la firma no cuadrará y Android se negará a instalarlo. En el cliente no hace falta nada más.
count=1 Workerman aguanta sin problemas unos 10 mil WebSockets simultáneos: server.php ya arranca con él en la línea 40. El primer cuello de botella será el tiempo de CPU de PHP en el pico de intercambio: 10 mil pongs por segundo más las acciones.
Today $hosts, $guests, $calls son arreglos en memoria dentro de un solo proceso. Para levantar varios procesos hay que llevarlos a Redis:
Si un mensaje llega al trabajador W1 pero el destinatario está en W2, se retransmite por Redis pub/sub.
Effect: escalado lineal hasta el número de núcleos del VPS. Con cuatro núcleos son unas 40 mil simultáneas.
Menos flexible y sin necesidad de Redis. Cada usuario cae siempre en el mismo trabajador. Pero se rompe cuando emisor y destinatario acaban en trabajadores distintos.
entrixy.apk.apk.entrixy.com → conectarlo a través de la CDN de Cloudflare._config.php change $apk_url a la nueva.assembleRelease add r2 cp app-release.apk apk-bucket/entrixy.apk.