A Resposta Curta

A pergunta "Flow ou Apex" recebe uma resposta incorreta quando analisada pela conveniência de escrita ou pela disponibilidade de desenvolvedores. A resposta certa depende de quatro fatores técnicos: quantas transações são processadas por vez, se a lógica exige atomicidade completa, a complexidade das condições e ramificações, e quem fará a manutenção do componente daqui a um ano. O Flow é a escolha declarative padrão para a maioria das automações de negócios – mas há pontos de transição claros onde continuar com o Flow cria um risco operacional, e não apenas um "código menos elegante".

Este artigo aborda a decisão de escolha em si: como identificar antecipadamente se a lógica justifica o uso de Apex e como evitar que a escolha seja feita por padrão, e não por discernimento. A questão da limpeza de Flows e processos de automação existentes que já se acumularam como dívida técnica é discutida em um artigo separado e não faz parte desta discussão.

O que de Fato Distingue os Dois no Nível da Plataforma

Flow é um declarative engine que é traduzido em tempo de execução para instruções que realizam DML e SOQL em nome do usuário, enquanto Apex é um código compilado que roda sob os mesmos Governor Limits, mas com controle direto da ordem das operações. A primeira diferença prática é a Bulkification: um desenvolvedor Apex constrói explicitamente um loop que coleta todos os registros em um único array e executa um DML único, enquanto no Flow é fácil construir um Loop que executa uma operação DML ou uma consulta em cada iteração separadamente — um padrão que atinge o limite de 101 consultas permitidas muito mais rapidamente.

A segunda diferença é o controle transacional. O Apex permite Savepoint e Database.rollback para cancelamento parcial, tratamento de DmlException no nível de registro individual via Database.insert(list, false), e lógica condicional complexa sem limite de profundidade de ramificações. No Flow, o tratamento de erros é definido no nível de Fault Path para cada elemento, e isso funciona bem para cenários lineares, mas se torna difícil de rastrear quando há mais do que algumas rotas de falha paralelas.

Estrutura de Decisão: Quatro Testes Antes de Escolher uma Ferramenta

Teste de Volume

Regra prática: se o processo roda em um único registro como resultado de uma ação do usuário (criação de um Lead, mudança de status de oportunidade), o Flow é quase sempre suficiente. Se o processo roda em dezenas a milhares de registros de uma vez — atualização periódica, processamento de um lote vindo de uma integração, limpeza de dados agendada — Apex com Batchable ou Queueable é a escolha segura, pois oferece controle total sobre a Bulkification e gerenciamento de Governor Limits frente a um volume variável.

Teste de Atomicidade

Deve-se perguntar: se parte da atualização falhar, a outra parte pode permanecer salva? Se a resposta for "não" — por exemplo, atualização de um pedido e criação de um registro de fatura que devem ocorrer juntos — Apex com Savepoint é a maneira correta de garantir isso. O Flow não oferece um rollback completo entre elementos sem a construção manual e complexa de lógica de compensação.

Teste de Complexidade das Ramificações

Um Flow com mais de 6-8 Decision Elements aninhados torna-se difícil de ler e caro de testar, mesmo que cada ramificação individual seja simples. Quando a complexidade da lógica de negócios excede isso, escrever essa mesma lógica como uma função Apex documentada com testes de unidade (@isTest) geralmente é mais barato de manter, mesmo que o tempo inicial de escrita seja maior.

Teste de Manutenção e Propriedade

Deve-se perguntar quem fará a manutenção do componente daqui a um ano, não quem o está construindo agora. Se a equipe de Admin for a responsável por atualizar as regras de negócios de forma contínua — como a alteração de condições de desconto ou valores limite — o Flow é preferível, mesmo que o Apex seja tecnicamente "mais limpo", pois é acessível para atualização sem um ciclo de implantação. Se as alterações exigem conhecimento do esquema de dados e testes de regressão, o Apex é a escolha certa, mesmo que haja apenas uma pequena equipe de desenvolvimento para mantê-lo.

Tabela de Decisão

CritérioEscolha FlowEscolha Apex
Volume de registros em uma única transaçãoAté algumas dezenasCentenas a milhares
Exigência de Atomicidade entre vários objetosNão críticaCrítica — Rollback completo necessário
Número de ramificações de decisãoAté aproximadamente 6-8Acima disso, ou lógica recursiva
Frequência de mudança das regras de negóciosFrequente, por AdminRara, exige testes de regressão
Necessidade de chamar API externa complexaChamada única simples (HTTP Callout)Lógica de Retry, autenticação complexa ou Batch
Exigência de testes automatizados (CI)LimitadaCompleta, @isTest com Coverage
Integração com Scheduled Job regularNão diretamente adequadoNatural via Schedulable

Cenário de Exemplo: Empresa de Equipamentos Médicos com Processo de Aprovação de Pedidos

Uma empresa de equipamentos médicos de médio porte com cerca de 40 representantes de vendas operava um Flow para o processo de aprovação de pedidos: verificação de estoque, cálculo de desconto, criação de registro de aprovação e envio de notificação ao gerente. No início, funcionou bem para um único pedido. Após seis meses, um novo cenário foi adicionado — importação em lote de pedidos de um arquivo de integração com o ERP, que cria entre 200 e 800 pedidos simultaneamente.

O Flow, que era acionado por um Record-Triggered Flow no nível "para cada registro", executava uma consulta de verificação de estoque dentro de cada execução separadamente. Com a importação de 500 pedidos, o sistema excedeu o limite de 100 consultas em uma única transação, e os pedidos falharam sem uma mensagem de erro clara para o usuário. A equipe identificou que o problema não era no Flow em si, mas na adequação entre um processo projetado para um único registro e um cenário de volume que não existia no momento da construção.

A solução não foi abandonar o Flow. A equipe dividiu a lógica: o Flow permaneceu responsável pelo processo manual de um único pedido (teste de baixo volume, necessidade de atualização frequente das regras de desconto pelo Admin), enquanto o processo de importação em lote foi transferido para um Apex Batch Job que realiza Bulkification completa, verifica o estoque em uma única consulta concentrada e executa um DML único para todos os registros. Os dois mecanismos chamam a mesma camada de lógica de negócios compartilhada (uma única Apex Class que o Flow também chama via Invocable Method), para que a regra de desconto não seja mantida duas vezes.

Riscos Comuns e Ações Preventivas

RiscoComo isso se manifesta na práticaAção preventiva
Flow sobre volume que cresce gradualmenteO processo funcionou por seis meses e então falhou silenciosamente por Governor LimitsAvaliar o volume esperado antecipadamente e planejar um ponto de transição para Apex antes de atingir o limite
Duplicidade de lógica de negócios em Flow e ApexDois locais calculam o desconto de forma diferenteCentralizar o cálculo de negócios em uma camada Apex comum que o Flow também chame
Trigger Order inesperadoVários Flows e Triggers no mesmo objeto entram em conflitoUm Trigger Handler centralizado em Apex para cada objeto crítico
Tratamento parcial de erros em Flow complexoParte dos registros é atualizada e parte não, sem visibilidadeTransferir processos que exigem Atomicidade para Apex com Savepoint
Apex sem testes suficientesUma pequena alteração quebra um processo crítico na próxima implantaçãoExigir Coverage real e não apenas uma porcentagem formal, incluindo cenários de falha

Checklist para Decisão Antes da Construção

  • Volume esperado avaliado para o período de um ano, não apenas o estado atual
  • Definido se o processo requer Atomicidade entre vários objetos
  • Contadas as ramificações de decisão esperadas na lógica
  • Confirmado quem fará a manutenção do componente e com que frequência as regras mudarão
  • Verificado se já existe lógica semelhante em Apex ou em outro Flow no mesmo objeto
  • Definido o Trigger Order se houver vários mecanismos de automação no objeto
  • Se Apex for escolhido — cenários de teste definidos, incluindo falha parcial
  • Se Flow for escolhido — Fault Path definido para cada elemento crítico

Como Isso se Conecta à Arquitetura Mais Ampla

A escolha da ferramenta certa para uma automação individual é apenas uma camada em uma imagem mais ampla da arquitetura de CRM, na qual tanto o modelo de dados quanto as permissões afetam o que o Flow ou o Apex podem tocar. Quando a automação cruza a fronteira para uma organização externa — por exemplo, verificação de estoque com o ERP em tempo real — a escolha entre Flow e Apex também se encaixa nas considerações sobre padrões de integração e na questão de como Salesforce se conecta ao ERP em termos de latência e tratamento de falhas.

Em organizações que operam vários Orgs, também é necessário verificar se a lógica de negócios é idêntica em todos eles — um tópico discutido no guia Single Org vs. Multi Org e que afeta a questão de valer a pena centralizar a lógica em um Apex Package compartilhado.

Resumo

A escolha entre Flow e Apex não é uma questão de habilidade da equipe ou gosto pessoal, mas sim o resultado de quatro testes técnicos: volume, atomicidade, complexidade das ramificações e frequência de mudança. O Flow é o declarative default para a maioria das automações que interagem com um único registro e mudam com alta frequência. O Apex é necessário quando há um volume significativo, quando é preciso controle total da transação ou quando a complexidade lógica excede o limite que ainda pode ser mantido por meio de uma interface declarativa. Uma organização que estabelece esses testes como parte de seu processo de trabalho — e não os deixa para o julgamento ad-hoc de cada desenvolvedor — economiza a maioria dos casos em que uma automação que funcionou bem no início se quebra silenciosamente quando o volume cresce.