Email Services Compared — SendGrid, AWS SES, Mailgun, Postmark, Resend
| Service | Free tier | Paid from | Best for | India notes |
|---|---|---|---|---|
| SendGrid (Twilio) | 100 emails/day | $19.95/mo (50K) | General-purpose | Good Indian card support |
| AWS SES | 200 emails/day (in EC2) | $0.10 per 1K | Cost-sensitive, AWS ecosystem | Lower per-email cost |
| Mailgun | 100 emails/day (3 mo) | $15/mo (10K) | Developers, complex routing | Mid-tier |
| Postmark | 100 emails/month | $15/mo (10K) | Transactional purist (no marketing) | Premium deliverability |
| Resend | 3K/mo, 100/day | $20/mo (50K) | Modern DX, React email templates | Newest, great API |
| Service | Gmail inbox % | Outlook inbox % | India local ISPs % |
|---|---|---|---|
| Postmark | 99% | 95% | 93% |
| Resend | 97% | 93% | 91% |
| SendGrid | 96% | 92% | 90% |
| Mailgun | 95% | 91% | 88% |
| AWS SES | 93% | 88% | 85% (improves with dedicated IP) |
Thanks for signing up
', }); ``` ### Example — SendGrid ```bash npm install @sendgrid/mail ``` ```typescript import sgMail from '@sendgrid/mail'; sgMail.setApiKey(process.env.SENDGRID_API_KEY); await sgMail.send({ from: '[email protected]', to: '[email protected]', subject: 'Welcome!', html: 'Thanks for signing up
', }); ``` ### Example — AWS SES ```bash npm install @aws-sdk/client-sesv2 ``` ```typescript import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2'; const ses = new SESv2Client({ region: 'ap-south-1' }); await ses.send(new SendEmailCommand({ FromEmailAddress: '[email protected]', Destination: { ToAddresses: ['[email protected]'] }, Content: { Simple: { Subject: { Data: 'Welcome!' }, Body: { Html: { Data: 'Thanks!
' } }, }, }, })); ``` ## Template management Three approaches: **1. In-code templates** (Resend + react-email): ```tsx import { Html, Head, Body, Heading } from '@react-email/components'; export function WelcomeEmail({ name }) { return ( Welcome {name}! ); } await resend.emails.send({ from: '[email protected]', to: '[email protected]', subject: 'Welcome!', react: , }); ``` Component-driven, previewable, testable. **2. Provider-hosted templates** (SendGrid, Mailgun): Create template in dashboard; reference by ID: ```typescript await sgMail.send({ templateId: 'd-abc123...', dynamicTemplateData: { name: 'Rajesh', orderId: 'ORD-1234' }, }); ``` Marketing team can edit without deploys. **3. MJML + Nunjucks** (self-hosted): MJML compiles to responsive HTML. Template in git, render at send time. See `mjml.io`. ## Webhooks — track what happens Every service sends webhooks for: - `delivered` — receiver accepted - `opened` — user opened (requires tracking pixel) - `clicked` — user clicked link - `bounced` — undeliverable (hard vs soft) - `complained` — user marked as spam - `unsubscribed` — user opted out Handler: ```typescript app.post('/webhook/email', express.raw({ type: 'application/json' }), (req, res) => { // Verify signature (per provider) const events = JSON.parse(req.body); for (const e of events) { if (e.event === 'bounce') { // Add to suppression list db.suppressionList.create({ email: e.email, reason: 'bounce' }); } if (e.event === 'spamreport') { db.user.update({ where: { email: e.email }, data: { suppressed: true } }); } } res.sendStatus(200); } ); ``` **Critical:** never send to suppressed emails. Bounce rate >5% damages your domain reputation. ## India-specific notes - **Mobile numbers for email verification** — some Indian apps require phone + email; plan for both - **Hindi/regional language emails** — all providers support UTF-8; some providers' templates have RTL/Hindi rendering issues — test - **GST on bills** — most providers bill from US; your accountant may need GST self-reverse-charge handling - **Card payments** — Razorpay doesn't work for subscription to US services; Indian international cards work but watch for 3D Secure friction ## Dedicated IP — when to buy Dedicated IP: ₹8,000-₹20,000/mo add-on. Consider when: - Volume >500K/mo - You need predictable deliverability (shared IPs have mixed reputation) - Scheduled bulk sends (newsletters) Warm up dedicated IP slowly — jumping from 0 to 100K/day triggers spam filters. ## Cost comparison (at 100K/month)| Service | Monthly cost (100K emails) | Extras |
|---|---|---|
| SendGrid Essentials | $19.95 | Validation API |
| AWS SES | $10 (100K × $0.10/1K) | In ap-south-1 region |
| Mailgun Foundation | $35 | Log retention |
| Postmark | $15 (10K batch pack) — or $50 for 100K | Transactional-only |
| Resend Pro | $20 | Modern DX |
For ≤100 emails/day — fine. Above that, deliverability drops on shared infrastructure. Use a dedicated transactional API.
Speed matters — Postmark delivers in 1-2 seconds. SendGrid and Resend similar. Avoid SES for OTPs (slightly higher latency on cold calls).
Advanced pattern: primary + fallback. Use Resend; fall back to SendGrid on API outage. Libraries like node-mailer-multi support this.
India SMS ₹0.20-0.50 per message (DLT-registered), email ₹0.02-0.05. SMS faster, email cheaper. Use SMS for critical OTPs; email for everything else.
Yes — use noreply@ or alerts@ for transactional, news@ or subdomain for marketing. Isolates reputation if marketing gets flagged.
Send transactional email reliably from your DomainIndia-hosted app. View hosting plans
Was this article helpful?
Your feedback helps us improve our documentation
Still need help? Submit a support ticket