Toda arquitetura tem um custo. Mas nem todo custo aparece na fatura da cloud. E é exatamente aí que mora o problema. Quando se fala em custo, a maioria dos times pensa em infraestrutura. CPU, memória e storage requests. Tudo isso é mensurável. Tudo isso aparece no dashboard.
Mas o que realmente pesa… não aparece em lugar nenhum. O custo mais alto da sua arquitetura não é técnico.
É operacional. E, principalmente, humano.
O custo que não está no AWS Billing
Uma arquitetura complexa não cobra só em dinheiro. Ela cobra em tempo. E tempo, em engenharia, é o recurso mais caro que existe. Toda vez que um dev precisa entender um fluxo distribuído, existe um custo. Toda vez que um bug leva horas a mais pra ser reproduzido, existe um custo. Toda vez que um deploy exige coordenação entre múltiplos serviços, existe um custo.
O problema? Ninguém mede isso.
Um exemplo simples de custo invisível: Parece só uma chamada HTTP. Na prática, é latência, falha e retry esperando acontecer.
```javascript
// order-service
async function createOrder(data) {
const order = await db.insert(data);
await axios.post('http://payment-service/pay', {
orderId: order.id,
amount: order.total
});
return order;
}
```
Simples, né? Agora vamos olhar o que isso esconde: Timeout de rede, Retry automático do client, Possível duplicidade de pagamento e Dependência de outro serviço.
Agora imagina isso em produção!! Você começa a ver logs assim:
```bash
Error: timeout of 2000ms exceeded
Retrying request...
Retrying request...
```
E, de repente: pedidos duplicados, pagamentos inconsistentes e clientes reclamando. Esse custo não estava no design inicial. Mas ele está sendo pago.
Complexidade é dívida, mesmo quando parece “boas práticas”
Muita complexidade nasce de boas intenções. Separar serviços, adotar mensageria, introduzir camadas de abstração, etc… Até que você chega nisso:
```javascript
class OrderService {
constructor(orderRepository, paymentGateway, eventBus, logger) {
this.orderRepository = orderRepository;
this.paymentGateway = paymentGateway;
this.eventBus = eventBus;
this.logger = logger;
}
async execute(data) {
const order = await this.orderRepository.save(data);
await this.paymentGateway.process(order);
await this.eventBus.publish('order_created', order);
return order;
}
}
```
Bonito, organizado e testável. Mas agora você precisa entender: repository, gateway, eventbus e fluxo assíncrono. E tudo isso só pra criar um pedido. Isso não é errado. Mas tem custo!
O tempo que você não vê
Um sistema simples permite decisões rápidas. Um sistema complexo exige contexto. Se liga nesse exemplo real: você vai alterar uma regra de pagamento. E no monólito:
```javascript
if (order.total > 1000) {
applyDiscount(order);
}
```
Ou seja, em arquitetura distribuída, você precisa:
- Encontrar onde a regra está
- Ver se está duplicada em outro serviço
- Garantir que eventos não quebram fluxo
- Testar comunicação entre serviços
Uma mudança de 5 minutos vira uma task de meio dia. E ninguém abre um ticket chamado: “custo da complexidade”
Cloud cara não é acidente. Cloud cara é consequência.
Olha esse exemplo típico:
```yaml
# Kubernetes deployment simplificado
replicas: 5
resources:
limits:
cpu: "500m"
memory: "512Mi"
```
Agora multiplica isso por 15 serviços. Mesmo com baixo tráfego, você já está pagando por: Containers ociosos, memória reservada e infra subutilizada
E ainda adiciona: Logs centralizados, tracing distribuído e monitoramento. Ou seja, o custo cresce. Silenciosamente.
O debug que ninguém quer fazer
Num sistema simples, você faz isso:
```bash
grep "error" app.log
```
Num sistema distribuído? Você precisa de:
- Correlation ID
- Tracing distribuído
- Logs agregados
E se não tiver isso bem feito: Você não debuga. Você chuta.
Ou pior: Você reproduz o bug em produção.
Overengineering: o luxo invisível
Existe uma linha muito fina entre preparar o sistema e complicar o sistema. Segue um exemplo clássico:
```javascript
// uso de fila para algo síncrono
await queue.publish('send_email', { userId });
```
Quando poderia ser:
```javascript
await sendEmail(user);
```
A fila pode fazer sentido, mas talvez ainda não. E cada decisão dessas acumula custo. Muito custo!
O custo organizacional
Esse aqui é o mais ignorado. Você cria múltiplos serviços. Agora precisa alinhar:
- Contrato de API
- Formato de evento
- Versionamento
Exemplo real:
```json
{
"event": "order_created",
"version": "v2",
"payload": {
"orderId": "123",
"amount": 100
}
}
```
Agora alguém muda o payload. Quebra outro serviço. E começa o ciclo: Hotfix, Rollback e Incidente.
O paradoxo da arquitetura moderna
Quanto mais ferramentas você usa… Mais você precisa gerenciar.
Kafka, Kubernetes, Redis e Tracing…. Cada uma resolve um problema. Mas todas juntas criam outro: complexidade.
Então por que ninguém mede isso? Porque não cabe em gráfico. Você não mede facilmente o tempo perdido em debug, nem o custo de mudança, nem a carga cognitiva do time.
Mas você sente. Principalmente, no tempo que as entregas levam, na quantidade de bugs e na dificuldade de evoluir o sistema
O que times maduros fazem diferente? Eles não começam pela tecnologia. Eles começam pelo problema. Eles escrevem coisas simples assim:
```javascript
function processOrder(order) {
validate(order);
charge(order);
notify(order);
}
```
E só complicam… Quando dói.
Por isso, sua arquitetura já está custando mais do que você imagina. A diferença é que parte desse custo não aparece na fatura. Aparece no tempo, na fricção e na velocidade que você perdeu — sem perceber.
E esse é o tipo de custo que, quando você nota… Já está caro demais para ignorar.




