Autor: George Silva
“Monolito ou microsserviços?” é uma daquelas perguntas clássicas de arquitetura de software que aparece em diversas discussões técnicas. Quase sempre ela vem carregada de opinião, experiência pessoal e, às vezes, um pouco de moda. O problema é que, no mundo real, a resposta raramente nasce de um debate teórico; ela aparece quando o padrão de carga, o modelo de escala e o custo operacional começam a divergir. Foi exatamente isso que aconteceu com a nossa API Pix.
QR Codes Pix
Quem já utilizou o Pix (ou seja, quase toda a população brasileira) sabe que é possível realizar os pagamentos através da leitura de um QR Code. Se formos mais a fundo no funcionamento desses QR Codes, veremos que eles são separados em dois tipos principais: estáticos e dinâmicos.
Os QR Codes estáticos são apenas uma forma conveniente de informar uma chave Pix em um formato 2D, não textual. Por isso, estes QR Codes costumam ser decodificados do lado da própria aplicação cliente (o aplicativo do seu banco, por exemplo), sem a necessidade de uma consulta ao servidor.
Os QR Codes dinâmicos, por sua vez, são mais ricos em atributos e informações, e por isso requerem que uma consulta ao servidor seja realizada para que possam ser decodificados.
QR Codes Pix na Delfinance
No ciclo de vida de cada QR Code Pix, existem no mínimo três ou quatro requisições:
- Criação
- Consulta/decodificação
- Consulta de status para conclusão
- E a própria conclusão
Inicialmente, as operações de QR Codes viviam dentro do mesmo serviço que concentrava todo o ecossistema Pix, e essas operações sozinhas dominavam o uso de CPU e memória e faziam o autoscaling elevar a quantidade de instâncias da aplicação inteira. Foi aí que a pergunta “monolito ou microsserviços?” deixou de ser filosófica e virou engenharia aplicada: por que escalar o sistema inteiro se a pressão está concentrada em uma responsabilidade específica?
O contexto: um monolito Pix com escala acoplada
A API Pix era uma aplicação única em Java com Spring Boot, rodando em serviços serverless na cloud, responsável por processar cash-ins, cash-outs, devoluções, gestão e portabilidade de chaves Pix, além da geração e decodificação de QR Codes, e outras rotinas correlatas. Era um monolito no sentido literal: um único deploy e um único ciclo de escala. Mesmo com uma arquitetura interna bem estruturada, tudo subia e descia junto. E como o autoscaling estava configurado por consumo de CPU e memória, bastava um conjunto de rotas elevar o uso desses recursos para que o o servidor aumentasse a quantidade de instâncias do serviço inteiro.
Aqui vale um ponto técnico que geralmente fica escondido no debate “monolito vs microsserviços”: o acoplamento de escala. Quando várias responsabilidades vivem no mesmo processo, você não escala “funções”, você escala “o processo inteiro”, com tudo que ele carrega. Em infraestruturas de hospedagem serverless, esse acoplamento costuma se traduzir em custo direto quando a carga é assimétrica (isto é, uma parte da aplicação recebe uma carga significativamente maior que as outras).
O diagnóstico: quando um único fluxo “puxa o bonde”
As métricas obtidas através dos serviços de observabilidade deixaram o diagnóstico claro: o pico noturno era puxado, majoritariamente, pelo ato de criar e decodificar QR Codes, com maior pressão por volta da meia-noite. Em alguns períodos, esse conjunto de rotas representava a maior parte do tráfego e do consumo de recursos. Isso não significava que o monolito estivesse “malfeito”; significava que o perfil de carga evoluiu e o modelo de escala ficou desalinhado.
Antes de partir para uma extração, é comum tentar “resolver por dentro”: cache, filas, otimizações, índices, fine tuning, etc. No nosso caso, essas peças não eram novidade. Já atuávamos com filas e cache, e o armazenamento dos QR Codes era feito no MongoDB devidamente indexado; então não se tratava de um gargalo clássico de índices. O ponto principal não era um “bug de performance”; era uma questão de arquitetura operacional: enquanto QR Code estivesse dentro do mesmo processo, o pico de CPU e memória continuaria provocando upscaling do serviço inteiro. Otimizar poderia melhorar números, mas não mudaria a pergunta central do tema “monolito vs microsserviços”: quem está definindo o tamanho e o custo do seu runtime?
A decisão: dividir para conquistar, o nascimento da QR Code API
A decisão foi extrair a gestão de QR Codes para uma API dedicada. A recém-nascida QR Code API passou a concentrar geração, decodificação e consultas relacionadas, incluindo o payload JWS (cadeia de caracteres em Base64 que carrega diversas informações essenciais de um QR Code). Ela ganhou ciclo de deploy, observabilidade e autoscaling próprios, e passou a escalar de forma independente do restante do Pix. A comunicação entre os dois serviços foi desenhada conforme a necessidade de cada fluxo: em alguns casos por HTTP e em outros via AMQP, mantendo a flexibilidade onde fazia sentido.
Esse é um ponto em que o debate “monolito vs microsserviços” costuma confundir duas coisas diferentes: arquitetura de código e arquitetura de deploy. A extração que fizemos foi, antes de tudo, uma decisão de deploy e escala: separar o domínio que dominava recursos para que a infraestrutura deixasse de escalar o sistema inteiro por causa dele.
Para reduzir risco e acelerar a entrega, seguimos uma evolução incremental e não uma “versão purista” de microsserviços. Mantivemos o mesmo MongoDB e a mesma instância de cache, organizando o uso de forma separada quando necessário. Isso evitou reescritas e migrações de dados que não eram essenciais para resolver o problema principal naquele momento: escala e custo.
Migração sem quebrar integrações
A migração precisava preservar compatibilidade. Como a QR Code API era um serviço novo, aproveitamos a oportunidade para resolver débitos técnicos antigos, mas também construímos uma réplica compatível do que existia dentro da API Pix, para que a mudança pudesse ocorrer sem quebra de integração. Atualizamos a documentação e direcionamos novos clientes apenas para o endpoint novo, enquanto clientes existentes migravam de forma gradual e controlada.
O rollout foi feito com feature toggle por número de conta, escolhendo clientes específicos como alvo. Esse mecanismo nos deu previsibilidade e, principalmente, rollback simples: bastava desabilitar o feature toggle e retornar ao caminho anterior. Como o armazenamento continuava no mesmo banco, o comportamento de idempotência e consistência que já sustentava o fluxo permaneceu válido, sem introduzir uma nova classe de problemas nesse aspecto.
Resultados: escalar só o necessário (principalmente à meia-noite)
O resultado foi o que esperávamos: a API Pix deixou de escalar durante a madrugada por causa dos QR Codes. Além disso, conseguimos reduzir o tamanho e quantidade das instâncias da aplicação Pix, porque o seu perfil de CPU/mem passou a refletir apenas os fluxos que realmente lhe pertenciam. A QR Code API nasceu naturalmente menor e passou a escalar conforme sua própria demanda, sem carregar o restante do ecossistema junto. Em latência, também vimos melhora, especialmente por reduzir competição por recursos dentro de um mesmo processo durante o pico noturno.
Naturalmente, nada disso vem de graça. Separar serviços adiciona complexidade operacional: mais um deploy para cuidar, mais pontos para monitorar, mais correlação de logs, métricas e rastreamento entre serviços. No nosso caso, esse trade-off foi positivo porque a assimetria do tráfego era clara, recorrente e custosa. Se o fluxo noturno caísse repentinamente e deixasse de justificar o investimento, provavelmente não valeria manter essa separação. Da mesma forma, se o domínio dos QR Codes tivesse dependências transacionais profundas com outros fluxos do Pix, o custo e o risco da separação poderiam superar o benefício.
Conclusão: microsserviços quando a matemática manda
No fim, ficou claro que a discussão “monolito vs microsserviços”, quando feita de forma madura, é menos sobre preferência e mais sobre critérios técnicos: acoplamento de escala, hotspots de tráfego e custo operacional. Microsserviços não são um objetivo; são uma ferramenta. Quando uma responsabilidade específica domina consumo e obriga você a escalar capacidades que não estão sob pressão, extrair uma fatia do monolito pode ser o caminho mais pragmático para reduzir custo e melhorar performance, desde que você tenha métricas para justificar a decisão, uma estratégia de migração compatível e um plano de rollback simples.
Se o seu produto depende de Pix e precisa crescer sem comprometer custo, latência e previsibilidade, decisões como essa fazem diferença no dia a dia.
A Delfinance opera APIs Pix em produção com foco em estabilidade e evolução contínua. Entre em contato conosco para discutir o seu cenário e entenda como podemos ajudar a escalar a sua operação de forma sustentável.
Leituras recomendadas
Para evoluir a integração com uma visão mais completa de engenharia em sistemas financeiros, confira nossos outros artigos:






