01
O limite que vale é o menor da cadeia, e ele não está no seu código
A primeira reação de quem recebe o relato é abrir o código do serviço e procurar onde o tamanho máximo do corpo está configurado. Encontra-se um valor, ele parece generoso, e a conclusão imediata é que o problema deve estar em outro lugar. A conclusão está certa pelo motivo errado: o problema realmente está em outro lugar, porque o valor encontrado no código é apenas um dos quatro ou cinco tetos que uma requisição precisa atravessar, e o que decide o destino dela é o menor deles, não o último.
Uma requisição típica em produção passa por uma rede de distribuição de conteúdo, um balanceador gerenciado, um servidor de borda que faz terminação de conexão segura, um proxy reverso interno e finalmente o processo da aplicação. Cada uma dessas camadas tem um limite próprio, cada uma tem um padrão diferente, e nenhuma delas consulta as outras. O padrão de um servidor de borda popular é um megabyte, o de um gateway gerenciado costuma ser dez, o de um framework de aplicação frequentemente é cem kilobytes, e o da função sem servidor que alguém colocou no meio do caminho no ano passado pode ser seis megabytes com codificação obrigatória em base 64, o que derruba a capacidade útil para pouco mais de quatro.
A consequência prática é que a resposta para a pergunta qual é o tamanho máximo que o meu serviço aceita não pode ser lida em nenhum arquivo de configuração isolado. Ela precisa ser medida atravessando o caminho inteiro, com uma requisição real, do lado de fora. Essa medição leva quinze minutos e é a única forma honesta de responder a um parceiro que pergunta quanto ele pode enviar.
| Camada do caminho | Padrão típico quando ninguém configurou | Formato do erro que ela devolve | Aparece no log da aplicação |
|---|---|---|---|
| Rede de distribuição de conteúdo | Entre 100 MB e sem limite, conforme o plano | Página de erro genérica do provedor | Não, a requisição nunca sai da borda |
| Balanceador gerenciado da nuvem | 1 MB a 10 MB conforme o tipo | Código 413 sem corpo ou com corpo padrão | Só na métrica do balanceador, não na aplicação |
| Servidor de borda ou proxy reverso | 1 MB na configuração padrão mais comum | Página HTML de erro, não JSON | No log do proxy, não no da aplicação |
| Framework ou middleware de corpo | 100 KB em vários ecossistemas | Exceção tratável, formato controlado por você | Sim, e é o único ponto onde isso é verdade |
| Função sem servidor no meio do caminho | 6 MB já contando a codificação de transporte | Erro de invocação, frequentemente 502 | Não, e o rastro fica no provedor |
A coluna mais importante é a última. Em quatro das cinco camadas a requisição recusada não gera nenhuma linha no log da aplicação, o que significa que o painel de erros do time permanece limpo enquanto o parceiro acumula falhas. Esse descompasso é o que faz o incidente durar dias: o suporte pede o identificador de rastreamento da requisição, o parceiro não tem um porque nenhuma resposta o devolveu, e o time procura no lugar onde o evento nunca foi registrado.
Requisicao de 2,4 MB atravessando a cadeia:
cliente
| POST /v1/lotes (2,4 MB)
v
+------------------------+
| CDN limite 100 MB | -> passa
+------------------------+
|
v
+------------------------+
| balanceador limite 10 MB | -> passa
+------------------------+
|
v
+------------------------+
| proxy reverso limite 1 MB | -> RECUSA AQUI
+------------------------+ 413, HTML, sem rastreio
| log da aplicacao: vazio
X (a requisicao morre)
+------------------------+
| aplicacao limite 8 MB | -> nunca executa
+------------------------+
Limite efetivo = min(100, 10, 1, 8) = 1 MB
O valor no codigo da aplicacao (8 MB) e irrelevante.