Her baytın nereden geldiğini bildiğinizde MQTT bant genişliği kullanımını tahmin etmek kolaydır: MQTT paketinin kendisi, onu taşıyan TCP/IP başlıkları, etrafındaki TLS şifrelemesi ve connect ile keep alive işlemlerinin arka plan trafiği. Bu rehber, gerçekçi bir telemetri mesajı için her katmanı QoS 0, 1 ve 2'de hesaplıyor, ardından bu sayıları cihazlarınız için hücresel bir plan seçerken kullanabileceğiniz aylık bir veri tahminine dönüştürüyor.
MQTT Neden Hafiftir ve Baytlar Yine de Nereye Gider?
MQTT'nin sabit başlığı iki bayt kadar küçüktür, HTTP'deki gibi metin başlıkları yoktur ve tek bir uzun ömürlü bağlantı, her istek için yapılan el sıkışmanın yerini alır. Bu da mesaj başına protokol ek yükünü çok küçük kılar. Ancak ölçülen (metered) bir bağlantıda MQTT baytları için değil IP baytları için ödeme yaparsınız ve küçük payload'larda alt katmanlar baskın gelir. Faydalı bir zihinsel modelin dört katmanı vardır:
| Katman | Mesaj başına maliyet | Notlar |
|---|---|---|
| Payload | Verileriniz | Telemetri için genellikle 20 ila 200 bayt JSON |
| MQTT | 2 ila 6 bayt + topic adı | Topic uzunluğu çoğu zaman en büyük MQTT maliyetidir |
| TLS | Kayıt başına yaklaşık 22 ila 29 bayt | TLS sürümüne ve şifreleme takımına bağlıdır |
| TCP/IP | Segment başına 40 bayt (IPv4, seçeneksiz) | TCP zaman damgalarıyla çoğu zaman 52; IPv6 ile 60 |
Bunlara ek olarak mesaj başına olmayan iki arka plan maliyeti vardır: bağlantı kurulumu (TCP, TLS el sıkışması, CONNECT) ve boşta kalırken gönderilen keep alive ping'leri. Her ikisi de aşağıda ele alınıyor. MQTT katmanının bayt düzeyindeki yapısı için MQTT paket yapısı rehberine bakın.
QoS'a Göre Mesaj Başına MQTT Ek Yükü
Tipik bir örnek alalım: MQTT 3.1.1, plant1/line2/pump3/telemetry topic'i (28 karakter) ve {"t":1760601600,"flow":12.4,"p":3.1,"temp":41.7} gibi 48 baytlık bir JSON payload'ı.
QoS 0'da PUBLISH paketi şöyledir:
- Sabit başlık: 2 bayt (tür ve bayraklar, bir bayt remaining length)
- Topic: 2 baytlık uzunluk öneki + 28 bayt = 30 bayt
- Payload: 48 bayt
- Toplam: 80 bayt
QoS 1 ve 2'de PUBLISH'e 2 baytlık bir paket kimliği eklenir ve her biri 4 bayt olan onay paketleri devreye girer:
| QoS | Hattaki paketler | MQTT baytı | Payload'a göre ek yük |
|---|---|---|---|
| 0 | PUBLISH (80) | 80 | 32 bayt |
| 1 | PUBLISH (82) + PUBACK (4) | 86 | 38 bayt |
| 2 | PUBLISH (82) + PUBREC + PUBREL + PUBCOMP (her biri 4) | 94 | 46 bayt |
MQTT 5'te PUBLISH'teki boş özellik uzunluğu için bir bayt ekleyin; özellik içermeyen başarılı onaylar 4 baytta kalır. Dolayısıyla MQTT katmanında QoS seçimi maliyeti yalnızca biraz değiştirir. Asıl fark taşıma katmanında ortaya çıkar, çünkü her ek paket genellikle ek bir TCP segmenti anlamına gelir. MQTT QoS seviyeleri rehberi, ek teslimat garantilerinin ne zaman buna değdiğini açıklıyor.
Topic Adı Çoğu Zaman En Büyük MQTT Maliyetidir
Yukarıdaki örnekte QoS 0 ek yükünün 32 baytının 30'u topic'tir. Derin ISA-95 tarzı topic'ler kolayca 50 karakteri aşabilir. İki çözüm vardır: cihaz tarafındaki topic'leri kısa tutun ya da ilk publish'ten sonra topic'i 2 baytlık bir sayıyla değiştiren MQTT 5 topic alias'larını kullanın. MQTT topic alias rehberi tasarrufu ayrıntılı olarak gösteriyor.
TCP/IP ve TLS'i Eklemek
Tek başına gönderilen her MQTT paketi, en az 40 baytlık IPv4 ve TCP başlıklarına sahip bir TCP segmentinde taşınır. Alıcı, verileri TCP ACK'leriyle onaylar; bunlar da ters yönde akan verilere eklenemedikleri sürece 40 baytlık segmentlerdir. Gecikmeli ACK davranışı işletim sistemine ve ağ yığınına göre değişir, bu yüzden ACK maliyetlerini yaklaşık değerler olarak kabul edin.
TLS, her yazma işlemini bir kayıt (record) içine sarar. TLS 1.3 ve AES-GCM şifrelemesiyle her kayıt 5 baytlık başlık, 1 baytlık iç içerik türü ve 16 baytlık kimlik doğrulama etiketi ekler: toplam 22 bayt. AES-GCM ile TLS 1.2 ise 8 baytlık açık nonce nedeniyle 29 bayt ekler.
Hepsini bir telemetri mesajı için bir araya getirdiğimizde (TCP seçenekleri olmadan IPv4, TLS 1.3, veri segmenti başına bir saf TCP ACK sayarak):
| QoS | Düz TCP (port 1883) | TLS 1.3 (port 8883) |
|---|---|---|
| 0 | 80 + 40 + 40 ACK = 160 bayt | 102 + 40 + 40 ACK = 182 bayt |
| 1 | 122 + 44 + 40 ACK = 206 bayt | 144 + 66 + 40 ACK = 250 bayt |
| 2 | 122 + 3 x 44 + 2 ACK, yaklaşık 335 bayt | 144 + 3 x 66 + 2 ACK, yaklaşık 420 bayt |
48 baytlık bir payload için hattaki maliyet, verinin kabaca dört ila sekiz katıdır. Payload'lar büyüdükçe bu oran küçülür: 1 KB'lık bir payload neredeyse aynı mutlak ek yüke sahiptir ve bu ek yük küçük bir orana dönüşür. Bu nedenle ölçümleri gruplamak, örneğin on mesaj yerine on örnek içeren tek bir mesaj göndermek, en etkili bant genişliği optimizasyonudur.
Gerçek kurulumlarda TLS isteğe bağlı değildir ve tablonun gösterdiği gibi mesaj başına maliyeti makuldür. Daha büyük maliyeti el sıkışmasıdır.
Bağlantı Kurulum Maliyetleri
Her yeni bağlantı şunlar için ödeme yapar:
- TCP el sıkışması: üç segment, kabaca 120 ila 180 bayt.
- TLS el sıkışması: genellikle birkaç kilobayt, çoğunlukla sunucunun sertifika zinciri. Kütüphanenizin desteklediği durumlarda TLS 1.3 oturum sürdürme (session resumption) bunu önemli ölçüde azaltır.
- CONNECT ve CONNACK: 20 karakterlik client ID, kullanıcı adı ve parola içeren bir CONNECT yaklaşık 80 bayttır; CONNACK ise MQTT 3.1.1'de 4 bayttır.
- Kalıcı oturum kullanılmıyorsa her abonelik için SUBSCRIBE ve SUBACK.
Yani tek bir yeniden bağlanma, onlarca telemetri mesajı kadar maliyetli olabilir. Her dakika bağlanan, bir kez publish eden ve bağlantıyı kesen cihazlar verilerinin çoğunu el sıkışmalarına harcar. Cihaz uzun süreler boyunca uykuya geçmiyorsa bağlantıyı açık tutun ve her yeniden bağlanmadan sonra tekrar abone olmak zorunda kalmamak için kalıcı oturum kullanın. Kalıcı oturum rehberi bunun nasıl yapılacağını açıklıyor.
Keep Alive Maliyetleri
Bir istemcinin keep alive aralığı boyunca gönderecek bir şeyi olmadığında PINGREQ (2 bayt) gönderir ve broker PINGRESP (2 bayt) ile yanıt verir. TLS 1.3 ve TCP/IP ile bir ping değişimi yaklaşık 64 + 64 bayt artı bir ACK'tir: kabaca 170 bayt.
| Keep alive | Boştayken günlük ping sayısı | Yaklaşık günlük veri |
|---|---|---|
| 30 sn | 2.880 | yaklaşık 485 KB |
| 60 sn | 1.440 | yaklaşık 240 KB |
| 300 sn | 288 | yaklaşık 48 KB |
| 900 sn | 96 | yaklaşık 16 KB |
Ping'ler yalnızca bağlantı başka bir şekilde boştayken gönderilir; bu nedenle 60 saniyelik keep alive ile her 30 saniyede bir publish yapan bir cihaz hiç ping göndermez. Daha uzun aralıklar veri tasarrufu sağlar, ancak hücresel ağlarda boştaki bağlantıları düşüren ve maliyetli bir yeniden bağlanmaya zorlayan NAT zaman aşımları riskini taşır. Bu değeri MQTT keep alive aralığı yazısındaki önerilerle ayarlayın.
Hücresel Bir Cihaz için Aylık Veri Tahmini
Bu Python hesaplayıcısı tüm parçaları bir araya getirir. Girdileri cihazınıza göre ayarlayın:
def mqtt_monthly_bytes(
payload=48, topic_len=28, qos=1, msgs_per_day=1440,
tls=True, reconnects_per_day=2, handshake_bytes=5000,
keepalive_s=120, idle_seconds_per_day=0,
):
ip_tcp = 40
tls_rec = 22 if tls else 0
publish = 2 + 2 + topic_len + payload + (2 if qos else 0)
def seg(mqtt_bytes):
return mqtt_bytes + tls_rec + ip_tcp
if qos == 0:
per_msg = seg(publish) + ip_tcp
elif qos == 1:
per_msg = seg(publish) + seg(4) + ip_tcp
else:
per_msg = seg(publish) + 3 * seg(4) + 2 * ip_tcp
pings = idle_seconds_per_day / keepalive_s if keepalive_s else 0
ping_bytes = pings * (2 * seg(2) + ip_tcp)
connect_bytes = reconnects_per_day * (handshake_bytes if tls else 300)
per_day = msgs_per_day * per_msg + ping_bytes + connect_bytes
return per_day * 30
for qos in (0, 1, 2):
mb = mqtt_monthly_bytes(qos=qos) / 1_000_000
print(f"QoS {qos}: {mb:.1f} MB per month")
TLS üzerinden QoS 1 ile dakikada bir mesajda sonuç, cihaz başına ayda yaklaşık 11 MB'tır ve bunun yalnızca küçük bir kısmı varsayılan iki yeniden bağlanmadan gelir. msgs_per_day değerini 144'e (on dakikada bir) değiştirip 300 saniyelik keep alive ve boşta geçen süreyi eklediğinizde toplam keskin biçimde düşer. Bunlar ölçüm değil, hesaplanmış tahminlerdir; bir test SIM kartında gerçek kullanımı kontrol ederek veya bir gün boyunca tcpdump ile trafiği yakalayıp baytları toplayarak doğrulayın.
Bant Genişliğini Azaltma Kontrol Listesi
- Gecikmenin izin verdiği yerlerde örnekleri daha az sayıda, daha büyük mesajlarda gruplayın.
- Kompakt payload'lar kullanın: kısa JSON anahtarları, CBOR veya Protobuf. Bkz. MQTT payload formatı.
- MQTT 5 ile cihaz topic'lerini kısaltın veya topic alias kullanın.
- QoS'u topic bazında seçin: ara sıra kaybın kabul edilebildiği sık telemetri için QoS 0, olaylar ve komutlar için QoS 1.
- Her mesaj için yeniden bağlanmak yerine bağlantıları açık tutun ve kalıcı oturumlar kullanın.
- Keep alive'ı, ağınızın NAT zaman aşımının izin verdiği en uzun değere ayarlayın.
- Değerler sabitken sabit bir hızda değil, değişiklik olduğunda publish edin.
- Gereksiz aboneliklerden kaçının: bir cihazdaki wildcard aboneliği eşleşen her mesajı alır ve bu da downlink verisine mal olur.
Verimli Cihazları ConnectMQ'da Çalıştırın
ConnectMQ, topic alias'lar ve session expiry dahil MQTT 3.1.1 ve 5.0'ı, Let's Encrypt sertifikasıyla 8883 numaralı port üzerinden TLS ile destekler; böylece yukarıdaki optimizasyonlar özel bir yapılandırma gerektirmeden çalışır. Ücretsiz herkese açık MQTT broker üzerinde prototip oluşturun, ardından gerçek trafiği özel bir broker'a karşı ölçün. Protokolde yeniyseniz MQTT eğitimi temelleri ele alıyor.
ConnectMQ ile Başlayın
Yönetilen bir MQTT broker, sunucu operasyonları yerine cihaz verimliliğine odaklanmanızı sağlar. app.connectmq.com adresinde kredi kartı gerektirmeden ücretsiz bir Serverless broker oluşturun ve cihazlarınızın tam olarak ne gönderdiğini görmek için canlı topic gezginini kullanın. Daha kapsamlı bir karşılaştırma için bulut MQTT broker seçme rehberimizi okuyun.
Sık Sorulan Sorular
MQTT mesaj başına ne kadar ek yük ekler?
MQTT katmanında bir PUBLISH, onaylardan önce QoS 0'da 4 bayt artı topic adı, QoS 1 ve 2'de ise 6 bayt artı topic ekler. TCP/IP ve TLS bunun üzerine paket başına kabaca 60 bayt veya daha fazlasını ekler.
TLS, MQTT'yi çok daha maliyetli hale getirir mi?
Mesaj başına TLS 1.3, kayıt başına yaklaşık 22 bayt ekler ve bu makul bir miktardır. Daha büyük maliyet, her yeni bağlantıda birkaç kilobaytlık el sıkışmasıdır; bu nedenle sık sık yeniden bağlanmak yerine bağlantıları açık tutun.
MQTT keep alive ne kadar veri kullanır?
Bir ping değişimi MQTT katmanında birkaç bayta mal olur, ancak TCP, IP ve TLS ile yaklaşık 170 bayta ulaşır. Boştaki bir bağlantıda 60 saniyelik aralıkla bu, günde kabaca 240 KB eder.
QoS 0 her zaman en ucuz seçenek midir?
Bayt açısından evet, çünkü hiç onay paketi göndermez. Ancak kaybolan mesajlar uygulamanızı verileri yeniden göndermeye veya yoklama (polling) yapmaya zorluyorsa, QoS 1 genel olarak daha ucuza gelebilir.



