Saber como escalar um broker MQTT começa por saber qual tipo de carga está realmente crescendo: conexões, mensagens de entrada ou fan-out de saída. Este guia explica cada dimensão, compara escalonamento vertical e horizontal, percorre o cálculo de fan-out de que você precisa para dimensionar e mostra os hábitos no lado do client que muitas vezes importam mais do que o próprio broker.
As Três Dimensões da Carga MQTT
Um broker MQTT faz três tipos diferentes de trabalho, e eles escalam de forma independente.
Conexões. Cada client conectado mantém um socket TCP, uma sessão TLS se houver criptografia, um objeto de estado de sessão e timers de keepalive. A carga de conexões é principalmente memória e descritores de arquivo, e cresce com o tamanho da frota mesmo quando os dispositivos estão em silêncio.
Mensagens de entrada. Cada PUBLISH de um client precisa ser interpretado, autorizado, comparado com as assinaturas e confirmado se o QoS for 1 ou 2. A carga de entrada cresce com o tamanho da frota multiplicado pela frequência de publicação.
Fan-out de saída. Para cada mensagem de entrada, o broker entrega uma cópia a cada assinante correspondente. Uma leitura de sensor consumida por um dashboard, um gravador de banco de dados e um serviço de alertas vira três mensagens de saída. O fan-out é a dimensão que as equipes mais esquecem, e muitas vezes é a maior.
Um quarto fator, mais discreto, é o estado de sessão: sessões persistentes com mensagens QoS 1 enfileiradas para clients offline consomem memória até esses clients voltarem ou a sessão expirar.
Cálculo de Fan-Out: Estimando a Carga Real do Broker
Você não precisa de um benchmark para raciocinar sobre a carga; precisa de aritmética. As fórmulas básicas são:
- Taxa de entrada = dispositivos x mensagens por dispositivo por segundo
- Taxa de saída = soma, para cada topic, de (taxa de entrada naquele topic x assinantes correspondentes)
- O trabalho total do broker é aproximadamente entrada mais saída, com custo extra para as confirmações de QoS 1 e 2 e para o TLS
Aqui está uma pequena calculadora que você pode adaptar à sua frota. Os números nela são um exemplo, não uma medição.
# fanout.py - estimativa aproximada de carga MQTT para planejamento de capacidade
fleet = [
# (nome, dispositivos, msgs_por_dispositivo_por_min, assinantes_por_mensagem, payload_medio_bytes)
("env sensors", 400, 2, 2, 180),
("machines", 60, 60, 3, 600),
("status", 460, 0.1, 1, 20),
]
total_in = total_out = total_bytes = 0.0
for name, devices, per_min, subs, size in fleet:
inbound = devices * per_min / 60
outbound = inbound * subs
total_in += inbound
total_out += outbound
total_bytes += (inbound + outbound) * size
print(f"{name:12s} in={inbound:7.1f}/s out={outbound:7.1f}/s")
print(f"\nTOTAL inbound {total_in:8.1f} msg/s")
print(f"TOTAL outbound {total_out:8.1f} msg/s")
print(f"Approx traffic {total_bytes/1024:8.1f} KB/s (payload only, no protocol/TLS overhead)")
Rode com python fanout.py. Duas lições costumam saltar aos olhos. Primeiro, um punhado de máquinas falantes pode pesar mais do que centenas de sensores lentos. Segundo, adicionar mais um assinante a um topic de alto volume, como um segundo serviço de analytics, pode aumentar a carga de saída mais do que adicionar centenas de dispositivos. Para um passo a passo mais detalhado, leia como estimar mensagens MQTT por segundo.
Escalonamento Vertical vs Horizontal
Há duas formas gerais de dar mais capacidade a um broker.
| Escalonamento vertical | Escalonamento horizontal | |
|---|---|---|
| Como | Máquina maior: mais CPU, memória, rede | Mais nós de broker trabalhando juntos |
| Complexidade | Baixa; configuração quase inalterada | Maior; os nós precisam compartilhar roteamento e estado de sessão |
| Domínio de falha | Um nó | Vários nós, dependendo do design |
| Limite típico | Maior máquina disponível | Overhead de coordenação entre nós |
| Bom para | A maioria das frotas pequenas e médias | Frotas muito grandes ou metas rígidas de redundância |
O escalonamento vertical é subestimado. Um único processo de broker bem ajustado, em hardware adequado, aguenta muito tráfego, e a simplicidade operacional tem valor. O ajuste normalmente envolve aumentar os limites de descritores de arquivo, dimensionar a memória para sessões e mensagens em trânsito e descarregar ou otimizar o TLS.
O escalonamento horizontal significa vários nós de broker atrás de um load balancer. A parte difícil não é adicionar nós, e sim mantê-los consistentes: uma mensagem publicada no nó A precisa chegar a um assinante conectado no nó B, e um client que reconecta em outro nó espera encontrar a sua sessão. Produtos de broker diferentes resolvem isso de formas diferentes, com contrapartidas distintas em latência e consistência.
Um terceiro padrão é o particionamento: rodar brokers separados e independentes para sites, tenants ou linhas de produto distintos. Ele evita totalmente a coordenação entre nós, ao custo de não ter um espaço de topics global. Para muitas implantações com vários sites e vários clientes, como um broker por planta para uma fábrica em Campinas e outra em Manaus, o particionamento é a forma mais simples de crescer.
Escalando o Lado dos Consumidores com Shared Subscriptions
Os consumidores de backend costumam ser o primeiro gargalo. Um único serviço Python que assina acme/# precisa processar cada mensagem que a frota envia. Quando ele fica para trás, as mensagens se acumulam no broker e a memória cresce.
As shared subscriptions do MQTT 5 resolvem isso permitindo que várias instâncias consumidoras dividam uma assinatura. Cada mensagem vai para um membro do grupo, e não para todos. As shared subscriptions estão disponíveis no plano Serverless (Paid) da ConnectMQ.
import os
import paho.mqtt.client as mqtt
GROUP = "writers"
FILTER = "acme/+/+/+/+/telemetry"
def on_connect(client, userdata, flags, reason_code, properties):
print("connected:", reason_code)
client.subscribe(f"$share/{GROUP}/{FILTER}", qos=1)
def on_message(client, userdata, msg):
# Grave no seu banco de dados, fila ou arquivo aqui.
print(os.getpid(), msg.topic, len(msg.payload), "bytes")
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id="YOUR_CLIENT_ID", protocol=mqtt.MQTTv5)
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 8883)
client.loop_forever()
Rode uma cópia por instância consumidora, cada uma com as suas próprias credenciais e client ID. Adicionar uma instância distribui ainda mais a carga sem mexer nos dispositivos.
Hábitos no Lado do Client que Escalam
Muitos problemas de escala são, na verdade, problemas de client. Estes hábitos ajudam em qualquer broker:
- Publique por mudança, não por timer. O report-by-exception reduz drasticamente a carga de entrada para valores que mudam devagar.
- Agrupe leituras. Envie dez amostras em uma mensagem em vez de dez mensagens.
- Use o QoS de forma deliberada. QoS 0 para telemetria de alta frequência em que a próxima amostra substitui a anterior; QoS 1 para eventos e comandos; QoS 2 só onde duplicatas são inaceitáveis. Veja níveis de QoS do MQTT explicados.
- Assine de forma restrita. Um dashboard que mostra um site não deve assinar
#. - Defina keepalives sensatos. Keepalives muito curtos multiplicam o tráfego de PINGREQ em uma frota grande.
- Adicione jitter às reconexões e às publicações periódicas. Milhares de dispositivos publicando exatamente no mesmo segundo criam picos desnecessários.
- Faça expirar o que você não precisa. Session expiry e message expiry impedem que o broker mantenha estado de clients que nunca vão voltar.
- Use topic aliases para topics longos em links restritos. Os topic aliases do MQTT 5 substituem strings de topic longas e repetidas por um inteiro curto.
Quando Migrar para um Plano Maior
Em um broker MQTT gerenciado, escalar é principalmente uma decisão de plano. Na ConnectMQ, a escada é esta:
- Serverless (Free): até 25 conexões, QoS até 1, mensagens de 256 KB. Protótipos e pequenos pilotos.
- Serverless (Paid): até 1.000 conexões, QoS 2, mensagens de 1 MB, shared subscriptions. Frotas em crescimento em um cluster compartilhado.
- Dedicated: um cluster isolado, para que a sua carga não divida recursos com outros tenants.
- BYOC: um broker rodando na sua própria conta de nuvem e gerenciado pela ConnectMQ, útil quando você quer escolher e controlar a infraestrutura.
- Self Managed Enterprise: para organizações que precisam operar o broker por conta própria.
Sinais de que você deve subir de plano incluem aproximar-se do teto de conexões, precisar de shared subscriptions para consumidores de backend ou querer isolamento do tráfego de outros tenants. Converse com a equipe sobre as conexões e taxas de mensagens esperadas para que uma implantação Dedicated ou Enterprise seja dimensionada para a sua carga. Se você está comparando modelos de forma geral, o guia de broker MQTT na nuvem cobre cada um, e alta disponibilidade de broker MQTT explica as perguntas sobre redundância a fazer junto com as de capacidade.
Armadilhas de Escala a Evitar
- Dimensionar pela média. Planeje para os picos, como trocas de turno, tempestades de reconexão e envios de backlog.
- Ignorar os assinantes. Conte o fan-out de saída, não só os dispositivos.
- Um único consumidor gigante com curinga. Divida-o com shared subscriptions antes que vire gargalo.
- Retained messages grandes em todo lugar. Cada novo assinante as recebe imediatamente, o que pesa em curingas amplos.
- Testes de carga contra a produção. Use um broker ou plano separado para testes de carga, para não bater nas suas próprias cotas. O servidor MQTT público (gratuito) serve para testes rápidos e protótipos, não para testes de carga nem para dados de produção.
Escale Sua Frota MQTT com a ConnectMQ
A ConnectMQ permite começar pequeno e subir na escada de planos à medida que suas conexões e seu fan-out crescem, sem mudar protocolos nem o design de topics. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e faça o upgrade quando os números disserem que é hora. Se quiser relembrar o que um broker MQTT faz antes de planejar, comece por aí.
Perguntas frequentes
O que normalmente limita primeiro a escala de um broker MQTT?
Depende da carga. Frotas grandes e silenciosas batem primeiro nos limites de conexões e memória, enquanto frotas movimentadas com vários consumidores por topic batem primeiro nos limites de fan-out de saída.
O escalonamento horizontal é sempre melhor que o vertical?
Não. O escalonamento vertical é mais simples e basta para muitas implantações. O horizontal adiciona overhead de coordenação e vale a pena quando um único nó não atende às metas de capacidade ou de redundância.
Como as shared subscriptions ajudam a escalar?
Elas permitem que várias instâncias consumidoras dividam uma assinatura, de modo que cada mensagem seja processada uma vez por um membro do grupo. Isso elimina o gargalo de consumidor único sem mudar os dispositivos.
Quando devo passar do Serverless para o Dedicated?
Considere o Dedicated quando precisar de isolamento em relação a outros tenants ou esperar uma carga além do que os planos Serverless compartilhados oferecem. Informe as conexões e taxas de mensagens esperadas para que a implantação seja dimensionada corretamente.



