Padrões de escalabilidade
Saiba mais sobre a confiabilidade bem criada → Escalabilidade e planejamento de capacidade
Padrões
| Onde procurar | Qual é a boa aparência |
|---|---|
| Eficiência da consulta SOQL | Consolide consultas usando consultas de relacionamento (Contatos, Cases__r) em vez de consultas separadas por objeto relacionado. Consulte todos os dados necessários uma vez por transação. Foque <50 consultas em transações síncronas, <100 em assíncronas (limites: 100 sincronização, 200 assíncrona). Mantenha 30-50% de margem abaixo dos limites. |
| Massificação da operação DML | Colete registros em Listas, execute uma única instrução DML por tipo de objeto por transação. Use Database.insert/update/delete com o parâmetro allOrNone que controla o comportamento de sucesso parcial. Destino <75 instruções DML por transação (limite: 150). O lote reduz o consumo de DML de N instruções para 1. |
| Gerenciamento de tamanho de heap | Consulte apenas campos obrigatórios (evite SELECT * patterns). Processe grandes conjuntos de resultados em blocos. Limpe coleções após o processamento para memória livre. Meta <4MB de heap em contexto síncrono (limite: 6MB), <8MB assíncrono (limite: 12MB). Erros de heap excedidos indicam a necessidade de padrões de divisão em blocos ou streaming. |
| Otimização de tempo de CPU | Minimize a complexidade computacional em loops. Use Mapas para pesquisas (O(1)), em vez de iteração de lista aninhada (O(n2)). Descarregue os cálculos pesados para contexto assíncrono. Meta <7.000ms de CPU em transações síncronas (limite: 10.000ms), <40.000ms assíncrono (limite: 60.000ms). |
| Linhas de consulta SOQL | Consultas de design retornando tamanhos de conjunto de resultados razoáveis. Use a cláusula LIMIT para limitar os resultados. Foque <25 mil linhas por consulta em contexto síncrono (limite: 50,000). Consultas que se aproximam dos limites devem usar paginação ou passar para processamento assíncrono com o Apex em lote ou o Queueable. |
| Alocação de chamada de API | Monitore o consumo do limite de API de 24 horas por meio da Visão geral do sistema. Operações da API em lote, em vez de chamadas de registro a registro. Armazenar em cache os dados de referência acessados com frequência usando o Cache da plataforma. Foque <70% do limite de API diário para acomodar picos. O limite de API varia conforme a edição e a contagem de licenças. |
| Limites de chamada | Consolidar chamadas externas: coloque vários registros em lote em uma única solicitação de API quando o sistema externo oferecer suporte a ela. Implemente o enfileiramento de solicitação para serializar chamadas. Respeite o tempo total de chamada de 120 segundos por transação. Limite: 100 chamadas por transação. Projete o processamento assíncrono para integrações pesadas de chamada. |
| Código (Apex, Aura, LWC) | Implementar padrões de massificação: processe coleções, não registros individuais, consulte uma vez e armazene em cache no Maps, execute DML único por tipo de objeto. Use consultas de relacionamento para minimizar o consumo de SOQL. Aplique algoritmos eficientes evitando loops aninhados em conjuntos de dados grandes. |
Antipadrões
| Onde procurar | Qual é a aparência ruim |
|---|---|
| SOQL em loops | Problema: Executar consultas SOQL internamente para loops que processam coleções de registros. Impacto: Erro de limite de consulta excedido em mais de 100 registros (limite: 100 consultas por transação). Resolução: Consulte uma vez antes do loop, armazene os resultados em Mapear com chave por campo de relacionamento. Pesquisa de Mapa dentro do loop (padrão de massificação). |
| DML em loops | Problema: Executar instruções inserir/atualizar/excluir dentro de loops. Impacto: Erro de limite de DML excedido em mais de 150 registros (limite: 150 instruções DML por transação). Resolução: Colete registros no loop de lista, execute a instrução DML única após a conclusão do loop. |
| Sem margem de limite do controlador | Problema: Projetar transações que consomem 95% + dos limites do controlador em condições normais. Impacto: Falhas de produção durante pequenos aumentos de carga, nenhuma capacidade para casos de ponta. Resolução: Foque 70% dos limites como um limite operacional. Reserve 30% de margem para picos e casos de ponta. |
| Produtos cartesianos de loop aninhado | Problema: Loops aninhados iterando duas grandes coleções criando operações O(n2). Impacto: O limite de CPU excedeu erros, o limite de heap foi excedido de objetos temporários. Resolução: Use pesquisas baseadas em mapa que convertem O(n2) em O(n). Colete chaves de loop externo, consulte registros relacionados uma vez, pesquise no loop interno. |
| Acúmulo de heap | Problema: O carregamento de uma consulta grande resulta na memória sem processamento em blocos. Impacto: Erro de limite de heap excedido (6 MB de sincronização, 12 MB assíncrono). Resolução: Consulte apenas os campos necessários. Processe em lotes limpando coleções após cada lote. Use o QueryLocator com o Apex em lote para processamento de vários milhões de registros. |
| Sem filtragem no nível do campo | Problema: Selecionar todos os campos (explícitos ou implícitos) quando apenas o subconjunto for necessário. Impacto: Consumo excessivo de heap, execução de consulta mais lenta, limite de linhas SOQL aproximado desnecessariamente. Resolução: Selecione apenas campos obrigatórios para processamento. Use a notação de relacionamento para buscar dados relacionados em uma única consulta, em vez de consultas separadas. |
| Sobreutilização de processamento síncrono | Problema: Processar grandes volumes de dados de modo síncrono em transações do usuário. Impacto: Usuário aguardando operações de vários segundos, os limites de CPU/heap excederam o bloqueio do usuário. Resolução: Mova o processamento pesado para o contexto assíncrono (Lote, enfileirável, Eventos de plataforma). Forneça resposta imediata ao usuário com a pesquisa de status. |
Padrões
| Onde procurar | Qual é a boa aparência |
|---|---|
| Processamento assíncrono | Use o Apex em lote para processar grandes volumes de registros (milhões). Use o Apex enfileirável para orquestração multifator complexa com encadeamento. Use Eventos de plataforma para desacoplamento conduzido por evento. Use o Apex agendado para manutenção periódica. Corresponder padrão assíncrono ao caso de uso: Lote para volume, Enfileirável para complexidade, Eventos para desacoplamento. |
| Implementação do Apex em lote | Projete o método start retornando QueryLocator seletivo para minimizar os registros processados. Configure o tamanho do lote com base na complexidade do registro (200 a 2 mil registros por executar). Implemente a interface stateful apenas quando necessário, pois ela reduz a taxa de transferência. Monitore AsyncApexJob quanto ao sucesso/falha. O lote fornece limites de controlador dedicados por bloco. |
| Arquitetura de eventos de plataforma | Publique eventos para alterações de estado que exigem processamento posterior. Assine usando acionadores do Apex em objetos de evento de plataforma ou assinantes externos por meio do CometD. Projete assinantes idempotentes (a repetição pode entregar eventos várias vezes). Use a retenção de 72 horas para recuperação de falhas temporárias do assinante. |
| Particionamento baseado em data | Processar dados em janelas de tempo: mês atual, no último trimestre, neste ano. Arquive dados históricos para objetos grandes ou armazenamento externo. O particionamento baseado em tempo permite trabalhos em lote paralelos que processam diferentes intervalos de data simultaneamente. A maioria das consultas filtra naturalmente por data, tornando isso eficiente. |
| Particionamento de tipo de registro | Processe diferentes tipos de registro de modo independente. Agende trabalhos em lote separados por tipo de registro habilitando a paralelização. Os tipos de registro costumam se correlacionar a processos comerciais distintos que justificam o processamento independente. Máximo de cinco trabalhos em lote simultâneos por organização exigem particionamento estratégico. |
| Particionamento baseado em geografia | Particione por proprietário, divisão ou território para processar a distribuição. Processe cada região, unidade de negócios ou território de vendas em trabalhos em lote paralelos. O particionamento baseado em geografia aproveita o modelo de compartilhamento: cada trabalho em lote é executado no contexto de um grupo de usuários específico que filtra dados naturalmente. |
| Estratégia de cache | Use o Cache da plataforma (partições de organização/sessão) para dados de referência acessados com frequência. O cache reduz o consumo de consulta e de API. Aloque partições da sessão e da organização em incrementos de MB inteiro; a capacidade padrão varia de acordo com a edição, com capacidade adicional comprável em blocos. A falta de cache deve voltar à consulta. O TTL de cache deve corresponder à frequência de alteração de dados: horas para dados de referência estáticos, minutos para semi-dinâmicos. |
| Massificação de fluxo | Projete fluxos processando coleções de registro usando variáveis Loop e Collection. Crie coleção de registros, realize Obter registros únicos, atualize a coleção com o elemento Atualizar registros único. Evite operações de registro individuais dentro de loops. Os padrões de massificação de fluxo refletem as práticas recomendadas do Apex. |
Antipadrões
| Onde procurar | Qual é a aparência ruim |
|---|---|
| Apenas processamento sequencial | Problema: Trabalho em lote único processando todos os 50 milhões de registros em sequência levando mais de 24 horas. Impacto: Bloqueia outro processamento, esgotamento da janela de manutenção, atrasos voltados para o usuário. Resolução: Particione os dados por data, tipo de registro ou geografia. Execute trabalhos em lote paralelos processando partições independentes simultaneamente. |
| Dependências de integração síncrona | Problema: Transações do usuário bloqueadas aguardando respostas do sistema externo por meio de chamadas síncronas. Impacto: Experiência do usuário vinculada ao desempenho do sistema externo, falhas de tempo limite durante interrupções externas. Resolução: Use Eventos de plataforma para integração assíncrona. Desacople a transação do usuário da disponibilidade do sistema externo. |
| Nenhuma camada de cache | Problema: Consultar os mesmos dados de referência repetidamente entre transações. Impacto: Consumo excessivo de SOQL, desperdício de limite de API, execução de transação mais lenta. Resolução: Implemente o Cache da plataforma para dados de referência acessados com frequência. O cache reduz o consumo do limite do regulador e melhora o desempenho. |
| Empilhamento de trabalhos em lote | Problema: Agendar mais de 20 trabalhos em lote iniciados simultaneamente. Impacto: A acumulação de profundidade da fila, o limite de cinco trabalhos simultâneos causa serialização, tempos de conclusão imprevisíveis. Resolução: O Stagger agenda a distribuição da carga em horas. Consolide trabalhos semelhantes em um único lote com lógica de envio dinâmica. |
| Sobreutilização de lote com estado | Problema: Implementar o Apex em lote com Database.Stateful quando não for necessário. Impacto: Serialização desnecessária de variáveis de membro da instância em invocações execute() e possível acumulação de heap do estado retido. Resolução: Use stateful apenas quando o estado deve persistir entre as invocações de execução. Prefira lotes sem estado para evitar sobrecarga desnecessária de serialização de estado. |
| Design de fluxo de thread único | Problema: Os registros de processamento de fluxo um por um dentro do Loop com elementos individuais Obter/atualizar registro por iteração. Impacto: O controlador limita o consumo proporcional à contagem de registros, falhas de transação em escala. Resolução: Colete registros na variável de coleção, realize Obter registros único, atualize a coleção com o elemento Atualizar registros único fora do loop. |
| Nenhuma estratégia de nova tentativa assíncrona | Problema: Trabalhos assíncronos com falha não foram repetidos automaticamente, exigindo intervenção manual. Impacto: Inconsistências de dados, carga operacional manual, erros de SLA. Resolução: Implemente uma nova tentativa automática com pendências exponenciais. Use os Eventos de plataforma para habilitar a reprodução de fila durável. Monitore AsyncApexJob e alerte sobre falhas contínuas. |
Padrões
| Onde procurar | Qual é a boa aparência |
|---|---|
| Lote vs. seleção enfileirável | Use o Apex em lote para: processando milhões de registros em blocos, operações em massa agendadas, migrações de dados. Use o Apex enfileirável para: fluxos de trabalho de integração de várias etapas com encadeamento, operações que exigem parâmetros de objeto complexos, trabalhos que precisam de um monitoramento melhor que @future. O Apex assíncrono compartilha um limite de 250.000 execuções por 24 horas (DailyAsyncApexExecutions) em Apex em lote, enfileirável, futuro e agendado, em vez de uma alocação específica de Queueable. |
| Encadeamento enfileirável | Implemente fluxos de trabalho de várias etapas enfileirando o próximo trabalho do método execute do trabalho atual. A cadeia habilita o processamento sequencial: chamada → resposta de análise → ação de acompanhamento de enfileiramento. Máximo de 1 enfileiramento por execução enfileirável evita cadeias de fuga. Projete cadeias com detecção de conclusão para evitar loops infinitos. |
| Uso do método @future | Use @future para operações assíncronas simples que não exigem parâmetros complexos (somente primitivos) e sem encadeamento. Limite: 50 chamadas @future por transação do Apex. @future fornece o padrão assíncrono mais simples, mas não tem visibilidade: nenhum monitoramento de trabalho, nenhum encadeamento, nenhum parâmetro complexo. Prefira Enfileirável para novo desenvolvimento. |
| Otimização do Apex agendada | Consolide operações agendadas em um único envio de classe agendável para manipuladores específicos. Máximo de 100 trabalhos agendados por organização exigem consolidação estratégica. Agende durante as horas de folga para reduzir a contenção com as operações do usuário. Use o Apex agendado para orquestração, delegue o processamento pesado ao Apex em lote. |
| Repetição de evento de plataforma | Projetar assinantes que lidam com cenários de repetição: eventos duplicados após falha do assinante, eventos de lacuna após indisponibilidade estendida. Manter o ReplayId processado pela última vez por assinante. Use EventBus.getReplayId() para detectar repetição vs. novos eventos. Implementar processamento idempotente (processar o mesmo evento duas vezes produz o mesmo resultado). |
| Padrão de continuação | Use a continuação para chamadas de execução longa de componentes do Lightning que exigem tempos de resposta >5 segundos. A continuação habilita várias chamadas simultâneas de 120 segundos, melhorando o desempenho percebido para operações paralelas. Limite: Três continuações por solicitação. Implemente a manipulação de tempo limite e o feedback do usuário. |
Para obter exemplos em linha e orientações detalhadas, consulte o pilar Confiabilidade ou navegue no explorador Padrões e antipadrões.