Bir e-ticaret sitesinin kampanya gecesi 80.000 kişiye bülten göndermesi gerekiyordu. Sunucu güçlüydü, liste temizdi, içerik hazırdı. Gönderim başladıktan iki saat sonra kuyrukta 60.000 mail birikmişti ve Gmail'e giden her bağlantı 421 4.7.0 Try again later dönüyordu. Sorun sunucunun gücü değildi; kimse mail gönderim hacmi planlaması yapmamış, saatlik limitin ne olması gerektiğini hesaplamamıştı. Mail gönderiminde kapasite, CPU veya RAM ile değil, alıcı tarafın size izin verdiği hızla belirlenir.
Bu yazıda gönderim hacminizi doğru ölçmeyi, ortalama değil zirve yükü baz almayı, sunucu tarafındaki fiziksel sınırları hesaplamayı, alıcı sağlayıcıların uyguladığı throttling'i tahmin etmeyi ve bunları Postfix üzerinde somut ayarlara dönüştürmeyi anlatacağım. Sonunda "günde kaç mail gönderebilirim" sorusuna tahminle değil, elinizdeki verilerle cevap verebileceksiniz.
Hangi Sayıyı Sayıyorsunuz: Hacmi Doğru Tanımlamak#
Kapasite planlamasında yapılan ilk hata, "aylık 500.000 mail" gibi tek bir sayıyla yola çıkmaktır. Bu sayı planlama için neredeyse işe yaramaz, çünkü mail gönderimi düzgün dağılmaz. Gerçekte ölçmeniz gereken dört ayrı büyüklük vardır ve bunları birbirine karıştırmamalısınız.
Birincisi mesaj adedi: kaç ayrı alıcıya gidiyor. İkincisi teslimat girişimi adedi: bir mesaj geçici ret alıp yeniden denenirse aynı mesaj için birden fazla SMTP oturumu açılır, yani sunucunuzun yaptığı iş mesaj adedinden fazladır. Üçüncüsü alıcı sağlayıcı dağılımı: 100.000 mailin 70.000'i Gmail'e gidiyorsa gerçek darboğazınız Gmail'in size açtığı bağlantı sayısıdır, toplam hacim değil. Dördüncüsü mesaj boyutu: 15 KB'lık düz metin bülten ile 900 KB'lık PDF ekli fatura maili, aynı adette bile bambaşka bant genişliği ve disk yükü üretir.
Mevcut durumu ölçmek için Postfix loglarından şu üç veriyi çıkarın:
# 1) Son 24 saatte kaç mesaj teslim edildi
grep "status=sent" /var/log/mail.log | wc -l
# 2) Alıcı alan adına göre dağılım (ilk 10)
grep "status=sent" /var/log/mail.log | grep -oE "to=<[^>]+>" | \
awk -F@ '{print tolower($2)}' | tr -d '>' | sort | uniq -c | sort -rn | head -10
# 3) Saatlik dağılım - zirve saatini bulmak için
grep "status=sent" /var/log/mail.log | awk '{print $3}' | cut -d: -f1 | \
sort | uniq -c | sort -k2
Üçüncü komutun çıktısı planlamanın kalbidir. Genellikle şuna benzer bir tablo görürsünüz:
| Saat | Teslim edilen mesaj | Toplama oranı |
|---|---|---|
| 08 | 1.240 | %3 |
| 09 | 14.800 | %37 |
| 10 | 9.100 | %23 |
| 11 | 3.400 | %8 |
| 12-23 | 11.460 | %29 |
Bu örnekte günlük 40.000 mailin %37'si tek bir saate sıkışmış. Kapasiteyi günlük 40.000'e göre değil, o saatteki 14.800'e göre planlamanız gerekir.
Zirve Yükü Hesaplama: Ortalama Aldatır#
Ortalama üzerinden planlama yapmak kapasite hesabındaki en pahalı yanılgıdır. Günlük 40.000 maili 24'e bölüp "saatte 1.667 mail, kolay" demek, kampanya saatindeki dokuz kat yükü görmezden gelmektir. Doğru yöntem şu formüldür:
Gerekli saatlik kapasite = (Zirve saatteki mesaj adedi) × (1 + yeniden deneme payı) × emniyet katsayısı
Yeniden deneme payı, geçici ret alan ve tekrar denenen mesajların oranıdır; temiz bir listede %5-10, greylisting kullanan alıcıların yoğun olduğu bir listede %20-30'a kadar çıkar. Greylisting'in gecikmeyi nasıl ürettiğini merak ediyorsanız greylisting ve mail gecikmesi yazısı bu davranışı ayrıntılı anlatıyor. Emniyet katsayısını 1,3 ile 1,5 arasında tutun; kapasiteyi tam sınırda planlamak, ilk yavaşlamada kuyruk patlaması demektir.
Yukarıdaki örnekle hesaplayalım: 14.800 × 1,15 × 1,4 ≈ 23.828 mesaj/saat, yani yaklaşık saniyede 6,6 mesaj. Bu, planlamanız gereken gerçek hedeftir. Aynı hesabı kendi verilerinizle yaparken şu adımları izleyin:
- Son 30 günün loglarından en yoğun saati bulun (yukarıdaki üçüncü komut).
- Aynı dönemde
status=deferredsayısınıstatus=sentsayısına bölerek yeniden deneme payını çıkarın. - Büyüme beklentinizi ekleyin: önümüzdeki 12 ayda liste %50 büyüyecekse zirve değeri 1,5 ile çarpın.
- Emniyet katsayısını uygulayın ve sonucu saniyeye bölerek hedef gönderim hızını bulun.
- Bu hızı, bir sonraki bölümdeki fiziksel ve alıcı taraf limitleriyle karşılaştırın.
Sunucu Tarafındaki Fiziksel Limitler#
Sunucunuzun ham gücü genellikle darboğaz değildir ama sınırsız da değildir. Bir SMTP teslimatının maliyeti üç kalemden oluşur: TCP bağlantısı ve TLS el sıkışması, mesajın diske yazılması ve kuyruk yönetimi, ve alıcı sunucunun cevap verme süresi. Bunlardan ilki CPU, ikincisi disk I/O, üçüncüsü ise tamamen sizin kontrolünüz dışındadır ve pratikte en belirleyici olanıdır.
TLS el sıkışması özellikle önemlidir çünkü her yeni bağlantıda asimetrik kripto işlemi yapılır. Modern bir sunucuda bu işlem milisaniyeler sürer, ancak saniyede yüzlerce yeni bağlantı açıyorsanız toplamda anlamlı bir CPU yükü oluşur. Bağlantıları yeniden kullanmak (smtp_connection_cache_on_demand) bu maliyeti ciddi biçimde düşürür.
Disk tarafında kritik olan, kuyruk dizininin (/var/spool/postfix) bulunduğu diskin IOPS kapasitesidir; boyut değil. Her mesaj kuyruğa yazılır, teslim edilince silinir, geçici ret alırsa deferred dizinine taşınır. 100.000 mesajlık bir kuyruk yüz binlerce küçük dosya işlemi demektir ve dönen disk üzerinde bu iş kilitlenir. Kuyruk mutlaka SSD veya NVMe üzerinde olmalıdır.
| Bileşen | Tipik darboğaz eşiği | Belirti |
|---|---|---|
| CPU (TLS el sıkışması) | Saniyede yüzlerce yeni bağlantı | Yüksek sys CPU, yavaş bağlantı kurulumu |
| Disk IOPS (kuyruk) | On binlerce bekleyen mesaj | qmgr yavaşlar, kuyruk erimez |
| Bellek | Yüksek eşzamanlı süreç sayısı | OOM killer, süreç düşmesi |
| Bant genişliği | Büyük ekli mesajlar | Uzun teslim süresi, timeout |
| Dosya tanıtıcı limiti | Eşzamanlı bağlantı sayısı | Too many open files |
Eşzamanlı süreç sayısını ayarlarken master.cf içindeki smtp servisinin maxproc değeri ve default_process_limit birlikte çalışır. Sunucunuzun bunları kaldırıp kaldıramayacağını görmek için gönderim sırasında top, iostat -x 2 ve postqueue -p | tail -1 çıktılarını aynı anda izleyin. Kaynak yetersizse VDS veya hazır yapılandırılmış SMTP sunucu paketlerine geçmek, ayarlarla uğraşmaktan daha hızlı sonuç verir.
Alıcı Tarafındaki Limitler ve Throttling#
Asıl sınır burada. Büyük posta sağlayıcıları her gönderici IP'si için eşzamanlı bağlantı sayısını, saatlik mesaj adedini ve bağlantı başına mesaj sayısını sınırlar. Bu limitler yayınlanmış sabit sayılar değildir; IP'nizin itibarına, gönderim geçmişinize ve o anki yüke göre dinamik olarak değişir.
Limite takıldığınızı log'daki geçici hata kodlarından anlarsınız. En sık karşılaşacaklarınız:
| Kod | Anlamı | Doğru tepki |
|---|---|---|
| 421 4.7.0 | Bağlantı hız sınırı, sonra dene | Eşzamanlılığı azalt, bekle |
| 450 4.2.1 | Alıcı geçici olarak kabul etmiyor | Yeniden deneme aralığını uzat |
| 451 4.3.0 | Sunucu tarafı geçici hata | Kuyrukta bırak, normal retry |
| 452 4.5.3 | Çok fazla alıcı | Alıcı sayısını böl |
| 550 5.1.1 | Alıcı yok (kalıcı) | Listeden çıkar, tekrar deneme |
| 554 5.7.1 | İçerik/itibar reddi | Gönderimi durdur, sebebi araştır |
4xx kodları geçicidir ve doğru tepki beklemektir; 5xx kalıcıdır ve doğru tepki listeyi temizlemektir. En yaygın hata, 4xx alınca yeniden deneme sıklığını artırmaktır — bu, limiti aşan davranışı pekiştirir ve IP'nizin daha sert kısıtlanmasına yol açar. Gmail tarafında hangi eşiklerin geçerli olduğunu ve şikâyet oranı beklentisini Gmail ve Yahoo yeni gönderici kuralları yazısında bulabilirsiniz; teslim sorunları sürüyorsa Gmail'e mail gitmiyor yazısındaki teşhis akışını izleyin.
Postfix'te Hız Limiti ve Kuyruk Ayarları#
Hesapladığınız hedef hızı Postfix'e uygulamanın yolu, alıcı alan adı bazında ayrı teslim politikaları tanımlamaktır. Önce main.cf içinde genel çerçeveyi kurun:
# main.cf - genel teslim davranışı
# Bir hedefe aynı anda kaç paralel teslim yapılsın (varsayılan 20 çoğu zaman fazladır)
default_destination_concurrency_limit = 10
# Bir bağlantıda arka arkaya kaç mesaj gönderilsin
default_destination_recipient_limit = 50
# Aynı hedefe iki teslim arasında minimum bekleme (0 = sınır yok)
default_destination_rate_delay = 0s
# Bağlantı önbelleği: TLS el sıkışma maliyetini ciddi düşürür
smtp_connection_cache_on_demand = yes
smtp_connection_cache_time_limit = 30s
# Geçici ret alan mesajlar kuyrukta ne kadar kalsın
maximal_queue_lifetime = 3d
bounce_queue_lifetime = 3d
# Yeniden deneme aralığı
minimal_backoff_time = 300s
maximal_backoff_time = 4000s
queue_run_delay = 300s
Ardından belirli alan adları için ayrı bir teslim kanalı (transport) açıp o kanala kendi limitini verirsiniz. Bu, "Gmail'e daha yavaş, kendi müşteri sunucularımıza daha hızlı gönder" demenin standart yoludur:
# master.cf - gmail'e özel, yavaş ve tek paralel teslim kanalı
gmailout unix - - n - 4 smtp
-o syslog_name=postfix-gmailout
-o smtp_destination_concurrency_limit=4
-o smtp_destination_rate_delay=1s
# transport haritası: hangi alan adı hangi kanaldan çıksın
echo "gmail.com gmailout:" >> /etc/postfix/transport
echo "googlemail.com gmailout:" >> /etc/postfix/transport
postmap /etc/postfix/transport
# main.cf'e haritayı tanıt ve yeniden yükle
postconf -e "transport_maps = hash:/etc/postfix/transport"
postfix reload
# Kuyruk durumunu izle
postqueue -p | tail -1
mailq | grep -c "^[A-F0-9]"
smtp_destination_rate_delay = 1s ayarı, o kanaldan saniyede en fazla bir teslim yapılmasını sağlar; concurrency_limit ile birlikte gerçek üst sınırı belirler. Bu iki değeri, hesapladığınız hedef hızı aşmayacak ama alıcıyı da kızdırmayacak şekilde ayarlayın ve her değişiklikten sonra 4xx oranını ölçün. Rakamları körlemesine yükseltmek yerine, bir hafta boyunca kademeli artırıp geçici ret oranının binde birkaç seviyesinde kalmasını hedefleyin.
Bant Genişliği, Disk ve Kuyruk Derinliği Planlaması#
Hacim planlaması yalnızca hız değil, aynı zamanda depolama ve trafik meselesidir. Kaba hesap şöyle işler: ortalama mesaj boyutunu (ek dosyalar dahil) mesaj adediyle çarparsınız, sonra protokol ek yükü ve yeniden denemeler için %20 ekleyin. Ortalama 60 KB'lık bir mesajla saatte 24.000 teslim yapıyorsanız kabaca 1,4 GB/saat çıkış trafiği demektir; yani sürekli yaklaşık 3-4 Mbit/sn. Kendi senaryonuz için bant genişliği hesaplayıcı ile hızlıca çevrim yapabilirsiniz.
Kuyruk için ayıracağınız disk alanını hesaplarken en kötü senaryoyu baz alın: en büyük alıcı sağlayıcı tamamen erişilemez hale gelirse, o sağlayıcıya giden mesajların tamamı maximal_queue_lifetime boyunca diskte durur. Yukarıdaki örnekte Gmail'e günde 28.000 mesaj gidiyorsa ve kuyruk ömrü 3 gün ise, en kötü durumda 84.000 × 60 KB ≈ 5 GB yalnızca kuyruk için gerekir. Buna gelen posta deposunu ve log'ları eklemeyi unutmayın.
Son olarak kuyruk derinliği için bir alarm eşiği belirleyin. Bekleyen mesaj sayısı normalde saatlik kapasitenizin onda birinin altında olmalıdır; bunu aşarsa ya alıcı taraf sizi kısıtlıyordur ya da gönderim hızınız kapasitenizi aşmıştır. Basit bir kontrol betiği yeterlidir:
#!/bin/bash
# /usr/local/bin/queue-check.sh - kuyruk derinliği alarmı
ESIK=2000
ADET=$(postqueue -p | tail -1 | awk '{print $5}')
ADET=${ADET:-0}
if [ "$ADET" -gt "$ESIK" ]; then
echo "UYARI: Postfix kuyrugunda $ADET mesaj bekliyor (esik: $ESIK)"
# En cok hangi hedefe takildigini goster
postqueue -p | grep -oE "@[a-zA-Z0-9.-]+" | sort | uniq -c | sort -rn | head -5
fi
Sık Yapılan Hatalar ve Kapasite Tuzakları#
En yaygın hata, paralelliği artırarak hız kazanmaya çalışmaktır. Alıcı sizi zaten kısıtlıyorsa eşzamanlı bağlantıyı 10'dan 40'a çıkarmak teslim hızını artırmaz; sadece daha fazla 421 cevabı toplarsınız ve IP itibarınız düşer. Doğru hamle paralelliği azaltıp gönderimi zamana yaymaktır.
İkinci tuzak, tüm listeyi tek seferde kuyruğa basmaktır. 80.000 mesajı bir anda kuyruğa yazmak qmgr'yi zorlar, disk I/O'yu tavana vurdurur ve kuyruk taramaları yavaşlar. Gönderimi uygulama tarafında partilere bölün: 5.000'lik gruplar halinde, aralarında birkaç dakika bırakarak besleyin.
Üçüncüsü bounce'ları kapasiteden saymamaktır. Geri dönen her mesaj yeni bir mesaj üretir ve bu da kuyruktan geçer. %5 bounce oranı, kapasitenizin %5'inin geri dönüşlere gitmesi demektir. Kirli bir listede bu oran çok daha yüksektir; liste hijyeni doğrudan bir kapasite meselesidir.
Dördüncü hata, pazarlama ve işlemsel maili aynı kuyruktan geçirmektir. Bülten kuyruğu şiştiğinde şifre sıfırlama maili de arkada bekler ve müşteri sisteme giremez. Bu ikisi ayrı transport kanallarından, hatta mümkünse ayrı sunuculardan çıkmalıdır. Paylaşımlı ve ayrılmış IP tercihinin bu ayrımla nasıl birleştiğini paylaşımlı mı ayrılmış IP mi yazısında bulabilirsiniz.
Sıkça Sorulan Sorular#
Günde kaç mail gönderebilirim#
Bu sorunun tek bir cevabı yoktur çünkü sınır sizin sunucunuz değil, alıcı sağlayıcıların IP itibarınıza tanıdığı haktır. Yeni ısıtılan bir IP'de günlük birkaç yüz mailden başlarsınız; oturmuş itibarı olan bir IP'de yüz binler mümkündür. Doğru yaklaşım sabit bir sayı aramak yerine geçici ret (4xx) oranınızı izlemek ve o oran yükselmeye başladığında hızı sabitlemektir.
Saatlik gönderim limitimi nasıl hesaplarım#
Son 30 günün loglarından en yoğun saatteki teslim adedini bulun, buna yeniden deneme payını (deferred/sent oranı) ekleyin ve 1,3-1,5 arası bir emniyet katsayısıyla çarpın. Çıkan sayı planlamanız gereken saatlik kapasitedir. Bunu 3600'e bölerek saniyedeki hedef teslim hızına çevirir, Postfix'in concurrency ve rate delay ayarlarını buna göre kurarsınız.
Kuyrukta biriken mailleri nasıl temizlerim#
Önce sebebi bulun: postqueue -p çıktısındaki hata mesajları hangi alan adına takıldığınızı gösterir. Geçici bir sorunsa postqueue -f ile kuyruğu yeniden işletmek yeterlidir. Kalıcı olarak teslim edilemeyecek mesajlar varsa postsuper -d ile silebilirsiniz, ancak silmeden önce hangi mesajları kaybettiğinizi bilin. Kuyruğu körlemesine boşaltmak, müşterilerinizin bekleyen faturalarını da silmek anlamına gelebilir.
421 hatası alıyorum, gönderim hızını artırmalı mıyım#
Hayır, tam tersini yapmalısınız. 421 4.7.0 alıcı sunucunun "çok hızlı geliyorsun, yavaşla" demesidir. Hızı artırmak veya yeniden deneme sıklığını yükseltmek durumu kötüleştirir ve daha sert kısıtlamaya yol açar. Eşzamanlı bağlantı sayısını düşürün, teslimler arasına gecikme koyun ve mesajların kuyrukta normal aralıklarla yeniden denenmesini bekleyin.
Mail kuyruğu için ne kadar disk alanı ayırmalıyım#
En büyük alıcı sağlayıcınızın tamamen erişilemez olduğu senaryoyu hesaplayın: o sağlayıcıya giden günlük mesaj adedini kuyruk ömrü (gün) ile ve ortalama mesaj boyutuyla çarpın. Çıkan değerin en az iki katını ayırmak güvenlidir. Kuyruk diskinin SSD veya NVMe olması, boyutundan daha önemlidir; kuyruk işi boyut değil IOPS işidir.
Gönderimi kaç parçaya bölmeliyim#
Pratik bir kural olarak, tek seferde kuyruğa basacağınız mesaj sayısı saatlik kapasitenizin dörtte birini geçmesin. Saatte 24.000 kapasiteniz varsa 5.000-6.000'lik partiler halinde, aralarında birkaç dakika bırakarak besleyin. Bu, kuyruğun sürekli erimesini sağlar, disk I/O'yu düzler ve bir sorun çıktığında yalnızca o partiyi durdurup düzeltmenize imkân verir.
Sunucumu büyütmek gönderim hızımı artırır mı#
Genellikle hayır. Darboğaz neredeyse her zaman alıcı taraftaki kısıtlamalardır, sizin CPU veya RAM'iniz değil. Daha güçlü donanım yalnızca kuyruk yönetimi disk I/O'sunda veya çok yüksek eşzamanlı TLS el sıkışmasında sıkıştıysanız fark yaratır. Önce iostat ve top ile gerçekten kaynak sınırında olduğunuzu doğrulayın; değilse yatırımı IP itibarına ve liste hijyenine yapın.
Kapanış#
Mail kapasitesi planlaması, donanım hesabından çok bir davranış hesabıdır. Aklınızda kalması gereken dört şey: ortalama değil zirve saati baz alın; hedef hızı geçici ret oranına bakarak kademeli ayarlayın; kuyruğu SSD üzerinde tutup derinliğine alarm kurun; ve pazarlama ile işlemsel maili asla aynı kuyruktan geçirmeyin. Bu dördü oturduğunda kampanya geceleri sürpriz olmaktan çıkar.
Kendi MTA'nızı kurup bu ayarları yönetmek isterseniz Postfix, Dovecot ve DKIM'i hazır gelen SMTP sunucu paketleri hızlı bir başlangıç sağlar; daha fazla kaynak ve tam root erişimi için VDS sunucularına bakabilirsiniz. Kuyruk ve limit ayarlarıyla uğraşmak istemiyorsanız sunucu yönetimi hizmetimiz bu işi üstlenir, kampanya tarafını segmentleyerek yönetmek içinse e-posta pazarlama çözümlerimize göz atabilirsiniz.