Email marketing at a low price, historically by sending through Amazon SES on your behalf. Lists, campaigns, simple automations and landing pages.
Build me email marketing that replaces EmailOctopus — and know exactly what the price is buying. It is **the SES relationship, wrapped so you never touch it**: the quota increases, the account review that comes with volume, the suppression list, and the bounce plumbing. You will still send through a provider. What you take on is the account, the warm-up, and being the one who is suspended if the complaint rate rises. That is the whole verdict. STACK - Node 20+ with Fastify, server-rendered HTML - SQLite through better-sqlite3, WAL mode - Amazon SES or an equivalent, through its API - A worker for sending, separate from the web process - Caddy in front THE SES REALITY, BEFORE ANY CODE - A new account is in a sandbox: you can only send to verified addresses, at a low rate, until you request production access and explain what you send and how people opted in. That request is a form a human reads, and it can be refused - Quota increases are requested as volume grows, each one a wait - The account is suspended if the bounce rate or complaint rate crosses a threshold. Those thresholds are low and they are measured over a rolling window - So: read the sending policy before writing anything, and put the numbers in the README THE DATA MODEL - lists, contacts, segments — segments as saved rules evaluated at send time, never stored as a member list - contacts: id, list_id, email, fields_json, status, confirmed_at, unsubscribed_at, bounced_at, complained_at, source, consent_text, consent_at, ip_hash - campaigns: id, list_id, segment_id, subject, preheader, body_html, body_text, status, scheduled_for, sent_at, recipient_count - deliveries: id, campaign_id, contact_id, status, sent_at, opened_at, bounced_at, bounce_kind, complained_at — one row per person per campaign, written before sending, which makes a resume exact and a duplicate impossible - suppression: email_hash, reason, at — global, across every list, forever - automations and automation_sends, so nobody receives a step twice - provider_events: id, message_id, kind, payload_json, processed_at — bounces and complaints arrive as notifications and must be idempotent SENDING - The worker claims a batch with a lease, sends, records the provider's message id, and continues. A crash resumes exactly where it stopped - Rate limited to the account's current quota, read from the provider rather than hard-coded - A test send required before any campaign, and a confirmation showing the recipient count and the segment - Bounces and complaints consumed from the notification topic: a hard bounce suppresses immediately, a soft bounce counts and suppresses after several, a complaint suppresses permanently and is never mailed again under any circumstance - The provider's own suppression list synchronised with yours, so the two never disagree DELIVERABILITY - SPF, DKIM and DMARC on your sending subdomain, with the records in the README - Separate subdomains for marketing and transactional. A password reset that fails because a campaign got complaints is a support disaster - Warm slowly: hundreds, then doubling over weeks - List hygiene: suppress anyone who has not opened anything in a very long time, and say so in the interface THE MESSAGE - Built with MJML or tables and inline styles, with a plain-text alternative generated from the same source - Preview at phone and desktop width, and in the client that renders with the Word engine — that one is the constraint - Personalisation with a default for a missing value - One-click unsubscribe with no login, plus the List-Unsubscribe headers the large providers now effectively require THE LIST - Double opt-in, a signup form and an embeddable one, honeypot, rate limit per address hash - The consent sentence stored with its timestamp exactly as shown - Import with a dry run and a declaration of where the addresses came from. Importing a purchased list is how an account is closed in a week OPERATIONS - .env: DATABASE_PATH, BASE_URL, AWS credentials and region, FROM_ADDRESS, SESSION_SECRET, HASH_SALT - Migrations on boot, each once; nightly backup off the machine — the list is the asset - Health endpoint reporting quota, send rate, bounce rate and complaint rate. Those last two are the numbers to watch daily WHAT MATTERS MOST Suppression and the complaint rate. Wire the notifications before the first campaign, because reputation is the one thing here that cannot be repaired afterwards.
What you lose
- The whole SES relationship — quota increases, suppression lists and the account review that comes with sending volume
- A drag-and-drop editor and templates that render correctly in Outlook, which is its own discipline
- Automation sequences with timing and conditions already built
If you would rather not build
- Amazon SES on its own, for transactional mail
What it costs
as published on their pricing page
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $9/mo | — | — |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
Listmonk
$0Self-hosted campaign email that speaks SMTP or SES directly.
knadh/listmonkfree · open source
MJML
$0A markup language that compiles to email HTML which survives Outlook.
mjmlio/mjmlfree · open source
Why this verdict
our own opinion · changed only by a person
56/100
Verdict kinda at 56: sending is a solved problem via SES, but Outlook-safe templates and sequence timing are where the weekend goes.
History
tracked since 10 Aug 2026 · nothing is ever overwritten
Questions about EmailOctopus
answered from the record above
Is EmailOctopus free?
No — the plan we track is $9 a month. Starter at $9/month billed monthly for 500 subscribers; free up to 2,500 with limited sends.
Can you replace EmailOctopus by building your own?
ALMOST. A weekend of work, and real gaps remain. Replacement score 56 out of 100, build time a weekend. Read what you lose before you decide.
How much does EmailOctopus cost?
$9 a month on Starter — $108 a year. Recorded 9 Aug 2026.
What do you lose by replacing EmailOctopus?
The whole SES relationship — quota increases, suppression lists and the account review that comes with sending volume; A drag-and-drop editor and templates that render correctly in Outlook, which is its own discipline; Automation sequences with timing and conditions already built. If any of those carry weight for you, keep paying.
Is there an open-source alternative to EmailOctopus?
Yes: Listmonk, MJML. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

