1. Rowfire
  2. Use cases

Alert sales when an account nears its seat limit

Post to Slack when a PostgreSQL account uses 80% of the seats it pays for, once a month per account, so account managers can start an upgrade conversation.

  • PostgreSQL
  • Slack
  • Zendesk
  • Account management
  • once per account per month

The trigger

One read-only SELECT against PostgreSQL. Rowfire polls it for new rows, and the rule fires once per account per month.

SELECT a.id AS account_id,
       a.name AS account,
       a.owner_email,
       a.seats,
       count(m.id) AS members,
       max(m.joined_at) AS latest_join
FROM accounts a
JOIN memberships m ON m.account_id = a.id AND m.removed_at IS NULL
WHERE a.is_internal = false
GROUP BY a.id, a.name, a.owner_email, a.seats
HAVING count(m.id) >= 0.8 * a.seats

Crossing 80% of seats is a derived condition: a count compared with a plan limit, across two tables. Table and column names are a sketch; adapt them to your schema.

The clock is latest_join, the moment the newest member joined, and the key is account_id.

{{ account }} is using {{ members }} of {{ seats }} seats. Owner: {{ owner_email }}.

Post it to the account manager’s channel, or open a Zendesk ticket if your team works from a queue.

For the customer-facing side of limits, see notify customers at 90% of their quota.

Questions

Can a trigger use GROUP BY and HAVING?

Yes. A trigger is any single SELECT: joins, aggregates and computed columns all work. It must return a clock column and the columns that make up the key.

Why once a month?

An account hovering around 80% would otherwise be announced every time someone joins. Monthly gives the account manager one prompt per cycle.