Onboarding Email Sequence: Build It on Events, Not Days

Summary

An onboarding email sequence should be built around one activation event and send each email because of a user signal, not a calendar day. Start with a welcome email, add a 24-hour nudge that only fires if the first action is missing, define exit rules before you write copy, and measure click-to-activate against a holdout group instead of open rate, which mail privacy features inflate.

Signal lanterns lining a misty harbor pier at dawn

An onboarding email sequence works when it reacts to what a new user did, not to how many days have passed. Build it around one activation event, send each email because of a signal, and give every email an exit condition. A fixed Day 1, Day 3, Day 7 schedule is the fallback, not the design.

Most teams do the reverse. They write five emails, attach delays, and ship. Six weeks later activation has not moved and nobody can say which email is responsible.

Start from the activation event, not the welcome email

The sequence exists to move a signup to one measurable action. Pick it before you write a word of copy. "Created a project" or "sent first API request" qualifies. "Logged in" does not.

Define the window too. Our default is activation within 14 days of signup, counted per signup cohort. Without the window you cannot compare two versions of the sequence.

Then work backwards. List the steps a user must complete to reach that event, and give each step one email at most. If a step has no email, the user either does it alone or you accept the drop-off.

Notebook with hand-drawn flowchart next to a keyboard and coffee

Skip the "tour of features" email. It answers a question nobody asked on day two. One email, one action, one link.

What does a minimal sequence look like in practice?

Five emails cover most SaaS products with a trial. This is the shape we see hold up, with the trigger for each.

Notice that three of the five are conditional. The welcome email is the only one that goes to everyone.

Welcome emails also get the best open rates you will ever see. Treat that number with suspicion: Apple Mail Privacy Protection preloads images and inflates opens for a large part of your list. Track click-to-activate instead.

Time-based drips fail on the users who matter most

A pure time-based drip sends the day-three email to a user who activated on day one. That user now gets told to do something they already did. It reads as automation, and it is.

It also fails in the other direction. A user who is stuck on step two gets a cheerful feature email, not help. The sequence cannot see the problem, so it cannot respond.

The fix is not complicated, but it needs an event source. Behavioral sequences need three inputs: the event stream, a per-user state, and a rule that checks state before each send.

{
  "trigger": "user.signed_up",
  "steps": [
    { "id": "welcome", "delay": "0s" },
    { "id": "first_action_nudge", "delay": "24h",
       "send_if": "NOT event(project.created)" },
    { "id": "proof", "delay": "72h",
       "send_if": "event(project.created) AND NOT event(first_send)" },
    { "id": "last_step", "delay": "7d",
       "send_if": "NOT event(activated)" }
  ],
  "exit_when": ["activated", "unsubscribed", "account.deleted"]
}

The send_if check runs at send time, not at enrolment time. That distinction matters. If you evaluate the condition when the user enters the flow, you have built a static segment, and the state will be stale by the time the email goes out.

The exit condition is the feature people forget

Every sequence needs a rule that ends it. The obvious one is activation. Two others get missed: unsubscribe from the onboarding stream, and account deletion or trial expiry.

We have seen sequences keep emailing users after they converted to paid. That is an exit condition bug, and it costs you more than a missed open. It teaches the user that your emails are not tied to their account.

Write the exit rules first and test them first. Replay a few real user timelines through the flow in a staging environment and check that each one stops where it should. A sequence with good copy and no exits is worse than a sequence with plain copy and clean exits.

Laptop showing terminal event logs in a dim room

Where the event data comes from

The quality of the sequence depends on the quality of the signal. There are three common sources, and they have different latency and failure modes.

A product analytics pipeline such as Segment forwards events within seconds, but only the events you instrumented. A direct webhook from your backend is the most reliable, because it fires from the code path that does the work. Postgres change data capture sees everything that touches the row, including changes made by admin scripts, which can be a feature or a bug.

Pick one source of truth for the activation event, and document it next to the flow definition so the next engineer does not add a second one. Two sources that disagree by a few minutes will produce emails that contradict the product state. That is how a user gets "Finish setting up" after finishing setup.

Idempotency matters here as well. Event pipelines retry, so the same project.created event may arrive twice. If your sender does not deduplicate by key, the user gets a double send.

Customer.io is built around this model: it ingests events through an API, SDKs or a CDP and triggers from a workflow builder. If you already run on a different stack, the same pattern works with any sender that accepts a trigger and evaluates conditions at send time.

Transactional or marketing: pick the stream deliberately

Some onboarding emails are transactional in practice. A "your API key is ready" message or an email verification should not wait behind a marketing queue, and it should not share a sending reputation with a promotional blast.

Postmark makes this split a design principle by separating message streams onto different infrastructure. The reasoning is sound even if you do not use it: a bad promotional send should never delay a password reset.

Our rule is simple. If the user cannot proceed without the email, it goes on the transactional stream. If the email is encouragement, it goes on the lifecycle stream, with an unsubscribe link that only affects that stream.

Brass railway switch lever at a track junction

Does a developer-first sender change the build?

It changes the starting point. With an API-first sender, the sequence logic lives in your code or in a small worker, and the provider only delivers. You get version control, tests and code review for your flows, and you lose the visual builder.

Resend takes this route, with a REST API, official SDKs and React Email templates. For a team that already treats emails as components, that is a reasonable fit. For a growth team that wants to edit copy without a deploy, it is friction.

Be honest about who edits the sequence. If the answer is "growth, weekly", a workflow builder is the right call, even if engineers dislike it. If the answer is "engineering, per release", keep it in code.

Measure click-to-activate, not opens

Open rate is a weak signal for this job. Mail privacy features inflate it, and an open does not mean the user did anything. Three numbers tell you more.

The holdout is the only way to know the sequence works. Without it, you are crediting the emails for activation that would have happened anyway.

We do not quote a benchmark activation rate here, because the published ones come from vendors with different definitions. Measure your own baseline first. Then change one email at a time.

Should you build one sequence or several?

Split by entry condition, not by persona labels. A user who signed up from an invite has a different first action than one who signed up alone. A user who imported data has already crossed a line the others have not.

Two or three entry paths are usually enough. More than that and the maintenance cost beats the lift, because every path needs its own exits and tests.

An all-in-one platform can reduce the setup work when the team is small. Brevo bundles email, SMS and a CRM under one login, which suits teams that do not want to wire an event pipeline yet. The trade-off is that the marketing dashboard sits at the center, and sub-second triggers are not what it is optimised for.

What we would ship first

Write the activation event and the 14-day window on one line. Build the welcome email and the 24-hour nudge with a send_if check and a clean exit. Add a holdout of 5 to 10 percent from day one.

Leave the proof email and the last-step push until you have two weeks of data. Add the blocker email as soon as you can name the most common failure in your logs. Which failure signal in your product would you wire up first?

Frequently asked questions

How many emails should an onboarding email sequence have?
Four to six emails over 7 to 10 days is the usual range, but the count matters less than the triggers. Every email after the welcome should depend on what the user has or has not done, and the sequence should end when they activate.
What is the difference between a drip campaign and an onboarding email sequence?
A drip sends on a fixed schedule to everyone. An onboarding sequence is tied to an activation event, checks user state before each send, and exits when the user activates, unsubscribes or leaves.
When should the first onboarding email be sent?
Within seconds of signup. The welcome email confirms the account and names one first action, so a delay of even a few minutes means the user has moved on to something else.
How do you measure whether an onboarding email sequence works?
Compare 14-day activation between users who got the sequence and a small holdout who did not. Add click-to-activate per email and trigger latency. Open rate alone is unreliable because of mail privacy preloading.
Should onboarding emails be transactional or marketing emails?
Both exist. Emails the user needs to proceed, such as verification or an API key, belong on a transactional stream. Encouragement and tips belong on a lifecycle stream with its own unsubscribe scope.
What data do you need to trigger onboarding emails by behavior?
An event stream that includes your activation event, a per-user state that records which events have fired, and a send-time check. Events can come from Segment, a backend webhook or Postgres change data capture.
notificationharbor
Start free