結論(おすすめ1つ)
Postmark に乗り換えよ。
Mailchimp Transactional(旧 Mandrill)からの移行先として最初に検討すべきは Postmark だ。理由は三つある。SMTP と HTTP API の両方を提供しているため既存コードの改修量が最小で済む。配信ログ・バウンス・開封のトレースがダッシュボードからリアルタイムに確認できる。そしてトランザクションメール専用のインフラとして設計されているため、マーケティングメールの混在によるレピュテーション汚染が構造的に起きない。SendGrid や Mailgun が「全部入り」ゆえに設定が煩雑になりがちなのと対照的に、Postmark は届けることだけに特化している。
比較表(料金/無料枠/移行コスト/対応言語)
| サービス | 無料枠 | 月額料金 | 移行コスト | 主要 SDK 言語 |
|---|---|---|---|---|
| Postmark | 初回トライアル分のみ | 公式の料金ページで要確認 | 低(SMTP 互換) | Ruby, Python, PHP, Node, Go, .NET |
| SendGrid | あり(月次上限は要確認) | 公式の料金ページで要確認 | 中(API 差異・設定項目が多い) | Python, Node, PHP, Java, C#, Go, Ruby |
| Resend | あり(月次上限は要確認) | 公式の料金ページで要確認 | 低(REST 設計がシンプル) | Node, Python, PHP, Ruby, Go, Java, Elixir |
| Amazon SES | AWS Free Tier 範囲内で要確認 | 公式の料金ページで要確認 | 高(IAM/SES サンドボックス解除が必要) | AWS SDK 全言語 |
| Mailgun | あり(トライアル期間は要確認) | 公式の料金ページで要確認 | 中(独自テンプレート構文への対応) | Python, Node, Ruby, PHP, Java, C# |
移行コストの「低・中・高」は工数感の目安であり、既存コードの構成によって変わる。
移行手順
Mandrill から Postmark への切り替えを例に取る。SMTP 接続情報だけ差し替えれば動くケースが多く、最小工数での移行を狙えるのが Postmark を推す実運用上の理由でもある。
Step 1: Sender Signature の設定(DNS 作業)
# Postmark ダッシュボード → Sender Signatures → Add Signature
# 表示された SPF/DKIM の TXT レコードを DNS に追加
# 例(DKIM):
# 名前: pm._domainkey.yourdomain.com
# 値: v=DKIM1; k=rsa; p=<公開鍵>
# 反映後にダッシュボードの「Verify」ボタンを押して確認
Step 2: SMTP 経由で即日切り替え(最小変更)
import smtplib
from email.mime.text import MIMEText
SERVER_TOKEN = "your-postmark-server-token" # Mandrill の API キーをここに差し替えるだけ
msg = MIMEText("本文テキスト", "plain", "utf-8")
msg["Subject"] = "件名"
msg["From"] = "noreply@yourdomain.com"
msg["To"] = "user@example.com"
with smtplib.SMTP("smtp.postmarkapp.com", 587) as s:
s.starttls()
s.login(SERVER_TOKEN, SERVER_TOKEN) # user/pass ともにトークンを使う
s.send_message(msg)
Step 3: HTTP API へ移行(推奨・長期運用向け)
pip install postmarker
from postmarker.core import PostmarkClient
client = PostmarkClient(server_token="your-postmark-server-token")
client.emails.send(
From="noreply@yourdomain.com",
To="user@example.com",
Subject="件名",
TextBody="本文テキスト",
HtmlBody="<p>本文</p>",
MessageStream="outbound",
Tag="password-reset", # ダッシュボードでタグ別に集計可能
TrackOpens=True,
)
Step 4: Webhook でバウンスを受信し DB に反映
# FastAPI の例
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/webhooks/postmark")
async def handle_event(request: Request):
payload = await request.json()
record_type = payload.get("RecordType")
if record_type == "Bounce":
bounced_email = payload["Email"]
bounce_type = payload["Type"] # "HardBounce" / "SoftBounce" 等
# DB に登録して以降の送信を抑制する処理をここに書く
suppress_email(bounced_email, bounce_type)
return {"status": "ok"}
Postmark ダッシュボードの Webhooks 設定でエンドポイント URL を登録すれば、バウンス・開封・スパム報告をリアルタイムに受け取れる。
向き不向き
Postmark が向くチーム・規模
- SaaS のパスワードリセット・会員登録確認など到達率が UX に直結するサービス
- インフラ専任がいない小〜中規模チームで、設定・運用コストを最小化したい場合
- 配信ログをエンジニアがダッシュボードで即確認したい開発スタイルのチーム
SendGrid が向くケース
- すでに Twilio との連携があり、コミュニケーション系 API を一本化したいチーム
- 大量送信でレート制御や IP ウォームアップを細かく制御したい場合
Resend が向くケース
- React Email などモダンなコンポーネントベースのテンプレートを使いたいフロントエンド寄りのチーム
- Next.js / Vercel スタックで新規サービスを立ち上げる場合
Amazon SES が向くケース
- AWS インフラに完全統合されており、インフラエンジニアが常駐しているチーム
- 送信量が非常に大きく、単価を極限まで下げたい場合
避けるべきケース
- SES を小規模チームが選ぶケース:IAM ポリシー設計・サンドボックス解除・バウンス率管理を自前でやる工数が予算と合わないことが多い
- Postmark を超大量送信で使うケース:送信量が増えるほどコストが積み上がる。事前に公式の料金ページで試算を
- Mailgun をドキュメント精度が重要な局面で使うケース:API 仕様変更やドキュメント更新のタイムラグが発生することがあるため、新機能追従が重要なプロジェクトでは事前に評価を行うこと
Top comments (0)