Skip to main content

Command Palette

Search for a command to run...

MongoClient não é SqlConnection

Updated
4 min readView as Markdown
MongoClient não é SqlConnection
M
6+ years of experience focused on Backend Development (.NET) for mission-critical systems, banking, and judicial data. Specialist in the Microsoft ecosystem with MCSA and MCSD certifications, plus additional certifications in Azure, AWS, and GCP. Focused on C# API and microservices development (.NET Core to .NET 10), emphasizing Background Services (Workers), messaging, and Batch processing.

Um é um gateway que gerencia possibilidades. O outro é um cano rígido. Entendeu a diferença?

Quem está começando com MongoDB no C# normalmente carrega um reflexo do mundo SQL:

“abri a conexão, usei, fechei”.

Em ADO.NET isso faz sentido porque a conexão costuma ser tratada como um recurso de curta duração, frequentemente com pooling no nível do provider.

No MongoDB, essa prática mais atrapalha do que ajuda. O MongoClient não é uma “conexão” no sentido tradicional. Ele é uma estrutura de alto nível que representa o acesso ao seu servidor (o replica set ou o cluster diretamente) e foi desenhado para ficar vivo, ser compartilhado e servir como base para todo o tráfego da aplicação.

Quando você usa o driver do MongoDB, normalmente a jornada é:

  1. Criar um MongoClient usando uma connection string.

  2. Recuperar o banco com GetDatabase(“”).

  3. Recuperar a coleção com GetCollection(“”).

  4. Realizar as operações (Find, InsertOne, UpdateOne, deleteOne, etc.).

Essa sequência parece “barata” à primeira vista, e aí vem o erro comum de “se é só criar um objeto, posso criar sempre que precisar”.


O que o MongoClient realmente faz (a visão técnica):

Em sistemas reais, o driver precisa lidar entre outras coisas com:

  • Pool de conexões:

    em vez de abrir e fechar um socket TCP a cada operação, o driver mantém conexões prontas para reutilizar, reduzindo custo de rede e melhorando latência média.

    Monitoramento em background (Server Discovery and Monitoring — SDAM):

    o driver executa verificações periódicas para entender quais nós estão saudáveis, quem é o primário, quais latências existem, e como reagir a mudanças.

    Reautenticação e handshakes:

    autenticação, negociação e validações iniciais não são gratuitas; repetir isso desnecessariamente aumenta custo.

Nada disso significa que o driver é “lento”. Significa apenas que ele foi desenhado para ficar vivo, justamente para que esses custos sejam pagos poucas vezes e o sistema opere com estabilidade.

Se você ignora isso em uma API com alta concorrência, o sistema tende a criar conexões em um ritmo maior do que o necessário. Quando chega um pico de tráfego, esse excesso faz com que conexões sejam abertas e descartadas o tempo todo, elevando o custo de rede e de autenticação, pressionando CPU/memória, e aumentando a latência justamente no pior momento.

O efeito mais perigoso é que não há falha de forma constante, e sim intermitente, o que dificulta diagnóstico e dá a sensação de “problema fantasma”. Em produção, isso normalmente aparece como:

  • requisições que “às vezes” demoram muito.

  • timeouts que parecem sem padrão.


A regra de bolso (e por que ela funciona)

“Não criarás mais de um MongoClient por aplicação, porque caos e latência já existem sem a sua ajuda.” — Marcus Costa

E como garantir isso de forma simples em aplicações modernas C#?

Use o contêiner de injeção de dependência do ASP.NET Core (ou equivalente) e registre o MongoClient como Singleton.

Nesse contexto, Singleton significa que o MongoClient é instanciado uma vez no início da aplicação e passa a ser compartilhado por toda a execução, evitando recriação do cliente.

...

using MongoDB.Driver;

var builder = WebApplication.CreateBuilder(args);
var mongoConn = builder.Configuration.GetConnectionString("Mongo");

builder.Services.AddSingleton<IMongoClient>(sp => new MongoClient(mongoConn));

...

var app = builder.Build();

app.MapControllers();
app.Run();

Dúvidas comuns

“Eu preciso dar Dispose() no MongoClient?”

  • Em geral, não no meio da aplicação e muito menos por request. Se for encerrar, encerre no shutdown do processo. Em aplicações com DI, o container normalmente coordena o ciclo de vida.

“Posso criar IMongoDatabase e IMongoCollection uma vez e reutilizar?”

  • Sim, geralmente é o que se faz. São referências derivadas do client e tornam o código mais simples e eficiente.

“E se eu tiver vários bancos?”

  • Se for o mesmo cluster/servidor, normalmente um único MongoClient resolve, recuperando os bancos via GetDatabase. Se forem clusters distintos (ou credenciais totalmente distintas), faz sentido ter mais de um MongoClient, mas ainda assim um por cluster, não um por requisição.

Obrigado por acompanhar o artigo até aqui. Algumas pequenas decisões de ciclo de vida, como reutilizar o MongoClient, costumam fazer uma diferença grande em estabilidade e previsibilidade da aplicação.​

Se quiser acompanhar mais conteúdos e projetos: