Capacidade por tipo de trabalho no Amazon Connect: o que muda de fato
Durante anos a concorrência do Amazon Connect tratou todo contato de um canal como se custasse o mesmo esforço. Um pedido de segunda via de extrato e um dossiê de contestação com doze anexos entravam no mesmo balde de "até 5 e-mails por agente", e a conta só fechava na média, nunca na cauda. A capacidade por workload type, lançada em 9 de setembro de 2026 para Task e Email, quebra esse balde. É uma mudança pequena na tela de configuração e grande na aritmética de dimensionamento, e vem com um modo de falha que merece uma auditoria antes de qualquer piloto.
Os três números que definem o desenho
connect:WorkloadType aceita até 500 valores; o routing profile aceita 5 linhas por canal. A taxonomia grande não cabe na configuração.MediaConcurrency documenta Channel, Concurrency e CrossChannelBehavior. Nada mais.O que mudou de fato na mecânica de roteamento
O modelo antigo é simples de descrever: o routing profile define Maximum contacts per agent por canal, mais um CrossChannelBehavior por canal. Quatro canais, quatro linhas, fim.
O modelo novo insere uma dimensão entre o canal e o contato. Existe um atributo predefinido de sistema, connect:WorkloadType, que você popula com valores próprios: Dispute-Review, KYC-Refresh, Statement-Request. O contato recebe o valor pelo bloco de flow Set contact attributes ou pela API UpdateContact. No routing profile, o canal Task ou Email deixa de ter uma linha e passa a ter até cinco, cada uma com sua concorrência de 1 a 10 e seu próprio comportamento entre canais.
O comportamento entre canais agora tem três opções, e a do meio é a interessante: nenhum outro canal ou workload type, só outros workload types do mesmo canal, outros canais simultaneamente. Dá para dizer que um agente em Dispute-Review não recebe absolutamente nada, enquanto um agente em Statement-Request acumula três da mesma classe e ainda aceita um chat.
Duas travas importantes. A primeira: um canal não mistura os dois modelos: ligar concorrência por workload type desativa a concorrência por canal naquele canal, e os campos antigos ficam inativos. A segunda: contato sem workload type explícito cai no seu subtype, o que significa que uma migração parcial não quebra o tráfego existente, desde que exista linha para o subtype.
Ciclo de vida de um contato sob concorrência por workload type
O valor de connect:WorkloadType é decidido cedo, no flow ou na API, e determina qual linha do routing profile governa o slot do agente. A linha tracejada para 'sem linha correspondente' é o caminho que não gera erro.
- E-mail de entrada · domínio da instância
- Task via API · ou a partir de um caso
- Set contact attributes · connect:WorkloadType
- UpdateContact · 10 TPS / burst 15
- Queue · FIFO por prioridade e delay
- Routing profile · até 5 linhas por canal
- Dispute-Review · conc. 1 · nenhum outro
- Statement-Request · conc. 3 · mesmo canal
- Sem linha correspondente · contato fica em fila
- Agente no CCP · slots por workload type
- GetCurrentMetricData · SLOTS_AVAILABLE · SLOTS_ACTIVE
- CloudWatch · ConcurrentEmailsPercentage > 80%
Onde isso realmente ganha
UpdateContact, então o classificador pode ser uma regra de negócio, um lookup ou um modelo, sem tocar no routing profile.A fila que isso conserta: contestação de cartão
Pegue uma operação de meios de pagamento com dois tipos de e-mail na mesma fila. Statement-Request é leitura de sistema e resposta de template: quatro minutos, sem anexo, sem decisão. Dispute-Review é dossiê, comprovantes, histórico de autorização, prazo regulatório correndo, e uma decisão que vira dinheiro devolvido ou não devolvido.
No modelo por canal com Concurrency = 5, o agente recebe os cinco. Quatro são template e um é dossiê, e o dossiê perde. Não perde por falta de gente: perde porque o agente é interrompido por quatro coisas triviais enquanto lê um extrato de autorização. O sintoma que aparece no relatório é tempo médio de tratamento subindo devagar, sem culpado.
A configuração nova diz o óbvio em voz alta: Dispute-Review com concorrência 1 e nenhum outro canal ou workload type; Statement-Request com concorrência 3 e só outros workload types do mesmo canal. Soma 4, dentro do teto de 10 por canal.
Dois números moram do lado. E-mail custa US$ 0,080 por mensagem enviada ou recebida: cada reabertura de thread por resposta apressada é um custo direto, além do retrabalho. E o contato de e-mail expira em 14 dias por padrão, ajustável até 90 via o atributo connect:ContactExpiry. Numa disputa com prazo regulatório, esses dois números precisam estar alinhados com o relógio da norma antes de qualquer discussão sobre concorrência.
O modo de falha que não gera erro
Se um contato chega com um valor de connect:WorkloadType que não tem linha correspondente no routing profile do agente, ele permanece na fila indefinidamente. Não há exceção, não há métrica dedicada, não há e-mail devolvido, o contato simplesmente nunca é oferecido. Isso transforma uma divergência entre flow e routing profile num incidente de SLA silencioso, e a divergência é fácil de criar: basta alguém adicionar um valor novo no bloco Set contact attributes e esquecer de um dos routing profiles. Antes do piloto, extraia todos os valores usados em flows e em chamadas de UpdateContact, cruze com o retorno de DescribeRoutingProfile de cada perfil e falhe o pipeline na diferença.
O buraco entre o console e o Terraform
Aqui está a crítica mais séria que tenho ao lançamento, e ela não é sobre roteamento: é sobre como a configuração viaja entre ambientes.
A API pública que mexe em concorrência de routing profile é UpdateRoutingProfileConcurrency, e o objeto que ela recebe é MediaConcurrency. Esse objeto documenta exatamente três campos: Channel com valores VOICE | CHAT | TASK | EMAIL, Concurrency de 1 a 10, e CrossChannelBehavior. Não há campo de workload type. A configuração das cinco linhas por canal é descrita como fluxo do console de administração, e o que não tem forma de API não tem forma de módulo Terraform, não tem plano, não tem diff de pull request.
A consequência prática é conhecida de quem opera contact center há tempo: a configuração de produção passa a divergir de homologação por caminhos que ninguém revisa. Numa operação sob auditoria: BACEN, PCI-DSS, qualquer regime que peça controle de mudança: "foi alterado no console por alguém com o perfil de segurança certo" é uma resposta cara de sustentar.
O que eu faria enquanto isso: manter a taxonomia de workload types como artefato versionado no repositório, com dono, definição e concorrência alvo por routing profile; rodar um job diário que lê DescribeRoutingProfile e ListPredefinedAttributes e compara com o artefato; e tratar divergência como incidente, não como tarefa de backlog. É reconciliação manual, mas é reconciliação auditável, que é o que a auditoria pede.
Os dois modelos, lado a lado
| Concorrência por canal | Concorrência por workload type | |
|---|---|---|
| Granularidade | Uma linha por canal, 4 linhas no total. | Até 5 linhas por canal em Task e Email, soma ≤ 10. |
| Caminho de configuração | Console e UpdateRoutingProfileConcurrency via MediaConcurrency. | Console de administração; a forma de API não está documentada em MediaConcurrency. |
| Falha de configuração | Canal desabilitado: comportamento visível, ninguém recebe. | Valor sem linha: o contato fica na fila sem erro nem alerta. |
Observabilidade: o que medir depois de ligar
A promessa é capacidade mais fiel à realidade. Prova disso são três sinais, e vale conferir a dimensionalidade de cada um na sua instância antes de prometer relatório a alguém.
Slots. SLOTS_AVAILABLE, exposto como Availability, conta quantos slots livres cada agente tem para novos contatos, respeitando os limites do routing profile e ignorando agente em status customizado. SLOTS_ACTIVE conta os ocupados por contatos conectados, em espera, em ACW ou pausados. Os dois vêm de GetCurrentMetricData, cujo teto é 5 TPS com burst 8, não é um endpoint para poll de um segundo.
Concorrência real. AVG_AGENT_CONCURRENCY, no GetMetricDataV2, é tempo de tratamento concorrente dividido por tempo de tratamento mais ocioso. Valor perto de 1 significa que o agente está tratando em série. Se você configurou concorrência 3 num workload type e a métrica fica em 1,1, a configuração não está sendo exercida, ou não há volume, ou a regra entre canais está bloqueando antes.
Saturação da instância. ConcurrentEmails e ConcurrentEmailsPercentage no CloudWatch guardam o teto de 1.000 e-mails ativos por instância; para Task o teto é 2.500 concorrentes. A recomendação da própria documentação é alarme em 80% da cota. Estourar não degrada: a chamada de API falha com erro de cota.
O sinal que não existe pronto é o do modo de falha da seção anterior. Idade do contato mais antigo por workload type, com alarme em um múltiplo do tempo de espera esperado, é o proxy que fecha essa lacuna.
Como adotar sem virar plantão
- 1
Meça a distribuição antes de escolher os cortes
Exporte tempo de tratamento por fila de Task e Email por 30 dias e olhe p50, p90 e p99. Se p90 e p50 estão a menos de 2× de distância, a fila não tem variância para justificar workload types, a concorrência por canal continua sendo a resposta certa.
- 2
Escreva a taxonomia como artefato, não como digitação no console
Cinco linhas por canal contra 500 valores possíveis em
connect:WorkloadTypesignifica que a taxonomia precisa de dono e de critério de fusão desde o primeiro dia. Versione nome, definição, concorrência alvo e comportamento entre canais no repositório. - 3
Não coloque PII no nome do tipo
A documentação é explícita: a informação de atributo predefinido não é criptografada.
VIP-Callbacké aceitável; qualquer valor que carregue nome, documento ou número de conta vira exposição de dado pessoal em telemetria e relatório: LGPD inclusive. - 4
Feche o laço flow ↔ routing profile no pipeline
Um job que lê os valores emitidos por flows e por
UpdateContacte compara comDescribeRoutingProfilede cada perfil, falhando na diferença. É a única defesa contra o contato que fica na fila para sempre. - 5
Ligue em um routing profile e planeje a coexistência
Ao trocar de modelo, os contatos existentes drenam sob as regras antigas enquanto os novos seguem a configuração nova. Escolha uma janela de baixo volume e não meça nada durante o período de coexistência, o número não significa nada ali.
Anti-padrões que já dá para prever
- Uma linha por produto: modelar workload type por linha de produto esgota as 5 linhas antes de expressar qualquer diferença de esforço. A dimensão útil é custo de atenção, não taxonomia comercial.
- Somar 10 porque o teto é 10: o teto do canal é orçamento máximo, não meta. Somar 10 em Email com quatro tipos garante que o tipo mais caro seja interrompido pelos outros três.
- Classificar com modelo sem valor de fallback: se o classificador devolve um rótulo novo em produção e não existe linha para ele, o contato desaparece da operação sem sinal. Fixe o conjunto de saída e trate desconhecido como o subtype.
- Reconfigurar em produção durante o pico: a troca entre modelos cria coexistência, e coexistência com fila cheia é o pior momento para interpretar métrica de capacidade.
Eu ligaria isso em exatamente uma fila, a de maior variância de tempo de tratamento, com dois workload types, não cinco. Dois tipos cabem na cabeça de quem opera e produzem um sinal limpo em AVG_AGENT_CONCURRENCY em duas semanas; cinco produzem uma planilha que ninguém revisa. Antes de tocar no routing profile, eu escreveria o job de reconciliação entre os valores emitidos nos flows e as linhas do perfil, porque a lição que já me custou madrugada é esta: o defeito perigoso não é o que derruba o sistema, é o que faz um contato de cliente sumir sem produzir uma única linha de log. E enquanto MediaConcurrency não tiver campo de workload type, eu trataria toda mudança dessa configuração como mudança manual em produção, com registro e dono, não como ajuste de tela.
Referências
Veredito
Adote em Task e Email quando a fila tiver variância real de esforço, p90 acima de 2× o p50, e quando existir alguém dono da taxonomia de workload types. Nesse cenário, é a correção de um erro de modelagem que estava na plataforma desde que Task existe, e o ganho aparece na cauda, exatamente onde o SLA quebra. Segure em três situações: operação sob controle de mudança rígido, enquanto MediaConcurrency não expuser workload type e a configuração viver só no console; fila homogênea, onde cinco linhas só adicionam superfície de erro; e qualquer adoção que comece antes de existir o job que compara os valores emitidos nos flows com as linhas do routing profile, sem ele, o preço da funcionalidade é um contato de cliente parado em fila sem alarme.
Continue lendo
Deep dives de arquitetura, AWS, IA e mercado: direto no seu email. Grátis.
Sem spam · cancele quando quiser
Pergunte ao Fernando sobre isto
Uma resposta focada sobre este artigo, do meu assistente de IA, baseada no meu trabalho.
Participe da conversa
Entre para comentar
Confirme seu e-mail para participar, você também recebe a newsletter. Sem senha.