How 1,000,000 personalized emails flow through one small pipeline — and why a crash can't cause duplicates.
System flow
One streaming pass: the recipient file is never held in memory. Batches of
1,000 pass two gates — a semaphore bounding work in flight (our memory and sockets) and a
token bucket bounding request starts/sec (the provider's quota) — into the transport seam;
every outcome has exactly one path out.
The pipeline knows no provider — Transport.sendBatch() is the single seam.
Full prose: docs/02-architecture.md.
Crash & resume — the checkpoint at work
Measured demo: the process is hard-killed (exit 137, no cleanup) after
~400k sends. The rerun reads the checkpoint, skips the 400 completed batches, and finishes the
remaining 600. Final checkpoint: 1,000 unique indices, zero duplicates.
sent in this run skipped via checkpoint crash point
The checkpoint is written after the provider accepts a batch and fsync'd
before anything else observes success — so the worst-case duplicate window is one batch,
never "everything since start". Full prose: docs/03-reliability.md.
Every failure has one exit
The retry unit is the batch, matching the transport's atomicity. Classification
happens at the transport boundary — only it knows what a provider's status codes mean.
Silently dropping batches would be the only failure worse than duplicates —
so malformed requests stop the campaign instead of being swallowed.