---
title: "Palumb vs Courier: notification workflows that stay in your own code"
url: "https://palumb.com/compare/courier"
description: "Courier has the widest channel list and the cleanest prices here. It is a US corporation, its EU datacenter is Enterprise-only, and you cannot self-host."
---

# Palumb vs Courier: notification workflows that stay in your own code

Written in your own repository, rendered by your own template engine, delivered through your own provider. The delivery path is open source, and the service is operated in the European Union under EU law alone.

[Join the beta](/waitlist/) [Jump to the comparison](#comparison)

Free up to 500 runs a month, and the beta is that free plan, so there is nothing to expire.

## Notification orchestration you stay in control of

Courier: More channels and real certifications. The only vendor here who publishes whose infrastructure runs its EU region, which is worth saying out loud.

Palumb executes the notification workflows you write, and takes nothing else. There is no builder to define them in, no template system to adopt and no sending pool to share: the workflow is a function in your repository, the message is whatever your own engine rendered, and it leaves on your own provider credentials. What Palumb runs is the part that is genuinely hard: resolving who should be told, executing steps durably across days and deploys, and keeping the record of every attempt.

Why teams pick Palumb

-   Workflows in your repository, not Palumb's
-   No lock-in: your template engine, your provider
-   Open source, and free to self-host
-   One EU jurisdiction, nothing to authorise

## What Courier asks you to accept

Every line comes from Courier's own documentation, checked on 25 August 2026.

### EU data residency is an Enterprise line item

Their own documentation: the EU datacenter is AWS eu-west-1 (Ireland) and “available for Enterprise customers”. So the requirement that brought a European buyer here is the one that moves them to the plan with no published price. With Palumb it is where the service already is.

### They tell you whose hardware it is, and that counts

Courier is the only vendor on these pages who publishes the infrastructure under its European region. Novu names its regions but not the hardware; Knock names neither. Their silence is not a better answer. Courier is simply the only one who gives you one, and gets marked down for it. Palumb's is Scaleway, a French company owned by Iliad.

### Courier is a US company, and Ireland does not change that

Courier is operated by trycourier.com, Inc., a US corporation participating in the EU–US Data Privacy Framework. A US company stays within reach of the US CLOUD Act wherever it stores data, because that follows from the company and not from the data centre. Ireland does not change it.

### The workflow is designed in their studio

Courier notifications are built in their designer and their automations, and a wait for something that happens outside is composed from a delay plus a cancellation token rather than being a step. In Palumb the workflow is a function in your repository, written in the language your application is already in, and the wait is a step with a timeout.

### Courier is proprietary, and you cannot run it yourself

The client libraries are open source; the product is not, and there is no self-hosted edition. Their cloud is the only place it will ever run, so the exit is a rewrite. Palumb's whole delivery path is AGPL-3.0 and self-hosting is free: the exit is a licence you already have.

### Seven days of log on the plan you start on

Retention rises with the plan: 30 days on Business, a year on Enterprise. Palumb keeps the proof of delivery (who, when, on which channel, with what outcome) for 90 days on every plan, the free one included, and the rendered content for 30.

## Palumb runs the workflow, and touches nothing else

The parts it runs are the ones that are easy to promise and slow to get right: waits survive a deploy, retries do not hammer the provider, and every attempt leaves a record.

[The full list is here](/features/).

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.

## Just write the workflow

A workflow is a function in your codebase. Our SDK gives it durable steps (a send, a wait on the clock, a pause until something happens in your product), and each one survives a crash and a deploy. There is nothing to define in a dashboard, and no copy of it on Palumb's side to drift from yours.

Three stacked boxes in one column, joined by a rail. Nothing travels along the rail. Instead the stretch of rail between two boxes fills, from the caller down to the one being called, holds while that one works, and then drains back the way it came. The fill is always the same grey, the ink of the Palumb mark: the line belongs to Palumb, and which end it starts from already says who placed the call.

At the top yourapp.com/backend, your own application, with the calls it makes into Palumb: trigger, for the orderPlaced workflow on topic.order-24, and days later sendEvent, for the order.shipped event. Each call is marked with a small square that fills in once Palumb has it, and appears only when it happens, so nothing is on screen before you make it, and the rail below it fills until Palumb holds the run, then drains back.

In the middle palumb itself, the durable engine, and it is the one box that is not an address because it is not something you run. It says one thing, running workflow, and it blinks, because a live run is the only thing in the figure that is happening rather than recorded. It appears only when the trigger arrives: before you call, there is nothing of yours in Palumb. Underneath it a row of small purple tokens grows, one for each step that has closed, each carrying that step's number, so by the end there are five and the row is the journal.

At the bottom yourapp.com/workflows/orderPlaced, your own workflow code, holding the program itself: the five steps numbered one to five: step.send for the confirmation, step.waitForEvent for the shipped signal with a thirty day limit, step.send for the tracking, step.delay of three days, and step.send for the feedback. Palumb calls down into it one step at a time, the rail filling down to that line and draining back. The moment a step is recorded its number leaves the line, replaced by a tick, and reappears as a token under Palumb: you wrote the step, we are the ones who remember it ran.

The steps are yours because they are written in your repository; what Palumb keeps is the place in the list. Through the thirty day wait and the three day delay the rail down to your code is grey and empty while the run stays alive in Palumb, which is why the run survives a wait in which your server does nothing at all.

order-placed.ts

```ts
workflow("orderPlaced", async ({ payload, step }) => {
  await step.send("confirmation", "email", () => confirmation(payload))

  const shipped = await step.waitForEvent("shipped", {
    event: "order.shipped",
    timeout: "30d",
  })
  if (!shipped) return

  await step.send("tracking", "email", () => tracking(shipped))

  await step.delay("cool-off", { seconds: 3 * 24 * 3600 })
  return step.send("feedback", "email", () => feedback(payload))
})
```

Worked examples, with the code

-   [How do you follow an order all the way to feedback?](/use-cases/order-updates/)
-   [How do you chase an unpaid invoice without chasing someone who paid?](/use-cases/unpaid-invoice/)
-   [How do you nudge a user who signed up and never came back?](/use-cases/activation-reminders/)
-   [How do you warn before a trial ends, and stop the moment they upgrade?](/use-cases/trial-ending/)
-   [How do you send a weekly summary on a fixed schedule?](/use-cases/weekly-summary/)
-   [How do you stop sending one email per comment?](/use-cases/comment-bursts/)

## Palumb vs Courier compared

Ownership, deployment, jurisdiction, pricing and what each of those means once you have signed.

|  | Courier | Palumb | What this means for you |
| --- | --- | --- | --- |
| Legal entity | trycourier.com, Inc. (United States) | One founder, Italy | Which government can compel a company follows from where it is incorporated, not from the region you pick. |
| EU data residency | Yes: AWS eu-west-1, Enterprise plan only | Yes, by default, on every plan | A European buyer's first requirement is their top plan and Palumb's starting point. |
| Infrastructure provider | AWS, and they publish it | Scaleway (France, Iliad) | They are the only vendor here who answers this in public, which is worth more than it costs them. |
| Open source | No: proprietary, client libraries aside | Yes: the whole delivery path, AGPL-3.0 | If the relationship ends you have something to run, not something to rebuild. |
| Self-hosting | Not possible: there is no self-hosted edition | Three services, same build as the cloud | Lock-in is the design there, not an oversight: their cloud is the only place it runs. |
| What a workflow is | A design in their studio | A function in your repository | Reviewed, typed and tested by the tools already running over the rest of your code. |
| What you write it in | Nothing: it is designed, not written | The language your application already uses | Seven are declared (TypeScript, PHP, .NET, Python, Go, Java and Rust), so the workflow is reviewed and tested by the tools already running over the rest of your code. |
| Billing unit | A send | A run, per recipient, any channels | Their pricing page says it is not per channel; the exact definition of a send is not in their public FAQ, and guessing at it would be worse than leaving it open. |
| Plans | Free to 10,000 sends, then $0.005 per send | Free to 500 runs, then €19, €49, €149 | The cleanest price curve of the four: no platform fee and no step. Their free tier is twenty times Palumb's, and Palumb's middle step works out at €0.0049 a run. |
| Log retention | 30 days on Business, one year on Enterprise | 90 days on every plan | Answering a dispute two months later is a plan upgrade there and included with Palumb. |
| Wait on an external event | Composed from a delay plus a cancellation token | A step, with a timeout | Waiting for the payment or the acknowledgement is something you assemble there and something you call with Palumb. |
| Channels | Email, SMS, push, in-app, chat, WhatsApp, Viber | Email at beta; SMS, Telegram, Slack and push declared | The widest channel list of anyone here. If breadth is what you are buying, buy Courier. |
| Certifications | SOC 2, GDPR, HIPAA | None | A buyer who wants an audit report on paper should buy Courier, and that is the right call. |
| Status | Generally available, with public customers | Private beta, no track record | You would be early, and being early carries a risk no argument removes. |

### Doesn't the United States have an EU adequacy decision?

It does, since 2023, and it still stands, so the transfer is lawful. It answers a different question from the one procurement asks: not which government can compel the company once the data is there. [The long version is on the jurisdiction page](/eu-jurisdiction/).

Taken from Courier's own [pricing page](https://www.courier.com/pricing), [privacy policy](https://www.courier.com/privacy-policy), [trust centre](https://security.courier.com/) and [documentation](https://www.courier.com/docs/welcome), including the page on their [EU datacenter](https://www.courier.com/docs/platform/workspaces/eu-datacenter). Checked on 25 August 2026. Facts about other companies go stale, and being corrected beats being wrong: if a fact here is out of date, [tell us](/contact/) and Palumb will fix it.

## Frequently asked questions

### What is the main difference between Palumb and Courier?

Palumb is open source, and it does one thing: it orchestrates. The workflow is a function in your own codebase, in your own language, deployed with the rest of your application; your template engine renders the message and your own provider sends it. Palumb resolves the recipients, executes the steps durably (waits included), and keeps the record of every attempt. You can also run the whole thing yourself, because the entire delivery path is AGPL-3.0 and self-hosting is free.

Courier is the opposite arrangement: proprietary software you cannot run yourself, notifications designed in their studio rather than written, and a US corporation whose European datacenter is sold as an Enterprise line item. On breadth Courier is ahead of everyone here (the widest channel list, a real compliance record, years in production), and their price curve is the cleanest of the four.

### Is Courier open source?

No. Courier is proprietary software. The client libraries you import are published under Apache-2.0 and MIT, which every vendor in this category does because otherwise nobody would import them. The product itself is closed and there is no self-hosted edition, so your notification history lives on their infrastructure for as long as you use them and the exit is a rewrite. Palumb publishes the whole delivery path under AGPL-3.0, and self-hosting is free.

### Does Courier offer EU data residency?

Yes, and they document it better than anyone else here: a dedicated European datacenter in AWS eu-west-1 (Ireland), with EU endpoints. Their documentation also says it is “available for Enterprise customers”. So the data can sit in Europe, on infrastructure owned by a US company, sold by a US company, on the plan you have to call sales for.

### How much does Courier cost?

Free up to 10,000 sends a month, then $0.005 per send with no platform fee and no step in between. That is the cleanest price curve of the four and pretending otherwise would be nonsense. Their free tier is twenty times Palumb's. Palumb is free to 500 runs, then €19, €49 and €149, which works out at €0.0049 a run in the middle. Both figures are each vendor's published prices, in their own currency.

### Can I define Courier workflows in code?

You trigger them from code through their API and SDKs, and you can manage templates programmatically. The notification itself is designed in their studio, and their automations compose a wait for an external event out of a delay plus a cancellation token. In Palumb there is nothing to design: the workflow is a function in your codebase, and the wait is a step with a timeout.

## The other comparisons

Six of them, each conceding first. If you are drawing up a shortlist, these are the rest of it, and [the index compares all six side by side](/compare/).

-   [Palumb vs Novu](/compare/novu/)
    
    The other self-hostable one, and the closest thing we have to a mirror. Bigger product, EU regions, and a company outside the Union.
    
-   [Palumb vs Knock](/compare/knock/)
    
    Richer workflow functions and an in-app feed. A New York company, and no self-hosting path at all.
    
-   [Palumb vs SuprSend](/compare/suprsend/)
    
    Multi-tenancy done properly, which is our own gap. Also a Delaware company processing data in the United States.
    
-   [Palumb vs MagicBell](/compare/magicbell/)
    
    An in-app inbox first, with a workflow engine of four commands and none of them waiting for an event. A San Francisco company that counts a delivery per channel.
    
-   [Palumb vs Building it yourself](/compare/build-it-yourself/)
    
    The competitor almost everyone actually picks, and for most teams the right answer. Here is where that stops being true.
    

Everyone who joins gets in, and it costs nothing. Your invite goes out when the beta opens.

[Join the beta](/waitlist/)