← Back to blog
批量发送群发速率限制开发者

Bulk Email Sending: Batching, Rate Limiting, and Large-Scale Delivery

Rovela batch API, cursor-based pagination for large lists, exponential backoff, send timing, and progress tracking.

Updated October 12, 2026
Bulk Email Sending: Batching, Rate Limiting, and Large-Scale Delivery

Bulk Email Sending: Batching, Rate Limiting, and Large-Scale Delivery

Sending ten thousand emails is a completely different problem from sending one. Bulk sending requires thinking about rate limits, memory usage, retry logic, and reputation impact.

Rovela batch send API

Rovela supports a batch send endpoint — one API call for multiple emails:

await rovela.emails.sendBatch([
  { from: 'news@yourdomain.com', to: 'user1@example.com', subject: 'Weekly update', html: '...' },
  { from: 'news@yourdomain.com', to: 'user2@example.com', subject: 'Weekly update', html: '...' },
  // up to 100 per request
]);

Handling large lists

You can't load 100,000 recipients into memory at once. Use cursor-based pagination from the database:

async function* streamContacts(batchSize = 1000) {
  let cursor = 0;
  while (true) {
    const rows = await db.query(
      'SELECT email, name FROM contacts WHERE status = $1 AND id > $2 ORDER BY id LIMIT $3',
      ['active', cursor, batchSize]
    );
    if (rows.length === 0) break;
    yield rows;
    cursor = rows[rows.length - 1].id;
  }
}

for await (const batch of streamContacts()) {
  const messages = batch.map(contact => ({
    from: 'news@yourdomain.com',
    to: contact.email,
    subject: 'This week',
    html: renderNewsletter({ name: contact.name }),
  }));
  await rovela.emails.sendBatch(messages);
  await sleep(100); // pace the sends
}

Rate control

Rovela's API is rate-limited; exceeding it returns 429. Use exponential backoff:

async function sendWithRetry(messages, attempt = 0) {
  try {
    return await rovela.emails.sendBatch(messages);
  } catch (err) {
    if (err.status === 429 && attempt < 5) {
      await sleep(Math.pow(2, attempt) * 1000); // 1s, 2s, 4s, 8s, 16s
      return sendWithRetry(messages, attempt + 1);
    }
    throw err;
  }
}

Send timing

When you send bulk email affects deliverability:

  • 9–11 AM or 2–4 PM on weekdays get the highest open rates (B2B)
  • Tuesday and Wednesday generally outperform Monday and Friday
  • Avoid late-night sends, especially when warming a new IP

Progress tracking

For large campaigns, record progress so you can pause and resume:

await db.query(
  'UPDATE campaign_sends SET sent_count = $1, last_contact_id = $2 WHERE campaign_id = $3',
  [sentCount, lastId, campaignId]
);