The events your app never emitted.
RowFire turns what happens in your database into events your tools act on: a Slack message or Zendesk ticket for your team, a Braze event or campaign for your customer, a call to any API. Engineering describes the event once, in SQL. Every team subscribes to it, without filing a ticket for each automation.
No sign-up. The demo runs on sample data and delivers to a built-in inbox.
SELECT a.id AS account_id, a.name AS account, a.owner_email, pa.invoice_no, pa.amount, pa.attempted_at FROM payment_attempts pa JOIN accounts a ON a.id = pa.account_id WHERE pa.status = 'declined'
Card declined for Kite Labs — INV-5 ($49.00, expired_card).
Payment failed for Kite Labs. Hi Femi, could you update your card?
payment_failed → starts the “update your card” campaign for the customer.
The problem
Every "when this happens, do that" becomes an engineering ticket.
The data is already in your database. But each alert, each campaign trigger, each "open a ticket when…" means application code, a deploy, and a queue behind the roadmap. So most of them never get built.
- Billing"Ping us when a card is declined — but not three times for one invoice."
- Sales"Post in #sales when an Enterprise account signs up."
- CS"Open a ticket when a trial ends in three days and never activated."
- Support"Escalate urgent tickets nobody has answered."
- Growth"Follow up with every NPS detractor, once a month at most."
- Lifecycle"Send
trial_stalledto Braze so the rescue campaign starts." - Product"Push the customer a notification when they hit 90% of their quota."
Events your app can't emit
Your app emits events when code runs. Not when something didn't happen.
A trigger is a query, not a change stream. So it can fire on conditions no line of application code ever announces, from data that's already there.
third declined charge this month
Derived conditions
Counts, thresholds and joins across tables become one event, defined once in SQL.
trial ends in 3 days, never activated
Absences
The cart nobody came back to, the urgent ticket with no reply, the user who stopped logging in.
no instrumentation, no deploy
Data you already have
Nobody has to add a tracking call and wait for a release. If it's in the database, it can be an event.
Why RowFire
Engineering defines the event once. Everyone else ships on their own.
The split follows who knows what: whoever knows the schema writes the query, and whoever owns the customer experience decides what happens and how often.
No engineering queue
Teams pick an event, say how often it may fire, attach an action and switch it on. Many rules can subscribe to one trigger.
Nothing changes in your app
No application code, no new service to deploy, no change-data-capture. RowFire reads with a read-only query and never writes to your database.
See it before it sends
A backtest replays a rule over the last N days. Shadow mode renders every real request without sending it. Promote when the numbers look right.
No duplicate noise
"Once per account per week" is a setting, not code. Three declines on one invoice are one billing problem, and customers hear about it once.
For your team and your customers
Slack and Zendesk for the people who work the problem. Braze custom events and campaign sends for the customer. Any REST API for everything else, with retries built in. Templates pull any column with {{ column }}.
All your databases
PostgreSQL, MySQL and MariaDB, as many as you have. Each trigger names the one it reads, so the app database and the support desk work side by side.
How it works
Three pieces, each owned by the person who knows it.
Describe the event as SQL engineering
A trigger is one SELECT. Join anything, compute anything, then pick which column is the clock and which columns make a row "one thing".
- Checked as you type: the columns it returns, aliases included
- Written in each database's own dialect
- Polled once, its rows fanned out to every rule on it

Subscribe a rule and backtest it support, billing, sales, growth
Pick the trigger, set how often one key may fire, and ask what it would have done. Here, 219 declined charges over 120 days become 107 tickets — 112 duplicates that never reach a customer.
- Once ever, once per period, or every nth time
- Example rows show exactly who would have been contacted

Attach an action, watch it in shadow, promote
Choose Slack, Zendesk, Braze or your own API, and write the message with the trigger's columns. New rules run in shadow: every request is rendered and recorded, nothing is sent. When it looks right, promote it to live.
- A stop-everything kill switch
- Every poll recorded, so "nothing happened" is distinguishable from "nothing ran"

From the demo
The backtest catches what a review would miss.
Real numbers from the sample SaaS company in the live demo, over 120 days of data.
Declined charges turned into Zendesk tickets by "once per account per week". The other 106 were retries that would have been duplicates.
Enterprise sign-up posts to #sales, naive query vs corrected. The backtest's example rows showed internal QA tenants slipping through.
Workers that would send when 16 race for the same row. A fire is claimed in the database first, so one event is one send.
Safety
Built to sit next to production data.
RowFire reads your database the way a reporting tool would, with more guardrails than most.
- Read-only, three ways. Read-only sessions, a parser that refuses anything but a single
SELECT, and the account you grant it. - What was checked is what runs. Queries are re-rendered from the validated syntax tree, with a statement timeout and a row cap.
- Credentials encrypted at rest. Secrets are applied at send time and never shown again after you save them.
- History never fires. Triggers start at "now", so switching a rule on doesn't replay last month.
- Versioned definitions. Every change is kept, and editing a live rule sends it back to shadow.
- Yours to run. Self-host it inside your own network. Open source under the AGPL.
FAQ
What it is, and what it isn't.
Isn't this reverse ETL?
No. Reverse ETL syncs state: a column kept equal to a field, continuously. RowFire emits moments: this just became true for this customer, so act once, at the cadence you chose.
How fast is it?
Triggers are polled, within a minute by default. It's built for reactions (campaigns, tickets, follow-ups), not for messages that must arrive instantly, like one-time passcodes.
Does it touch my database?
It only reads. Read-only sessions, a parser that accepts a single SELECT, and the account you grant it. More on safety.
Which databases?
PostgreSQL, MySQL and MariaDB, as many as you have. Each trigger names the one it reads.
See your first rule fire in five minutes.
The live demo gives you a private workspace on a sample SaaS company: two databases, seven ready-made rules, and a Demo inbox that shows what Slack and Zendesk would receive.