MQTT vs HTTP, bir IoT projesinde genellikle verilen ilk protokol kararıdır ve bu kararı yanlış vermenin bedeli daha sonra biten piller, gecikmeli dashboard'lar ya da polling istekleri altında boğulan bir sunucu olarak karşınıza çıkar. Bu rehber iki protokolü ek yük, push ve polling, güç tüketimi ve bağlantı modeli açısından karşılaştırıyor; ardından kimsenin sözüne güvenmek zorunda kalmadan farkı kendi ağınızda ölçebilmeniz için bir benchmark betiği sunuyor.
İki Farklı İletişim Modeli
HTTP bir istek/yanıt (request/response) protokolüdür. İstemci bir bağlantı açar, method, path ve header'lardan oluşan bir istek gönderir ve sunucu yanıt verir. Sunucu konuşmayı başlatamaz. Bir cihaz yeni bir komutun bekleyip beklemediğini öğrenmek istiyorsa tekrar tekrar sormak zorundadır.
MQTT bir yayınla/abone ol (publish/subscribe) protokolüdür. Her istemci broker'a tek ve uzun ömürlü bir TCP bağlantısı açık tutar, topic'lere mesaj publish eder ve ilgilendiği topic'lere subscribe olur. Broker eşleşen mesajları geldikleri anda iletir. Publisher'lar ve subscriber'lar birbirlerine doğrudan hitap etmez; tek bir sensör ölçümünün aynı anda bir dashboard'a, bir veritabanı yazıcısına ve bir alarm servisine ulaşabilmesini sağlayan da budur. Ortada ne olduğunu görmek isterseniz bir MQTT broker'ın ne yaptığını okuyun.
Konuşmayı kimin başlattığına dair bu tek fark, aşağıdaki neredeyse tüm ödünleşimleri belirler.
Bir Bakışta MQTT vs HTTP
| Özellik | HTTP (REST) | MQTT |
|---|---|---|
| Desen | İstek/yanıt, her zaman istemci başlatır | Broker üzerinden publish/subscribe |
| Bağlantı | İstemci-sunucu çifti başına kısa ömürlü ya da keep-alive | İstemci başına tek kalıcı TCP bağlantısı |
| Sunucudan cihaza push | Yerleşik değil (polling, long polling, SSE, WebSocket) | Yerleşik: broker publish anında iletir |
| Mesaj başına ek yük | İstek satırı ve metin header'lar, çoğu zaman yüzlerce bayt | En az 2 baytlık sabit header ve topic |
| Fan-out | Gönderici her alıcıyı ayrı ayrı çağırmalı | Broker eşleşen her subscriber'a iletir |
| Teslim garantileri | Uygulamanın tanımladığı yeniden denemeler | Yerleşik QoS 0, 1, 2 |
| Çevrimdışı tespiti | Gelmeyen isteklerden çıkarım | Keep alive ve Last Will |
| Bilinen son değer | Bir API'yi sorgulamak | Retained message'lar |
| Araçlar | Evrensel: tarayıcılar, proxy'ler, CDN'ler, API gateway'ler | Broker ve MQTT istemci kütüphaneleri |
| En iyi olduğu alan | CRUD, dosya aktarımı, herkese açık API'ler, tek seferlik çağrılar | Telemetri, komutlar, canlı durum, çok sayıda cihaz |
Ek Yük: Hattaki Baytlar
Her HTTP isteği bir istek satırı, bir Host header'ı ve genellikle content type, content length, authorization, user agent gibi daha fazlasını taşır. Bunların hepsi metindir ve hepsi her istekte yeniden gönderilir. 20 baytlık bir sensör ölçümü için header'lar verinin kolayca on katı büyüklüğe ulaşabilir.
Bir MQTT PUBLISH paketinde ise 2 bayta kadar küçülebilen sabit bir header, topic adı ve payload bulunur. Kimlik doğrulama CONNECT sırasında yalnızca bir kez yapılır. Bundan sonra her ölçümün maliyeti, topic'i ve verisinden biraz fazlasıdır. MQTT 5, uzun bir topic dizesini küçük bir tam sayıyla değiştiren topic alias'larıyla bunu daha da küçültebilir.
TLS her ikisi için de tabloyu değiştirir. Handshake pahalıdır ve her istek için yeni bir TLS bağlantısı açan HTTP istemcileri bu bedeli her seferinde öder. MQTT ise bağlantı başına bir kez öder. HTTP keep-alive ve HTTP/2 bu farkı azaltır, ancak kısıtlı kaynaklara sahip pek çok HTTP istemcisi bunları kullanmaz.
Push vs Polling
Bulutun bir cihaza komut göndermesi gerekiyorsa HTTP size üç seçenek sunar: sık sık polling yapıp bant genişliğini israf etmek, seyrek polling yapıp gecikmeyi kabullenmek ya da WebSocket veya server-sent events gibi ikinci bir kanal eklemek. MQTT ise doğrudan iletir. devices/pump-7/cmd topic'ine subscribe olmuş bir cihaz, komut publish edilir edilmez, genellikle ağdaki gidiş-dönüş süresi içinde onu alır.
Polling sunucu tarafında da kötü ölçeklenir. Her beş saniyede bir polling yapan bin cihaz, bir şey değişsin ya da değişmesin saniyede yüzlerce istek demektir. MQTT'de ise broker söylenecek bir şey olana kadar boşta bekler.
Pil ve Ağ Üzerindeki Etki
Pille çalışan cihazlarda en büyük güç maliyeti genellikle telsiz modülüdür ve önemli olan, ne sıklıkla ve ne kadar süre açık kaldığıdır. HTTP polling telsizi belirli bir programla uyandırır, bağlantı açar, muhtemelen TLS müzakeresi yapar, header'ları gönderir ve yanıt bekler. MQTT ise bağlantıyı keep alive aralığında gönderilen küçük PINGREQ paketleriyle açık tutar ve bunun dışında yalnızca gerçek veri iletir.
Bu, MQTT'yi her pilli cihaz için otomatik olarak daha iyi yapmaz. Saatte bir uyanıp tek bir ölçüm gönderen ve tekrar uykuya dalan bir sensör kalıcı bağlantıdan fayda görmez; tek bir HTTP POST daha basit olabilir. Kalıcı bağlantı modeli; cihazlar sık veri gönderdiğinde, komut alması gerektiğinde ya da çevrimiçi durumunu bildirmesi gerektiğinde karşılığını verir. Her baytın ve her bağlantı kurulumunun para ettiği hücresel bağlantılarda daha küçük paketler ve daha az handshake hızla birikerek fark yaratır.
Kendi MQTT vs HTTP Benchmark'ınızı Çalıştırın
Sonuçlar ağınıza, TLS ayarlarınıza ve kütüphanenize bağlıdır; bu yüzden ölçün. Aşağıdaki betik 200 küçük JSON ölçümünü MQTT üzerinden ücretsiz herkese açık MQTT broker'a, 200 tanesini de HTTP POST ile yerel bir test sunucusuna gönderir ve her biri için geçen süreyi yazdırır. Önce iki bağımlılığı kurun.
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})
# --- Minimal yerel HTTP endpoint'i ---
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: her ölçüm için bir POST, her seferinde yeni bağlantı ---
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: tek bir keep-alive oturumunu yeniden kullan ---
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: tek bağlantı, QoS 1, her PUBACK'i bekle ---
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) # herkese açık broker'ın istemci başına 10 msg/s sınırının altında kal
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")
Karşılaştırmayı dürüst tutan iki uyarı var. HTTP sunucusu localhost'ta çalışır, dolayısıyla internet gidiş-dönüşü yoktur; MQTT broker ise uzaktadır. Birebir bir gecikme testi istiyorsanız HTTP testini gerçek bir uzak endpoint'e yönlendirin. Ayrıca herkese açık broker her istemciyi saniyede 10 mesajla sınırlar; bu yüzden betik publish'ler arasında bekler ve bu süreyi toplamdan çıkarır. Süre yerine bayt sayısını görmek için aynı betiği Wireshark altında çalıştırıp ölçüm başına toplam baytları karşılaştırın. Fark genellikle en çarpıcı biçimde burada ortaya çıkar.
HTTP Ne Zaman Doğru Tercihtir?
HTTP birçok durumda hâlâ daha iyi bir araçtır:
- Uzun süre uyuyan ve hiç komut alması gerekmeyen cihazlardan seyrek yüklemeler.
- HTTP range isteklerinin, CDN'lerin ve önbelleğe almanın parladığı firmware imajları, loglar veya kamera görüntüleri gibi büyük aktarımlar.
- Her geliştiricinin ve aracın zaten REST konuştuğu herkese açık ve iş ortağı API'leri.
- Yalnızca giden HTTPS'e izin veren kısıtlayıcı ağlar. Burada bile güvenli WebSocket üzerinden MQTT'ye çoğu zaman izin verilir, çünkü sıradan bir HTTPS upgrade isteği olarak başlar.
Gerçek sistemlerin çoğu ikisini birlikte kullanır: telemetri, komutlar ve durum için MQTT; cihaz kaydı, firmware indirme ve arka ofis API'leri için HTTP. MQTT'ye subscribe olup bir REST endpoint'i sunan küçük bir köprü servisi yaygın bir desendir; Flask ile MQTT'den REST API'ye rehberi bunun bir örneğini gösteriyor.
MQTT Ne Zaman Doğru Tercihtir?
Cihazlar sık veri bildiriyorsa, bulutun cihazlara hızla ulaşması gerekiyorsa, aynı veriyi birden fazla tüketici kullanıyorsa ya da hangi cihazların çevrimiçi olduğunu bilmeniz gerekiyorsa MQTT'yi seçin. Retained message'lar sonradan katılanlara güncel durumu verir, Last Will bir cihaz düştüğünde çevrimdışı durumunu publish eder ve QoS seviyeleri mesaj bazında ek yük ile teslim garantisi arasında denge kurmanızı sağlar. MQTT publish/subscribe modeli makalesi, sistem büyüdükçe üreticileri tüketicilerden ayırmanın neden önemli olduğunu açıklıyor.
MQTT'nin bedeli bir broker'a ihtiyaç duymanızdır ve bir broker'ı güvenilir şekilde işletmek, TLS sertifikalarından bağlantı limitlerine kadar ciddi bir operasyon yüküdür. ConnectMQ bu tarafı sizin yerinize üstlenir. Ekiplerin kendi broker'larını sürdürmek yerine yönetilen bir MQTT broker seçmesinin temel nedeni de budur. Hâlâ temelleri öğreniyorsanız MQTT eğitimi topic'leri, QoS'u ve oturumları adım adım anlatıyor.
Karar Kontrol Listesi
- Sunucunun cihazlara veri veya komut push etmesi gerekiyor mu? Evet ise MQTT'ye yönelin.
- Cihazlar saatte birkaç kereden fazla veri gönderiyor mu? Evet ise MQTT'ye yönelin.
- Aynı veriyi birden fazla servis tüketiyor mu? Evet ise MQTT'ye yönelin.
- Payload büyük mü ya da işlem tek seferlik bir dosya aktarımı mı? Evet ise HTTP kullanın.
- Üçüncü tarafların standart web araçlarıyla entegre olması gerekiyor mu? Sisteminizin sınırında HTTP sunun.
- Çevrimiçi/çevrimdışı durumu önemli mi? MQTT size keep alive ve Last Will'i ücretsiz olarak verir.
MQTT'yi ConnectMQ'da Deneyin
Projeniz için MQTT vs HTTP sorusunu çözmenin en hızlı yolu, kendi cihazınızı gerçek bir broker'a karşı çalıştırmaktır. ConnectMQ size 8883 ve 8084 portlarında TLS ile güvence altına alınmış, otomatik oluşturulan kimlik bilgilerine sahip özel bir broker, tarayıcı içi bir MQTT istemcisi ve canlı bir topic gezgini sunar. app.connectmq.com adresinde kredi kartı gerekmeden ücretsiz Serverless planla başlayın ve sonuçları mevcut HTTP kurulumunuzla karşılaştırın.
Sık Sorulan Sorular
MQTT, HTTP'den daha hızlı mı?
Sık gönderilen küçük mesajlar için genellikle evet, çünkü MQTT tek bir bağlantıyı yeniden kullanır ve çok daha küçük header'lar gönderir. Tek bir büyük aktarımda fark küçüktür ve HTTP araçları çoğu zaman daha iyidir.
MQTT bir REST API'nin yerini alabilir mi?
Polling'e dayalı cihaz endpoint'lerinin yerini alabilir, ancak herkese açık API'ler, CRUD işlemleri ve dosya aktarımları için REST hâlâ daha uygundur. IoT platformlarının çoğu ikisini birlikte kullanır.
MQTT, HTTP'den daha az pil tüketir mi?
Cihazlar sık iletişim kuruyorsa veya komut alması gerekiyorsa, tekrarlanan handshake'ler ve polling olmadığı için genellikle evet. Tek bir ölçüm göndermek için seyrek uyanan cihazlar çok az fayda görebilir.
Tarayıcılar MQTT'yi HTTP gibi kullanabilir mi?
Evet, WebSocket üzerinden MQTT ile. Tarayıcı istemcileri MQTT.js gibi bir kütüphane kullanarak wss://broker.connectmq.com:8084/mqtt gibi bir URL'ye bağlanır.



