Background sending with per-sender rate limits #36

Closed
opened 2026-10-15 01:18:54 -04:00 by vmanne-poc · 0 comments
Owner

Today:

  • "Send now" sends every email inside the HTTP request, one after another, creating a new SMTP connection each time.
  • Large lists time out the request.
  • There is no way to respect a provider's limits. The SES sandbox allows 1 email per second, and production SES has a per-account rate.

Plan

  • Sending moves to a background job:
    • POST .../send claims the campaign (it is already atomic) and returns right away
    • a worker (the scheduler process) sends in batches
    • the campaign shows progress (sent / total)
  • Use a DB-backed queue, with no new infrastructure: Message rows with queuedAt and no sentAt or failedAt are the queue. The worker restarts safely after a crash, and nothing is sent twice. Each row is claimed before sending.
  • Per-sender rate limits: emails per second, per minute and per hour, all optional, set on the sender form.
  • Reuse one pooled transport per sender per batch.
  • Retry temporary failures (4xx SMTP replies) with back-off. Permanent failures (5xx) set failedAt and keep the error text, which shows in the report.
  • The UI shows SENDING with progress and refreshes automatically.
**Today:** - "Send now" sends every email inside the HTTP request, one after another, creating a new SMTP connection each time. - Large lists time out the request. - There is no way to respect a provider's limits. The SES sandbox allows 1 email per second, and production SES has a per-account rate. **Plan** - Sending moves to a background job: - `POST .../send` claims the campaign (it is already atomic) and returns right away - a worker (the scheduler process) sends in batches - the campaign shows progress (sent / total) - Use a DB-backed queue, with no new infrastructure: `Message` rows with `queuedAt` and no `sentAt` or `failedAt` are the queue. The worker restarts safely after a crash, and nothing is sent twice. Each row is claimed before sending. - Per-sender rate limits: emails per second, per minute and per hour, all optional, set on the sender form. - Reuse one pooled transport per sender per batch. - Retry temporary failures (4xx SMTP replies) with back-off. Permanent failures (5xx) set `failedAt` and keep the error text, which shows in the report. - The UI shows SENDING with progress and refreshes automatically.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
vmanne-poc/Postak#36
No description provided.