MQTT vs HTTP costuma ser a primeira decisão de protocolo em um projeto de IoT, e errar nela aparece mais tarde como baterias drenadas, dashboards lentos ou um servidor soterrado por requisições de polling. Este guia compara os dois em overhead, push versus polling, consumo de energia e modelo de conexão, e depois traz um script de benchmark para você medir a diferença na sua própria rede em vez de confiar na palavra de alguém.
Dois Modelos de Comunicação Diferentes
HTTP é um protocolo de requisição/resposta. Um client abre uma conexão, envia uma requisição com método, caminho e headers, e o servidor responde. O servidor não pode falar primeiro. Se um dispositivo precisa saber se há um novo comando esperando, ele tem que perguntar, de novo e de novo.
MQTT é um protocolo de publish/subscribe. Cada client mantém uma única conexão TCP de longa duração com um broker, publica mensagens em topics e assina os topics que lhe interessam. O broker envia as mensagens correspondentes no momento em que elas chegam. Publicadores e assinantes nunca se endereçam diretamente, e é isso que permite que uma única leitura de sensor chegue ao mesmo tempo a um dashboard, a um gravador de banco de dados e a um serviço de alertas. Se quiser ver o que fica no meio, leia o que um broker MQTT faz.
Essa única diferença, quem inicia a conversa, determina quase todos os outros trade-offs abaixo.
MQTT vs HTTP em Resumo
| Aspecto | HTTP (REST) | MQTT |
|---|---|---|
| Padrão | Requisição/resposta, o client sempre inicia | Publish/subscribe por meio de um broker |
| Conexão | Curta ou keep-alive por par client-servidor | Uma conexão TCP persistente por client |
| Push do servidor para o dispositivo | Não nativo (polling, long polling, SSE, WebSocket) | Nativo: o broker envia ao publicar |
| Overhead por mensagem | Linha de requisição mais headers em texto, muitas vezes centenas de bytes | Header fixo mínimo de 2 bytes mais o topic |
| Fan-out | O remetente precisa chamar cada destinatário | O broker entrega a todos os assinantes correspondentes |
| Garantias de entrega | Novas tentativas definidas pela aplicação | QoS 0, 1, 2 embutidos |
| Detecção de offline | Inferida pela ausência de requisições | Keep alive e Last Will |
| Último valor conhecido | Consultar uma API | Retained messages |
| Ferramentas | Universais: navegadores, proxies, CDNs, API gateways | Broker mais bibliotecas client MQTT |
| Melhor em | CRUD, transferência de arquivos, APIs públicas, chamadas pontuais | Telemetria, comandos, estado ao vivo, muitos dispositivos |
Overhead: Bytes na Rede
Toda requisição HTTP carrega uma linha de requisição, um header Host e geralmente content type, content length, authorization, user agent e mais. Tudo isso é texto e tudo é enviado de novo a cada requisição. Para uma leitura de sensor de 20 bytes, os headers podem facilmente ser dez vezes maiores que os dados.
Um pacote PUBLISH do MQTT tem um header fixo de apenas 2 bytes, o nome do topic e o payload. A autenticação acontece uma única vez, no CONNECT. Depois disso, cada leitura custa pouco mais que seu topic e seus dados. O MQTT 5 consegue reduzir ainda mais com topic aliases, que substituem uma string de topic longa por um inteiro pequeno.
O TLS muda o cenário para os dois. O handshake é caro, e clients HTTP que abrem uma nova conexão TLS por requisição pagam esse custo toda vez. O MQTT paga uma vez por conexão. HTTP keep-alive e HTTP/2 reduzem a diferença, mas muitos clients HTTP com recursos limitados não os utilizam.
Push vs Polling
Se a nuvem precisa enviar um comando a um dispositivo, o HTTP oferece três opções: fazer polling com frequência e desperdiçar banda, fazer polling raramente e aceitar latência, ou acoplar um segundo canal como WebSocket ou server-sent events. O MQTT simplesmente entrega. Um dispositivo inscrito em devices/pump-7/cmd recebe um comando assim que ele é publicado, normalmente dentro do tempo de ida e volta da rede.
O polling também escala mal no servidor. Mil dispositivos fazendo polling a cada cinco segundos significam centenas de requisições por segundo, tenha algo mudado ou não. Com MQTT, o broker fica ocioso até haver algo a dizer.
Impacto na Bateria e na Rede
Em dispositivos a bateria, o rádio costuma ser o maior consumidor de energia, e o que importa é com que frequência e por quanto tempo ele fica ligado. O polling HTTP acorda o rádio em uma agenda, abre uma conexão, possivelmente negocia TLS, envia headers e espera uma resposta. O MQTT mantém uma conexão aberta com pequenos pacotes PINGREQ no intervalo de keep alive e, fora isso, só transmite dados reais.
Isso não torna o MQTT automaticamente melhor para todo dispositivo a bateria. Um sensor que acorda uma vez por hora, envia uma leitura e volta a dormir não se beneficia de uma conexão persistente, e um único HTTP POST pode ser mais simples. O modelo de conexão persistente compensa quando os dispositivos enviam com frequência, precisam receber comandos ou devem informar seu status online. Em links celulares, onde cada byte e cada estabelecimento de conexão custam dinheiro, pacotes menores e menos handshakes fazem diferença rapidamente.
Rode Seu Próprio Benchmark MQTT vs HTTP
Os números dependem da sua rede, das configurações de TLS e da biblioteca, então meça. O script abaixo envia 200 pequenas leituras JSON via MQTT para o servidor MQTT público (gratuito) e 200 via HTTP POST para um servidor de teste local, e depois imprime o tempo decorrido de cada um. Instale primeiro as duas dependências.
pip install "paho-mqtt>=2.0" requests
import json
import threading
import time
import uuid
from http.server import BaseHTTPRequestHandler, HTTPServer
import paho.mqtt.client as mqtt
import requests
N = 200
PREFIX = f"connectmq/demo/{uuid.uuid4().hex[:8]}"
reading = json.dumps({"device": "bench-1", "temp": 21.7, "hum": 48})
# --- Endpoint HTTP local mínimo ---
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
self.rfile.read(int(self.headers["Content-Length"]))
self.send_response(204)
self.end_headers()
def log_message(self, *args):
pass
server = HTTPServer(("127.0.0.1", 8080), Handler)
threading.Thread(target=server.serve_forever, daemon=True).start()
# --- HTTP: um POST por leitura, nova conexão a cada vez ---
start = time.perf_counter()
for _ in range(N):
requests.post("http://127.0.0.1:8080/telemetry", data=reading,
headers={"Content-Type": "application/json"})
http_new = time.perf_counter() - start
# --- HTTP: reutiliza uma única sessão keep-alive ---
session = requests.Session()
start = time.perf_counter()
for _ in range(N):
session.post("http://127.0.0.1:8080/telemetry", data=reading,
headers={"Content-Type": "application/json"})
http_keepalive = time.perf_counter() - start
# --- MQTT: uma conexão, QoS 1, espera cada PUBACK ---
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"bench-{uuid.uuid4().hex[:8]}")
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_start()
start = time.perf_counter()
for _ in range(N):
info = client.publish(f"{PREFIX}/telemetry", reading, qos=1)
info.wait_for_publish()
time.sleep(0.11) # fica abaixo do limite de 10 msg/s por client do broker público
mqtt_elapsed = time.perf_counter() - start - N * 0.11
client.loop_stop()
client.disconnect()
server.shutdown()
print(f"HTTP new connection : {http_new:.2f}s")
print(f"HTTP keep-alive : {http_keepalive:.2f}s")
print(f"MQTT QoS 1 (net) : {mqtt_elapsed:.2f}s")
Duas ressalvas mantêm a comparação honesta. O servidor HTTP roda em localhost, então não há ida e volta pela internet, enquanto o broker MQTT é remoto; aponte o teste HTTP para um endpoint remoto real se quiser um teste de latência equivalente. Além disso, o servidor MQTT público limita cada client a 10 mensagens por segundo, por isso o script dorme entre as publicações e desconta esse tempo. Para contar bytes em vez de tempo, rode o mesmo script com o Wireshark e compare o total de bytes por leitura. Geralmente é aí que a diferença fica mais evidente.
Quando o HTTP É a Escolha Certa
O HTTP continua sendo a melhor ferramenta em várias situações:
- Envios esporádicos de dispositivos que dormem por longos períodos e nunca precisam de comandos.
- Transferências grandes, como imagens de firmware, logs ou snapshots de câmera, em que range requests HTTP, CDNs e cache brilham.
- APIs públicas e para parceiros, em que todo desenvolvedor e toda ferramenta já falam REST.
- Redes restritivas que só permitem HTTPS de saída. Mesmo aqui, MQTT sobre WebSocket seguro costuma ser permitido, porque começa como um upgrade HTTPS comum.
Muitos sistemas reais usam os dois: MQTT para telemetria, comandos e status, HTTP para provisionamento, download de firmware e APIs de back-office. Um pequeno serviço de ponte que assina o MQTT e expõe um endpoint REST é um padrão comum; o guia de MQTT para API REST com Flask mostra um exemplo.
Quando o MQTT É a Escolha Certa
Escolha MQTT quando os dispositivos reportam com frequência, quando a nuvem precisa alcançar os dispositivos rapidamente, quando vários consumidores precisam dos mesmos dados ou quando você precisa saber quais dispositivos estão online. Retained messages entregam o estado atual a quem chega depois, o Last Will publica um status offline quando um dispositivo cai e os níveis de QoS permitem trocar overhead por garantias de entrega a cada mensagem. O artigo sobre o modelo publish/subscribe do MQTT explica por que desacoplar produtores de consumidores importa à medida que o sistema cresce.
O custo do MQTT é que você precisa de um broker, e operá-lo de forma confiável é trabalho operacional de verdade, de certificados TLS a limites de conexão. O ConnectMQ cuida dessa parte para você. Esse é o principal motivo pelo qual equipes escolhem um broker MQTT gerenciado em vez de manter o próprio. Se você ainda está construindo os fundamentos, o tutorial de MQTT aborda topics, QoS e sessões passo a passo.
Checklist de Decisão
- O servidor precisa enviar dados ou comandos aos dispositivos? Se sim, tenda ao MQTT.
- Os dispositivos enviam dados mais do que algumas vezes por hora? Se sim, tenda ao MQTT.
- Vários serviços consomem os mesmos dados? Se sim, tenda ao MQTT.
- O payload é grande ou a troca é uma transferência de arquivo pontual? Se sim, use HTTP.
- Terceiros precisam integrar usando ferramentas web padrão? Exponha HTTP na borda do seu sistema.
- O status online/offline é importante? O MQTT oferece keep alive e Last Will de graça.
Experimente MQTT no ConnectMQ
A forma mais rápida de resolver MQTT vs HTTP no seu projeto é rodar seu próprio dispositivo contra um broker real. O ConnectMQ oferece um broker privado protegido por TLS nas portas 8883 e 8084, com credenciais geradas, um client MQTT no navegador e um explorador de topics ao vivo. Comece no plano Serverless gratuito em app.connectmq.com, sem cartão de crédito, e compare os resultados com a sua configuração HTTP atual.
Perguntas frequentes
O MQTT é mais rápido que o HTTP?
Para mensagens pequenas e frequentes, geralmente sim, porque o MQTT reutiliza uma única conexão e envia headers muito menores. Para uma única transferência grande, a diferença é pequena e as ferramentas HTTP costumam ser melhores.
O MQTT pode substituir uma API REST?
Pode substituir endpoints de dispositivos baseados em polling, mas REST continua sendo mais adequado para APIs públicas, operações CRUD e transferências de arquivos. A maioria das plataformas de IoT usa os dois.
O MQTT consome menos bateria que o HTTP?
Quando os dispositivos se comunicam com frequência ou precisam receber comandos, normalmente sim, já que não há handshakes repetidos nem polling. Dispositivos que acordam raramente para enviar uma leitura podem ter pouco benefício.
Navegadores podem usar MQTT como usam HTTP?
Sim, por meio de MQTT sobre WebSocket. Clients no navegador se conectam a uma URL como wss://broker.connectmq.com:8084/mqtt usando uma biblioteca como o MQTT.js.



