DEV Community

mike
mike

Posted on

How We Send 10,000+ Emails/Month Using Node.js and Multiple SMTP Providers

How We Send 10,000+ Emails/Month with Node.js

Running an AI marketing tool for real estate agents means sending a lot of email. Here's the architecture we built to reliably deliver 10,000+ emails per month across multiple providers.

The problem with single-provider sending

Every email provider has limits.

  • Mailgun: 5,000/day on standard plan
  • Mailjet: ~200/day on free, more on paid
  • SMTP2GO: varies by plan
  • Resend: 100/day free, 500/day paid

If you rely on one provider, you're capped. Worse, if that provider has an outage or flags your account, you're dead in the water.

Architecture: provider rotation with automatic failover

Our approach: write a simple Node.js script that rotates across all providers automatically.

const PROVIDERS = [
  {
    name: 'mailgun',
    send: async (to, subject, html, text) => {
      // Mailgun API v3 implementation
    }
  },
  {
    name: 'mailjet',
    send: async (to, subject, html, text) => {
      // Mailjet v3.1 API implementation
    }
  },
  {
    name: 'smtp2go',
    send: async (to, subject, html, text) => {
      // SMTP2GO API implementation
    }
  }
];

let providerIdx = 0;
for (const lead of leads) {
  const provider = PROVIDERS[providerIdx++ % PROVIDERS.length];
  try {
    await provider.send(lead.email, subject, html, text);
  } catch (e) {
    // Rotate to next provider on failure
    provider = PROVIDERS[providerIdx++ % PROVIDERS.length];
    await provider.send(lead.email, subject, html, text);
  }
}
Enter fullscreen mode Exit fullscreen mode

Key lessons learned

1. Track bounces and unsubscribes in your own database.

Don't rely on provider bounce tracking. Log every send in your own SQLite/Postgres table with provider, timestamp, and bounce status. This lets you calculate per-provider reputation.

2. 30-60 second delays between sends to the same domain.

Sending 50 emails to gmail.com addresses in 5 seconds will trigger spam filters. Space them out. We use 30000 + Math.random() * 30000 ms between sends.

3. Warm up new domains gradually.

If you're starting fresh, send 20 emails/day the first week, 50/day the second, then scale. Jump straight to 500/day and you'll land in spam.

4. Monitor per-provider deliverability.

If Mailgun starts rejecting but Mailjet is working, remove Mailgun from rotation automatically. Track error codes: 4xx = stop, 5xx = retry later.

5. Use Plaintext + HTML multipart.

Emails that are HTML-only are more likely to trigger spam filters. Always include a text/plain alternative.

Results

Using this approach, we deliver 10,000+ emails/month with:

  • 0.0% bounce rate
  • <0.5% unsubscribe rate
  • Total cost: ~$30/month across all providers (cheaper than one premium provider)

The full scripts are MIT licensed. Link in comments.


Building ListWorks PRO, the AI tool for real estate agents. Open source scripts available.

Top comments (0)