Como calcular taxas de retenção em Real-Time Analytics: passo a passo
Vamos criar um pipeline simples para calcular taxas de retenção em Real-Time Analytics: medir quantos utilizadores que fizeram uma acção no dia de referência voltam em dias seguintes. Este cálculo é essencial para avaliar fidelidade, monitorizar A/B tests e medir o impacto de mudanças de produto em tempo real. A ideia básica é formar coortes pelo primeiro dia de acção e depois medir, para cada dia relativo (day_index), quantos utilizadores dessa coorte voltaram. Em cenários reais, é comum observar retenções de day 1 na ordem dos 20–60% dependendo do produto, e retenções a 7 dias de 5–30%.
Pré-requisitos
- Fonte de eventos em streaming (por exemplo, Event Hubs, Kafka ou outro) com eventos que contenham user_id e event_timestamp. Idealmente cada evento tem também event_id para deduplicação.
- Plataforma de Real-Time Analytics que aceite consultas em streaming (por exemplo, Azure Data Explorer / Kusto ou outro motor compatível). Para grandes volumes considere suportes de stateful processing.
- Ferramenta para visualizar resultados (Power BI, dashboards ou query explorer) que suporte tabelas agregadas e heatmaps para coortes.
Passo 1: Normalizar eventos e criar marcação de dia
É importante converter timestamps para um carimbo de dia consistente (UTC ou uma zona horária escolhida) para comparar dias. A normalização evita que eventos perto da meia-noite sejam colocados em dias diferentes por fusos horários. No exemplo em KQL transformamos o timestamp bruto em datetime e extraímos event_day com startofday(). Em ambientes com milhões de eventos/dia, faça esta transformação o mais cedo possível (na ingestão) para reduzir custo de processamento posterior.
// Exemplo KQL para normalizar eventos
Events
| where event_type == "action"
| extend event_time = todatetime(event_timestamp)
| extend event_day = startofday(event_time)
| project user_id, event_day
Passo 2: Identificar o primeiro dia de evento por utilizador (coorte)
Para calcular retenção precisamos da coorte: o primeiro dia em que o utilizador realizou a acção. Agrupamos por user_id e pegamos o mínimo event_day. Em amostras controladas, se tivermos 1.000 utilizadores com primeira acção em 2026-10-01, esse cohort_day terá cohort_users = 1000. Em produção, quando lidamos com milhões de utilizadores, é comum usar aproximações (por exemplo approx_dcount) para reduzir custo, aceitando um erro de 0.5–1%.
// Calcular a coorte (primeiro dia por user)
let FirstDay =
Events
| where event_type == "action"
| extend event_time = todatetime(event_timestamp)
| extend event_day = startofday(event_time)
| summarize cohort_day = min(event_day) by user_id;
FirstDay
Passo 3: Associar eventos à coorte e calcular diferença em dias
Juntamos os eventos com a coorte para cada utilizador e calculamos o dia relativo (day_index) desde a coorte — por exemplo, 0 é o dia da primeira acção, 1 é o dia seguinte, etc. Isto permite agregar por day_index e ver a evolução ao longo do tempo. No exemplo limitamos a janela a 30 dias, mas pode estender-se a 90 dias ou a 180 dias conforme necessidade. Atenção ao custo: guardar estado para muitas coortes e janelas longas aumenta armazenamento e latência.
// Eventos com day_index relativo à coorte
let EventsWithCohort =
Events
| where event_type == "action"
| extend event_time = todatetime(event_timestamp)
| extend event_day = startofday(event_time)
| project user_id, event_day
| join kind=inner (
FirstDay
) on user_id
| extend day_index = datetime_diff('day', event_day, cohort_day) * -1 // ou: toint((event_day - cohort_day) / 1d)
| where day_index >= 0 and day_index <= 30 // limitar janela, ex: 30 dias
| summarize users_active = dcount(user_id) by cohort_day, day_index;
EventsWithCohort
Passo 4: Calcular tamanho da coorte e taxa de retenção por dia
Agora calculamos o número total de utilizadores na coorte (day_index == 0) e depois a percentagem que voltou em cada day_index. Uma abordagem simples é obter CohortSize e fazer um join; outra é pivotar para construir uma matriz coorte x day_index, útil para heatmaps. Verifique sempre que retention_pct em day_index 0 é 100% (ou perto, se usou aprox_count_distinct).
// Tamanho da coorte (dia 0)
let CohortSize =
EventsWithCohort
| where day_index == 0
| project cohort_day, cohort_users = users_active;
// Retenção percentual por coorte e day_index
EventsWithCohort
| join kind=inner (CohortSize) on cohort_day
| extend retention_pct = todouble(users_active) / todouble(cohort_users) * 100.0
| order by cohort_day, day_index
Passo 5: Optimizar para Real-Time (janelas incrementais e state)
Para Real-Time Analytics, evite recomputar tudo a cada nova mensagem. Use janelas incrementais (tumbling ou sliding) e mantenha um estado com agregados por (cohort_day, day_index). Em soluções como Azure Stream Analytics ou jobs Kusto com update policies, processe por micro-batches (ex.: 5s–1min) e atualize tabelas agregadas. Se tiver 10k coortes ativas e 30 dias de janela, terá até 300k combinações de estado—projete memória e TTL adequados.
// Pseudocódigo para atualização incremental (conceptual)
// 1) Ingerir novo lote de eventos
// 2) Calcular event_day e juntar com tabela FirstDay incremental
// 3) Atualizar agregação agreg_table (cohort_day, day_index) com novos user_ids únicos
// 4) Recalcular retention_pct apenas para cohorts afetadas
Dicas práticas: use deduplicação por (user_id, event_id) com TTL para evitar contagens inflacionadas; quando o volume é muito alto, considere approx_dcount para users_active (erro aceitável de 0.5%). Para latência muito baixa, mantenha uma store de state (ex.: Cosmos DB, KV store) que armazene o primeiro dia por user_id e pequenas agregações por coorte que são incrementadas em streaming.
Verificar o resultado
Valide que cada cohort_day tem um cohort_users (day_index = 0) e que retention_pct é 100% no day_index 0. Teste com dados controlados: por exemplo, crie 1.000 utilizadores com eventos no dia 0; simule que 400 voltam no dia 1 e 180 no dia 7. Espera-se obter retention_pct day1 = 40.0% e day7 = 18.0%. Verifique também contra duplicados: se um utilizador gera 3 eventos no dia 1, só deve contar uma vez (unique user).
Conclusão
Este processo permite calcular taxas de retenção em Real-Time Analytics, mostrando coortes e retenção por day_index para monitorização de produto. Próximos passos práticos: estender a janela para 90 dias se precisa de visibilidade de longo prazo, segmentar por propriedades (país, versão, canal) e criar visualizações em Power BI (heatmap + linhas de tendência). Lembre-se: deduplicação e escolha entre contagem exacta e aproximada são decisões chave para equilíbrio entre custo, precisão e latência. Quer experimentar segmentar por canal de aquisição num exemplo controlado de 1.000 utilizadores para ver o impacto nas taxas de retenção?