Durable notification workflows, in your own code.
Palumb is notification infrastructure that calls your code: unlimited workflows, your own sending provider, and the whole delivery path open source.
The beta is free, open to everyone, and it does not end.
No vendor lock-in.
Everything that would be hard to leave behind is already yours. In your repository, on your provider, under a licence you can run yourself.
What stays yours
Your workflows
notifications/order-placed.tsIn your git repository. Versioned, reviewed, diffable. We keep no copy: we call your deployment and deliver what it returns.
Your templates
invoice.tsxWhatever engine you already use. There is no Palumb template system, so there is nothing to migrate off.
Your providers
SMTP_HOST=…Your server, your API keys, your sending reputation. Palumb has no sending capacity of its own.
The engine itself
AGPL-3.0The whole delivery path is published. Self-host it and you owe us nothing.
What you take on
Running it yourself
The machines, the upgrades, the backups, the monitoring, and whatever breaks at three in the morning.
The hard parts, handled.
The parts of a notification system that are easy to promise and slow to get right: waits that survive a deploy, retries that do not hammer the provider, a record of what actually happened to every attempt. Palumb ships them so you do not have to write them yourself.
A workflow branching into the three ways time enters it, all three of them steps in its body: gathering events until Monday, a durable delay of three days, and waiting for a shipped signal.
Gathering, waiting, or sleeping for days.
A run can gather what arrives until an instant your code names, stay alive through hours or days without losing its place across a crash or a deploy, or pause until your app sends a signal or the timeout fires.
Any sending provider.
Send through the channel a workflow needs (Email, SMS, Telegram, Slack or push), each on your own sending provider, never pooled with anyone else's.
Fan-out.
Subscribe a recipient to a topic once; every trigger on that topic reaches everyone still on it, each with their own run. No loop you write yourself.
However you reach it.
Open the dashboard to look, call the REST API to build on it, or point your own AI agent at the MCP server. Same data, three ways in.
Tried, tracked, never twice.
A failed send is retried on a schedule that backs off, a retry never duplicates one that already went out (it carries the same Message-ID), and every attempt ends up in the record: accepted, failed or bounced, with the reason.
Three events reach one POST /sendEvent: comment.added, task.assigned, deadline.soon. It collects them into a single digest document with three entries and one email.
Digests.
Each event becomes one item in a digest that builds up over a window; when it closes, every item goes out in one notification, not one message per event.
Four template syntaxes stacked: a Handlebars tag, a React Email component, an MJML tag, and a plain template string.
Any template engine.
Keep the template engine you already use: MJML, React Email, Handlebars, or a plain string. Palumb never renders; it only delivers what you hand it.
What do you write it in?
The SDK is a library you import in TypeScript, PHP, .NET, Python, Go, Java or Rust, and it ships on the deploy you already run: no new runtime, no extra service, nothing to orchestrate.
Self-hosted: three services on your machine.
A standard, lightweight stack: the application, Restate and PostgreSQL, on Node.js. The whole delivery path is under AGPL-3.0.
services:
app:
image: palumb/palumb
restate:
image: restatedev/restate
postgres:
image: postgres:17
three services, one file
Fully managed: the same three, on ours.
We run the managed cloud version of Palumb: backups, upgrades, monitoring and patches are ours to handle, on European infrastructure. Your environment is still infrastructure as code: a Terraform file you version instead of a console you click. And because it runs the exact same software you would self-host, switching between the two is a deploy, not a migration.
What you declare converges into one Terraform file: providers, api keys, environment. The file reaches Palumb, and from there backups, upgrades, monitoring stop being yours.
European ownership, not just EU hosting.
Every company in the delivery path is European. So is the one you would take to court.
No parent in another jurisdiction to compel, no hyperscaler in the middle. You can check the lot, and who owns them, in the sub-processor list; who can compel whom, and what adequacy actually settles, is on the jurisdiction page.
A map of Europe with seven marked countries: Italy for founder, France for cloud, data, Germany for domain, mail, Netherlands for monitoring, Slovenia for CDN, Sweden for contact form, Estonia for payments. Every one of them is inside the European Union.
Who is Palumb for?
Engineers who would rather keep the notification logic in their own repository, on the stack they already have, than hand it to someone else's engine. Europe and regulated sectors are where the question gets asked first, not the only place it gets asked.
Engineers, not editors
You would rather review a pull request than a canvas.
Operational sending
Your notifications are transactional, and getting one wrong costs you.
A European stack, on purpose
You are building in Europe, and you would rather your suppliers were too.
Migrating off a vendor
You already run a notification platform, and want the exact differences before you touch it.
Palumb is bootstrapped: no investors, no board, no exit to answer to. The European argument on this page is worth only what the company behind it is free to keep, and there is no one else with a claim on that. Who builds Palumb →
Everyone who joins gets in, and it costs nothing. Your invite goes out when the beta opens.
Join the beta