Measure, Keep, and Grow1 · What PostHog is

PostHog Workflows vs Hogsend

What Hogsend is — a code-first lifecycle engine — why it makes PostHog dramatically better for teams that live in code, and how it splits from PostHog's own no-code messaging product.

Hogsend is a code-first lifecycle & marketing-automation engine. You write your onboarding emails, drip campaigns, and Discord/Telegram nudges as TypeScript journeys that live in your repo, run on your own infrastructure, and are triggered by the same PostHog events you're already capturing. It's what makes PostHog dramatically better for growth teams that live in code: the measurement stays in PostHog, and Hogsend turns those measurements into action you can version, code-review, and trust.

PostHog has its own messaging product (PostHog Workflows, formerly the open-source Laudspeaker). It's a no-code canvas for marketers, and it's good at what it does: batch sends and simple drip campaigns targeted on PostHog data.

The PostHog Workflows builder: a visual canvas where a Trigger connects to an Email step, a Wait-until-condition step, a branch into 'if condition matches' and 'no match' paths, and an Exit — with a palette of Email, SMS, Slack, Delay, and branch blocks on the right.
PostHog Workflows: the same onboarding logic as boxes on a canvas — trigger, email, wait, branch, exit. PostHog docs

This course pairs PostHog with Hogsend instead, for the lifecycle layer, because the audience here is people who build, and because the messaging layer is where the "owned by the people who build" principle actually bites. The split is deliberate:

PostHog WorkflowsHogsend
AuthoringVisual no-code canvasCode-first TypeScript (defineJourney)
Lives inPostHog cloudYour repo, your infra, your email provider
Best atBatch + simple drips, by marketersDurable multi-step journeys, by developers
VersionedA config in a UIA dependency you pin and code-review
LogicWhat the canvas exposesAnything you can express in code

The clean division of labour, which the rest of the course follows:

  • PostHog detects — event collection, identity, cohorts, the analytics you read.
  • Hogsend acts — the journeys that send the emails and Discord/Telegram messages, triggered by events, with the results fired back as events PostHog can measure.

To make "code-first" concrete before the lifecycle chapter builds it properly — this is a real journey shape, abbreviated:

defineJourney({
  meta: { id: "activation-nudge", trigger: { event: "user.signed_up" } },
  run: async (user, ctx) => {
    await sendEmail({ to: user, template: "welcome" });
    const { timedOut } = await ctx.waitForEvent({
      event: "project.created",
      timeout: hours(48),
    });
    if (timedOut) await sendEmail({ to: user, template: "activation-nudge" });
  },
});

Read what that buys you: the branching is ordinary TypeScript (if), the "wait up to 48 hours for the activation event" is one line, and the whole thing lives in a pull request a colleague reviews. Now picture maintaining the same logic as boxes on a canvas — then picture the version with three more branches. That divergence is the whole argument, and it compounds with every condition you add.

You don't have to choose one forever. The point is that the measurement lives in PostHog and the code-first lifecycle automation lives in Hogsend — and the lifecycle chapters are entirely about why a code-first journey beats a flowchart once your logic gets real (behavioural branching, exact-once sends, holdouts you can prove).