Início/ Cases/ Signals: previsão de downgrade
Case study · Growth & Predição

O churn não era o vilão. O downgrade era, e ninguém via chegar.

Um score simples de 0 a 10 prevê quem vai cair de patamar antes que aconteça, e vira lista viva pra mídia paga e CRM agirem primeiro.

SaaS B2B · agendamento Growth & Revenue BigQuery · SQL
score de risco
Aviso de confidencialidade. "Agenda Certa" é uma empresa fictícia usada pra descrever este projeto. Os números são ilustrativos e arredondados. A metodologia, a arquitetura de dados, os testes e as decisões de produto são reais, construídos por mim. Nenhum dado proprietário de qualquer empresa aparece aqui.

O contexto

Agenda Certa é um SaaS de agendamento e gestão pra pequenos negócios de serviço, clínicas, salões, estúdios. O negócio cadastra os serviços, define a agenda e recebe os agendamentos dos clientes finais. Quanto mais atendimentos ele conclui, mais a Agenda Certa fatura. O modelo vive de volume.

O cliente que sustenta o negócio tem nome interno: ICP. É o negócio que atende sete ou mais clientes distintos por mês, de forma recorrente. Ele é uma fração da base. Responde pela maior parte do volume.

Todo mês, cerca de um quarto da base de ICP deixava de bater os sete clientes atendidos. A liderança de Growth olhava esse número subir e tratava como churn. A resposta padrão era disparar cupom. Não movia o ponteiro.

A dor da liderança

O time gastava mais de meio milhão por mês em mídia paga sem saber, no clique, se aquele negócio viraria cliente recorrente ou faria um atendimento e sumiria. Pagava o mesmo CAC pra dois perfis opostos.

A base de ICP vazava por um ralo que ninguém tinha mapeado direito. A campanha de reativação com cupom trazia de volta justamente quem só voltava pelo cupom, usava uma vez e ia embora. Um ciclo caro, sem fim.

A liderança sabia que tinha um problema de retenção. Não sabia onde ele morava, quem estava prestes a cair, nem quanto isso custava em volume.

Meu papel

Peguei o problema do zero. Diagnóstico, arquitetura de dados, modelo, desenho do experimento, apresentação executiva e o plano de operação com o time de mídia e CRM.

A ideia central era simples de explicar e difícil de fazer bem: transformar comportamento em sinais que preveem quem vai cair, montar uma lista desses clientes e servir essa lista direto pras plataformas de mídia e pro CRM, agindo antes da queda. Chamei o projeto de Signals.

Como ataquei o problema

Regra número um: dado antes de hipótese. Toda afirmação que chegava ("o problema é preço", "quem usa concorrente churna mais") virava uma pergunta a ser respondida com número, não uma verdade a ser aceita.

Regra número dois: separar fato de hipótese em cada passo, e resolver contradição em vez de conviver com duas narrativas.

Regra número três, a mais importante do ponto de vista técnico: nada de vazamento. Todo sinal usado pra prever o evento de um mês é medido só com dado disponível até o momento da decisão. Isso parece óbvio. Quebra a maioria dos modelos que "acertam 85%" olhando pra trás.

O diagnóstico que virou a chave

Comecei validando a intuição da liderança. Ela estava meio errada, do jeito certo.

O churn de ICP (o cliente que zera os atendimentos) é estável e baixo. Roda perto de 4% ao mês, com pouca variação, e só tem pico sazonal previsível no começo do ano. Não é o vilão.

O vilão é o downgrade. É o ICP que continua ativo, mas cai de sete clientes atendidos pra um, dois, três. Roda perto de 22% ao mês. Seis vezes o churn. Estava num platô alto, sem melhorar sozinho.

Isso muda a estratégia inteira. O churner já foi, caro e improvável de recuperar. O downgrader ainda está na sua casa, só desacelerou. Dá pra reverter, e é barato. A maior parte da perda de status vinha dele.

Traduzi o custo pra língua da liderança. O downgrade tirava algo entre 4% e 5% do volume total de atendimentos da empresa. Todo mês. Um número que ninguém tinha na ponta da língua, e que sozinho justificava o projeto.

A fundação de dados

Antes de qualquer modelo, construí a base. Arquitetura medallion no BigQuery, com uma disciplina: cada tabela validada contra a verdade conhecida antes de seguir pra próxima.

Duas séries temporais na camada silver, uma de atendimentos concluídos por usuário e dia, outra de agendamentos marcados por usuário e dia. Aqui apareceu a primeira armadilha. Agendamento e atendimento são eventos diferentes. O agendamento é a marcação feita pelo cliente final. O atendimento é o serviço efetivamente realizado. Confundir os dois inflava tudo.

Descobri a definição certa de cada evento cruzando os campos de data contra uma tabela de referência de usuário. O atendimento bateu com um dos campos com precisão quase exata (a base reconstruída dava 30.452 contra 30.454 conhecidos). O agendamento bateu 100% com a data oficial de primeiro agendamento. Só depois desse casamento eu confiei na base.

Na camada gold, duas peças que servem qualquer modelo futuro, não só este. Um feature store por usuário e mês, com os sinais medidos point-in-time. Uma tabela de labels com os desfechos de cada mês (recorrente, downgrade, churn). O backtest vira um join entre as duas. Trocar de "downgrade" pra "churn" ou "previsão de ativação" é trocar a coluna de label, sem refazer pipeline.

Essa escolha de arquitetura foi deliberada. O projeto nasceu como o primeiro de vários. A fundação precisava aguentar os próximos sem retrabalho.

Dois tipos de ICP, dois problemas distintos

Uma sutileza que evitou muita confusão. A empresa tinha duas definições de cliente ideal que pareciam a mesma coisa.

O ICP de retenção é quem atende sete ou mais clientes distintos no mês. É medido em clientes atendidos. É o alvo deste projeto.

O ICP de ativação é o novo usuário que faz dois agendamentos em até sete dias. É medido em agendamentos, olhando o primeiro agendamento. É um problema de aquisição, com outra população e outro evento.

Misturar os dois é a receita pra um modelo que não funciona pra nenhum. Mantive separados desde o começo, e a fundação atende os dois.

O que prevê o downgrade

Aqui está o coração do projeto. Rodei um backtest em quase um ano de meses fechados pra descobrir quais sinais separam de verdade quem cai de quem fica.

O sinal mais forte e mais acionável é o ritmo da primeira semana. O ICP que não conclui nenhum atendimento nos sete primeiros dias do mês tem perto de 47% de chance de dar downgrade. Quem conclui cinco ou mais na primeira semana tem menos de 1%. O comportamento da primeira semana entrega o futuro do mês.

O segundo sinal é a faixa de volume do mês anterior. Quem estava no piso do ICP (sete a catorze clientes atendidos) cai a 38%. Quem estava no topo (trinta ou mais) cai a 2%. O risco vive na margem.

Recência e clientes finais distintos reforçam. O negócio que atende muitos clientes finais diferentes quase não cai. O que concentra em poucos, cai muito.

Teve um achado estratégico sobre cupom. Quem usou cupom no mês anterior dá mais downgrade e mais churn. Confirmou a tese de que cupom não segura esse cliente. Atrai quem usa e vaza.

O interessante foi o que caiu. Dois "priors" que a empresa tinha como verdade não se sustentaram no teste. O tipo de e-mail não separava nada. O canal de aquisição não previa retenção de quem já era ICP. Depois que o cliente amadurece, o que manda é o comportamento atual dele, não de onde ele veio. Fato venceu hipótese, duas vezes.

O modelo

Nada de caixa-preta na primeira versão. Um score aditivo de zero a dez, transparente, que combina os sinais validados. Ritmo da semana, faixa de volume, recência, cupom, clientes finais distintos.

A escolha por um score simples foi consciente. Ele é explicável pra liderança e pro time de mídia. E vira o baseline honesto que um modelo de machine learning futuro vai ter que bater. Sem esse baseline, qualquer ML parece bom. É o mesmo raciocínio por trás do score de ICP que fiz no case de ICP e Curva ABC: critério simples e transparente bate modelo complexo que ninguém confia.

O backtest do score foi limpo. Cortando no score cinco ou mais, a lista pega cerca de 42% da base, captura perto de 86% dos downgraders e roda a 46% de precisão, contra uma base de 22%. O topo do score (oito a dez) concentra churn. O mesmo modelo ordena a severidade e já entrega o público de churn de brinde.

22%
downgrade mensal do ICP, 6x o churn (~4%)
47%
chance de downgrade sem nenhum atendimento na 1ª semana (vs <1% com 5+)
42%
da base capturada pela lista de risco (score ≥ 5)
86%
dos downgraders capturados pela lista, a 46% de precisão

(números representativos, anonimizados)

A lista e a ativação

O modelo vira uma lista viva, gerada no BigQuery, com os campos de identidade que o Google e o Meta precisam pra casar o público. Cada usuário recebe um score, um tipo de risco e um grupo.

A lista alimenta um Google Sheet, que o Google Ads lê como Customer Match. A mesma lista vai pro HubSpot como lista do mês, ligada a um workflow de retenção. A comunicação é de valor, sem cupom, exatamente pra não repetir o erro do passado.

Um detalhe de operação que fez diferença. A lista serve também pra negativar esses usuários nas outras campanhas. Assim só uma comunicação toca o cliente do teste, e a medição fica limpa.

O experimento

Sem controle, resultado vira achismo. A lista já nasce sorteada.

Cerca de 80% dos usuários entram no grupo alvo e recebem a campanha. Cerca de 20% ficam no holdout e não recebem nada. O sorteio é determinístico por usuário, então o mesmo negócio cai sempre no mesmo grupo, todo mês. O holdout nunca contamina.

A métrica é uma só, definida antes: o percentual que mantém o status de ICP no mês. O lift é a diferença entre a retenção do alvo e a do holdout. Leio no fim do mês, no mesmo calendário que a empresa usa pra medir ICP, pra não descasar as réguas.

Com o tamanho da lista, dá pra detectar uma redução de dois a três pontos percentuais já no primeiro mês. O ganho compõe. Um cliente mantido no ICP segue concluindo atendimentos nos meses seguintes.

O potencial de impacto

Apresentei em cenários, porque o lift real só vem do holdout. Prometer número fechado antes do teste seria desonesto.

No cenário base, uma redução de cinco pontos no downgrade do público alvo mantém algo como 535 negócios no nível ICP por mês e recupera perto de 3.750 clientes atendidos mensalmente. No otimista, quase o dobro. Isso é só a primeira versão, sobre uma fatia da perda total, com o modelo aprendendo a cada ciclo.

O número que prende a liderança não é a recuperação da v1. É o tamanho do problema que agora dá pra enxergar e atacar. Perto de 5% do volume da empresa estava indo embora por um evento que ninguém via chegar.

O achado bônus: aquisição

Enquanto validava a atribuição, caiu uma descoberta que virou um projeto separado.

Pro cliente que já é ICP, o canal de aquisição não prevê retenção. Mas pro novo usuário, o canal prevê tudo. Alguns canais convertem cinco vezes mais em ICP de ativação que outros. O gargalo de qualidade não está na conversão de agendamento pra ICP, que é parecida entre canais. Está no passo anterior, fazer o adquirido agendar a primeira vez.

Um canal de volume gigante trazia muita gente que nunca agendava. Outro, pequeno, trazia gente que agendava e ficava. Esse é exatamente o sinal que faz sentido levar pro Google e o Meta, subir lance em quem vira ICP e cortar quem só traz churn. É o ataque direto ao CAC.

Retenção e aquisição são dois modelos, duas populações. Separei os dois. O de retenção subiu primeiro.

O detalhe de calendário que quase passou batido

Perto do go-live, uma pergunta boa do time de mídia. Os atendimentos se concentram em algum dia da semana? Investiguei.

O motor é o dia útil. Os cinco dias úteis pesam parecido, perto de 18% a 20% cada. O fim de semana é morto, sábado e domingo somam menos de 4%. O primeiro atendimento do mês puxa pra segunda.

Isso definiu a data de geração da lista. A janela dos sete primeiros dias sempre contém um de cada dia da semana, então ela é balanceada entre meses. Mas os dias úteis podem cair no fim da janela. Num mês em que a primeira segunda cai no dia seis, gerar a lista antes do dia oito marcaria a base inteira como risco. A regra virou clara: gerar no dia oito, nunca antes.

Stack de ferramentas

CamadaFerramentas
Data warehouse e modelagemGoogle BigQuery, SQL puro, tabelas particionadas e clusterizadas, arquitetura medallion (bronze / silver / gold), scheduled queries idempotentes com append por partição
Métodos analíticosFeature engineering point-in-time, backtest em meses fechados, análise de cohort, RFM, score aditivo transparente, desenho de holdout e leitura de incrementalidade (lift)
Fontes de comportamento e atribuiçãoGoogle Analytics 4 e Firebase (comportamento web e app), HubSpot (CRM)
Ativação de mídia e CRMGoogle Ads (Customer Match, Demand Gen), Meta Ads (Custom Audiences), Google Sheets (Connected Sheets como ponte), HubSpot (listas e workflows), identificadores hasheados em SHA-256
Comunicação executivaDeck gerado por código com PptxGenJS, storytelling em cinco atos, QA visual automatizado
Método de trabalhoDesenvolvimento assistido por LLM (modelo como operador de SQL e documentação), estratégia e validação de cada número por mim
BigQuery SQL GA4 Firebase HubSpot Google Ads Customer Match Meta Ads Custom Audiences Google Sheets PptxGenJS

Estrutura do repositório

signals-downgrade/
├── README.md                         visão geral do case
├── docs/
│   ├── 01-contexto-e-plano.md        diagnóstico, decisões, arquitetura
│   ├── 02-runbook-operacional.md     BigQuery, Sheets, Google, HubSpot
│   ├── 03-experimento-holdout.md     desenho do teste e leitura do lift
│   └── 04-padroes.md                 convenções e aprendizados
├── sql/
│   ├── silver/
│   │   ├── slv_atendimentos_uid_dia.sql
│   │   └── slv_agendamentos_uid_dia.sql
│   ├── gold/
│   │   ├── gld_features_uid_mes.sql  feature store point-in-time
│   │   ├── gld_labels_uid_mes.sql    desfechos por mês
│   │   └── gld_publico.sql           lista viva + score + holdout
│   └── validacao/
│       ├── backtest_sinais.sql       poder de separação por sinal
│       └── leitura_lift.sql          alvo vs holdout no fim do mês
└── deck/
    ├── build_deck.js                 geração do deck executivo
    └── case-deck.pdf

A convenção de nomes segue o padrão camada, fonte, domínio e grão. Bronze pra dado cru, silver pra dado limpo, gold pra dado de negócio. Tudo idempotente, particionado por data e agendado.

O que eu tiraria como aprendizado

Validar a intuição da liderança rende mais que confirmá-la. O churn não era o problema. Descobrir isso com número mudou a aposta inteira e economizou meses de esforço no lugar errado.

Point-in-time não é detalhe. É a diferença entre um modelo que funciona no ar e um que só brilha no retrovisor.

Um baseline simples e transparente ganha de um modelo complexo que ninguém entende. Principalmente quando você precisa que o time de mídia e a liderança comprem a ideia.

Holdout desde o primeiro dia. Ele é o que separa "achamos que funcionou" de "provamos que funcionou".

Próximos passos

A v1 sobe com o modelo de downgrade e o holdout. Na sequência, o modelo de churn de ICP, que os scores altos já entregam quase de graça. Depois, a previsão de ICP de ativação e o modelo de aquisição, atacando o CAC pela qualidade do canal.

A mesma esteira, eventos diferentes. É pra isso que a fundação foi construída assim.

Sua retenção também pode ter um vilão escondido

30 minutos, de graça. Entro nas suas plataformas e mostro se o que está corroendo sua base é churn de verdade ou downgrade disfarçado.

Quero meu diagnóstico grátis →