1. Rowfire
  2. Use cases

Thank customers on every fifth order

Send a Braze event on a customer's first order and every fifth one after it, from PostgreSQL, with an every-nth cadence instead of counting code.

  • PostgreSQL
  • Braze
  • Lifecycle
  • on the 1st, 6th, 11th… order per customer

The trigger

One read-only SELECT against PostgreSQL. Rowfire polls it for new rows, and the rule fires on the 1st, 6th, 11th… order per customer.

SELECT o.id AS order_id,
       c.id AS customer_id,
       c.first_name,
       o.total_amount,
       o.completed_at
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.status = 'completed'
  AND o.paid_at IS NOT NULL
  AND o.is_test = false

The trigger lists completed orders. The key is customer_id and the clock is completed_at. The rule does the counting: with a cadence of every 5th time per key, a customer’s first order fires, then every fifth after it. Table and column names are a sketch; adapt them to your schema.

The Braze side

Bind Braze track_event with external_id set to {{ customer_id }} and an event name such as order_milestone. A campaign triggered by that event sends the thank-you or the reward.

Lifetime milestones instead

If the reward is for a customer’s 5th order ever, put the count in the query: add row_number() OVER (PARTITION BY o.customer_id ORDER BY o.completed_at) as order_number, filter to the milestones you want, and use a once-ever rule keyed by order_id.

The same trigger can carry other rules with other cadences, such as a weekly thank-you or a post to the ops channel for every order. Each rule keeps its own count.

For customers who stopped before checkout, see recover abandoned carts.

Questions

Which orders fire, exactly?

With every 5th time per customer, the first order Rowfire sees for a customer fires, then the sixth, the eleventh and so on.

Does it count orders from before the rule existed?

No. A trigger starts at now, so history never fires and the count begins with the first order after the rule starts. For lifetime milestones, compute the order number in the query instead.

What if a worker crashes mid-send?

The count only advances for an occurrence that is genuinely new, so a replayed run doesn't shift which order is next in line.