Versão do documento 2026-05-29 · Objetivo: o atual e único VPS deve aguentar até 100 mil MAU sem cair, e a aplicação mudar-se para uma CDN sem costuras quando chegar a altura.
| Metric | Valor | Source |
|---|---|---|
| MAU | 100,000 | o objetivo |
| DAU | 30,000 | 30 % do MAU, normal numa aplicação utilitária |
| WS simultâneos | 10 000 (pico 15 mil) | ~10 % do MAU durante o dia, 15 % no pico |
| Ações por dia | 90,000 | 3 aberturas ou chamadas por utilizador diário |
| Pedidos da API HTTP por segundo (média) | 3-5 | sobretudo key_create, host_sync e crash_report |
| Pedidos da API HTTP por segundo (pico) | 30-50 | após um lançamento em massa que atualiza os números |
count=1 — um único processo PHP mantém TODAS as ligações WebSocket nos vetores $hosts, $guests, $calls in-memory.File: HostService.kt:1424-1432. Hoje syncPendingHostKeys() é chamada a cada 60 s e bate em Api.keyCreate por cada chave pendente sem qualquer recuo.
Guardar em Prefs per-localId: attempt_at_id e attempt_count_id. Recuo: 30 s → 60 s → 2 min → 5 min → 15 min → 30 min (limite). Reposto em caso de sucesso.
File: Vault.kt:213. A mesma lógica.
File: GuestConn.kt (5+ locais). Comparar o novo parseNumbers com o anterior, por hash ou diretamente. Se forem iguais, não incrementar AppState.overridesVersion. Isto elimina as ondas de recomposição — 80 leituras de SharedPreferences × 20 cartões — em cada inicialização do WebSocket.
In server.php case 'host_hello' / 'guest_hello': se o mesmo device_id / user_key enviou um hello há menos de N segundos, fechar a ligação sem tocar na base. N = 5 s.
Proteção caso um cliente com a lógica partida envie cem hellos por segundo.
In enqueueHostMsg: se este host_id já tem mais de 200 linhas, apagar a mais antiga com DELETE FROM pending_host_msgs WHERE host_id=? ORDER BY id ASC LIMIT 1. Proteção contra o crescimento sem fim da fila perante atividade 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'].
Quando a mudança para a CDN acontecer, muda exatamente uma linha em _config.php to https://apk.entrixy.com/entrixy.apk (Cloudflare R2 com domínio próprio). Não é preciso lançar a aplicação.
O cliente já verifica a assinatura do APK ao descarregar (keystore de depuração, ver build.gradle.kts:23-29). Para uma CDN isso basta: mesmo que um nó da CDN troque o ficheiro, a assinatura não confere e o Android recusa instalá-lo. No cliente não é preciso mais nada.
count=1 O Workerman aguenta sem dificuldade cerca de 10 mil WebSockets em simultâneo — o server.php já arranca com ele na linha 40. O primeiro estrangulamento será o tempo de CPU do PHP no pico de troca: 10 mil pongs por segundo mais as ações.
Today $hosts, $guests, $calls são vetores em memória dentro de um único processo. Para correr vários processos é preciso movê-los para o Redis:
Se uma mensagem chega ao trabalhador W1 mas o destinatário está em W2, encaminha-se por Redis pub/sub.
Effect: escalonamento linear até ao número de núcleos do VPS. Com quatro núcleos são cerca de 40 mil em simultâneo.
Menos flexível e sem precisar de Redis. Cada utilizador cai sempre no mesmo trabalhador. Mas parte-se quando o remetente e o destinatário ficam em trabalhadores diferentes.
entrixy.apk.apk.entrixy.com → ligá-lo através da CDN da Cloudflare._config.php change $apk_url para o novo.assembleRelease add r2 cp app-release.apk apk-bucket/entrixy.apk.