O que realmente roda por trás do Salesforce Flow?
Entenda a arquitetura de execução do Flow Builder: orquestração, limites de governor e o que acontece nos bastidores de cada automação.
Flow não é só arrastar blocos numa tela, por baixo existe um motor de execução com regras bem definidas de ordem, contexto e limites de governança. Entender como ele realmente processa registros, variáveis e chamadas externas muda a forma como você arquiteta automações no Salesforce.
Flow não é Apex visual — e também não é só arrastar caixinha
Existe uma pergunta que parece simples, mas muda completamente a forma como a gente desenha automações no Salesforce:
O que roda de verdade por trás do Flow Builder?
Quando você arrasta um Create Records, um Loop, um Decision ou um Get Records para a tela, o que está executando por baixo? Tem código? Tem linguagem intermediária? A plataforma gera Apex nos bastidores?
A resposta curta é: Flow não é Apex visual. E também não existe nenhuma linguagem pública chamada "FlowScript" ou equivalente. Flow é uma camada declarativa da Salesforce. Você desenha a automação no Flow Builder, a plataforma persiste aquilo como metadata e o runtime interpreta essa estrutura conforme o contexto, os dados e os limites da transação.
A própria Metadata API define Flow como o metadata que representa a estrutura, a lógica e o comportamento de execução de um flow. Ou seja, Flow não é um desenho estático. É uma definição técnica de como uma automação deve se comportar dentro da plataforma.
Esse entendimento muda bastante a conversa.
Quando alguém fala "Flow é no-code", muita gente escuta "Flow é simples". Mas não é bem assim. Flow é declarativo, sim. Mas ele executa operações reais no banco. Ele consome governor limits. Ele participa da ordem de execução. Ele pode disparar trigger, outro flow, validação, Apex, regra de duplicidade — tudo aquilo que um arquiteto Salesforce precisa considerar no design de qualquer solução.
A forma mais honesta de definir Flow é esta:
Flow é automação bulkificada sem código aparente. Não porque ele gera uma classe Apex que você edita depois — não gera. Mas porque ele carrega as mesmas responsabilidades arquiteturais que um código bem escrito teria.
O que o runtime do Flow realmente executa
Quando você usa um Get Records, o Flow Runtime executa uma consulta em registros do Salesforce com base nos filtros configurados. A documentação define que o elemento encontra registros que atendem aos critérios e armazena os valores retornados em variáveis. O modelo mental útil aqui é algo como:
List<Account> accounts = [
SELECT Id, Name
FROM Account
WHERE Type = 'Customer'
];
Mas atenção: isso é só um modelo mental para raciocinar sobre custo e comportamento. O Flow não entrega esse SOQL. Você não vê a query gerada, não edita o comando. O runtime interpreta o metadata do elemento e executa a operação nativa da plataforma.
O mesmo vale para Create Records. Quando você cria um registro no Flow, aquilo é uma operação de banco. O equivalente mental seria um insert:
insert accountsToCreate;
Novamente: não é uma classe Apex criada automaticamente. É o runtime do Flow executando uma operação nativa.
Esse detalhe importa porque evita dois erros comuns de leitura:
- Achar que Flow é "menos sério" porque não tem código visível.
- Achar que todo Flow é Apex disfarçado.
Nenhuma das duas está correta.
O que cada elemento executa por trás
Uma forma prática de construir o modelo mental certo é mapear cada elemento para sua semântica de execução:
- Start: Inicia a entrevista do Flow. Em Record-Triggered Flow, a plataforma entrega o registro que disparou a automação, normalmente via
$Record. - Get Records: Executa consulta em registros com base nos filtros definidos. Pense em SOQL controlado pelo runtime.
- Create Records: Executa criação de registro. Mentalmente, um
insert. - Update Records: Executa atualização de registro. Mentalmente, um
update. - Delete Records: Executa exclusão de registro. Mentalmente, um
delete. - Assignment: Altera valor em memória dentro da entrevista do Flow. Não grava nada no banco sozinho.
- Decision: Avalia condições. É o equivalente declarativo de um
if / else if / else. - Loop: Percorre uma coleção item por item. A cada iteração, o Flow armazena temporariamente o item atual em uma variável de loop.
- Formula: Usa o motor de fórmulas da plataforma — o mesmo raciocínio de formula field, validation rule e afins.
- Subflow: Chama outro Flow. Excelente para reaproveitamento, mas aumenta a complexidade da transação.
- Action: Chama uma ação da plataforma: envio de e-mail, aprovação, quick action, Apex invocable, integrações, etc.
- Apex Action: Aqui entra Apex de verdade, via método exposto com
@InvocableMethod. - Screen: Renderiza interface para o usuário em runtime Lightning. Continua controlando navegação, variáveis e ações.
- Pause / Wait: Pausa a entrevista e retoma depois, em outra transação.
- Fault Path: Trata falha de um elemento — DML que falhou, Apex Action com erro, callout problemático. Mas não é uma carta mágica contra governor limits.
Esse mapeamento deveria estar na cabeça de todo admin, consultor e arquiteto que trabalha com Flow. Porque o problema raramente está em saber qual elemento arrastar. O problema está em entender o custo de execução daquele elemento dentro da transação.
O maior perigo: operação de banco dentro de Loop
Aqui é onde muito Flow bonito vira bomba em produção.
Imagine este desenho:
Get Contacts
Loop Contacts
Update Contact
Visualmente parece simples. Tecnicamente, você está executando uma operação DML dentro de um loop. Em Apex, o equivalente seria:
for (Contact c : contacts) {
c.Phone = account.Phone;
update c;
}
Quem já estudou Apex sabe que isso é um sinal claro de problema. A Salesforce trata da mesma forma no contexto de Flow: o Salesforce Code Analyzer para Flow tem uma regra específica que identifica operações de banco dentro de loop — Get Records, Create Records, Update Records e Delete Records — porque cada chamada conta contra os limites da transação. Os limites clássicos de 150 operações DML e 100 queries SOQL por transação se aplicam aqui sem exceção.
O desenho correto seria:
Get Contacts
Loop Contacts
Assignment no Contact atual
Add Contact atual em uma collection
Update Records fora do Loop
O modelo mental em Apex seria:
List<Contact> contactsToUpdate = new List<Contact>();for (Contact c : contacts) { c.Phone = account.Phone; contactsToUpdate.add(c); }
update contactsToUpdate;
O Flow continua visual. Mas o pensamento por trás precisa ser de bulkificação. Isso vale para qualquer projeto minimamente sério: se existe volume, integração, Data Loader, API, Experience Cloud, CPQ, Revenue Cloud ou qualquer operação em massa, você não pode desenhar Flow como se cada registro existisse isolado no mundo.
Flow também está sujeito a governor limits
Outro ponto que precisa ficar claro: Flow não vive fora dos limites da plataforma.
A documentação de limites de Flow é explícita: flows estão sujeitos a limites de transação e, se um elemento fizer a transação exceder governor limits, o sistema executa rollback da transação inteira. Isso pode acontecer mesmo que o elemento tenha um caminho de falha configurado.
Flows autolaunched podem compartilhar os limites da transação que os iniciou. Screen Flows e flows com Wait podem atravessar mais de uma transação, dependendo do ponto de pausa ou avanço do usuário.
Esse ponto é fundamental porque o padrão de falha mais comum não é lógica errada — é escala não prevista. A pessoa testa o Flow com um registro, funciona perfeitamente, ativa em produção e descobre depois que o problema nunca foi a lógica. Era volume.
Um registro passa. Cinco registros passam. Duzentos registros processados em massa por uma integração talvez não passem. E aí não adianta dizer "mas era só Flow". Para a plataforma, operação de banco é operação de banco, independente de onde ela foi originada.
Before Save Flow é um caso especial — e vale entender bem
O Record-Triggered Flow otimizado para atualização rápida — o chamado before save — tem um comportamento diferente dos demais.
Ele executa antes do registro ser gravado no banco. Por isso é ideal para alterar campos do próprio registro que disparou o Flow. A documentação da Salesforce recomenda esse tipo quando o objetivo é atualizar campos, validar dados ou evitar duplicidade no registro em processo de salvamento. A referência também aponta que esse caminho pode ser até 10 vezes mais rápido que o after save em cenários de atualização do próprio registro, porque evita uma gravação extra.
O modelo mental seria algo assim:
for (Account acc : Trigger.new) {
acc.Some_Field__c = 'Novo valor';
}
Você altera o valor em memória antes do commit. Por isso, se o objetivo é apenas preencher um campo do próprio $Record, um before save Flow com Assignment normalmente é a escolha mais eficiente — muito melhor do que disparar um Update Records no mesmo registro após o salvamento.
Essa diferença parece pequena na teoria. Em projeto com alto volume de registros, ela pesa bastante na prática.
Quando o Flow chama Apex — e quando isso faz sentido
Quando você usa uma Apex Action, a natureza da execução muda.
Nesse caso, o Flow chama um método Apex exposto com @InvocableMethod. O Flow continua sendo o orquestrador, mas a lógica executada dentro daquela action é Apex de verdade — com todas as implicações de teste, cobertura, controle de erro e manutenção que isso implica.
Esse é um caminho válido quando:
- A lógica ficou complexa demais para o Flow manter de forma inteligível.
- Existe necessidade de controle mais fino sobre exceções.
- O processamento envolve transformações que virariam um labirinto de elementos declarativos.
- A solução precisa de algo que o Flow simplesmente não oferece nativamente.
E aqui vai uma opinião bem direta: nem tudo precisa virar Apex, mas nem tudo deveria virar Flow. Tem automação que é perfeita para Flow. Tem automação que começa em Flow e deveria terminar em Apex. E tem automação que nunca deveria ter nascido em Flow — especialmente quando a lógica depende de transformações complexas, volume imprevisível ou regras difíceis de manter visualmente por quem vier depois.
Arquitetura boa não é escolher sempre a ferramenta mais nova ou mais visualmente elegante. É escolher a ferramenta que vai sobreviver ao volume, ao próximo release, ao suporte e ao próximo arquiteto que abrir aquilo daqui a seis meses.
O modelo mental correto para pensar em Flow
A estrutura que uso para raciocinar sobre qualquer Flow é esta:
Metadata do Flow ↓ Flow Runtime ↓ Flow Interview ↓ Elementos executados em sequência ↓ Query, DML, fórmula, action, Apex, tela, callout ↓ Tudo dentro dos limites e da transação da plataforma
Esse é o ponto central. Flow não é "arrastar caixinha". Flow é automação transacional em cima da plataforma Salesforce.
- Quando você usa Get Records, pense em consulta com custo de SOQL.
- Quando usa Create Records, pense em
insert. - Quando usa Update Records, pense em
update. - Quando usa Loop, pense em iteração — e em o que está dentro dela.
- Quando usa Decision, pense em condicional.
- Quando usa Assignment, pense em memória, sem custo de banco.
- Quando usa Apex Action, pense em código invocado dentro do fluxo, com todas as implicações de um método Apex.
Essa mudança de mentalidade é o que separa quem monta Flow de quem desenha automação escalável.
Conclusão
Não existe uma linguagem exposta por trás do Flow. O que existe é um runtime declarativo da Salesforce interpretando metadata e executando operações reais da plataforma — com governor limits, ordem de execução, impacto em transação e todas as consequências arquiteturais que isso implica.
Por isso, Flow precisa ser tratado com o mesmo respeito que tratamos Apex, trigger, integração e regra de compartilhamento. Não porque tudo seja código. Mas porque tudo roda dentro da mesma plataforma — e a plataforma sempre cobra a conta: limite de transação, volume de dados, manutenção e impacto em produção.
No fim, a pergunta certa não é apenas:
"Qual elemento eu uso aqui?"
A pergunta que faz diferença é:
"O que este elemento vai executar por trás e qual será o custo disso dentro da transação?"
Quando você começa a pensar assim, o Flow deixa de ser uma ferramenta visual e passa a ser o que realmente é: uma camada poderosa de automação da plataforma Salesforce, que precisa ser desenhada com cabeça de arquitetura.