Datadog is brilliant for "is my server on fire?" alerts. But what about "did revenue drop 20% today?" or "has this client not logged in for 7 days?" Those are business metric alerts — and most monitoring tools either can't do them or make them absurdly expensive.
The gap is real. Your infrastructure monitoring sees CPU, memory, and error rates. It doesn't see that your largest customer just stopped paying, that your trial-to-paid conversion dropped by half this week, or that a sales rep hasn't followed up on a deal in 10 days.
Business metric alerts require access to your actual database — the same Postgres, BigQuery, or Snowflake instance where your application data lives. And the condition isn't "is a number above a threshold" — it's "run this SQL query and tell me if the result means something is wrong."
Here are the four real approaches to solving this, with honest tradeoffs for each.
Approach 1: Cron + Python script (the DIY path)
The most common first attempt. Write a Python script, connect to your database, run a query, check the result against a threshold, and fire a Slack webhook if something looks off.
Here's a working example:
# alert_failed_orders.py
import os
import psycopg2
import requests
from datetime import datetime
conn = psycopg2.connect(
host=os.environ["DB_HOST"],
dbname=os.environ["DB_NAME"],
user=os.environ["DB_USER"],
password=os.environ["DB_PASSWORD"]
)
cursor = conn.cursor()
cursor.execute("""
SELECT COUNT(*)
FROM orders
WHERE created_at > now() - interval '1 hour'
AND status = 'failed'
""")
count = cursor.fetchone()[0]
if count > 5:
requests.post(os.environ["SLACK_WEBHOOK_URL"], json={
"text": f"Alert: {count} failed orders in the last hour. Check the payments dashboard."
})
conn.close()Deploy this on a cron job (*/15 * * * * for every 15 minutes) and you have a working alert. No monthly fee, no vendor lock-in, full control.
The honest problem: This works perfectly for one or two alerts. Then you add a third. Then a fifth. Then someone asks "can we get an alert when churn exceeds 3% this month?" and suddenly you have eight Python scripts, each with its own database connection, its own threshold logic, and zero observability into whether they're actually running.
Silent failures are the real killer. Your cron script crashes on a Tuesday night because the database connection timed out. No one notices until Friday when someone asks "why didn't we get the weekly revenue alert?" There's no retry logic, no audit trail, no way to see execution history without SSHing into the box and reading logs.
For 1-2 alerts on a technical team, this is honestly fine. Beyond that, you're building infrastructure you'll never maintain properly.
Approach 2: Datadog custom metrics ($5/metric/month)
Datadog can do business metric alerts — you emit custom metrics via their API or StatsD, then set up monitors on those metrics. The alerting infrastructure is excellent: escalation policies, composite conditions, anomaly detection.
The catch: custom metrics cost $5/metric/month. That sounds cheap until you realize you need a metric for "daily revenue," "failed orders per hour," "trial conversions this week," "customers with no login in 7 days," "deals without activity in 10 days" — and suddenly you're paying $50-100/month just for business metric monitoring on top of your existing Datadog bill.
More importantly, you still need to write the code that queries your database and emits the metrics. Datadog doesn't query your Postgres directly (nor should it — you don't want your monitoring tool running arbitrary SQL against production). So you're back to writing scripts, except now they emit metrics to Datadog instead of sending Slack messages directly.
Best for: Teams already deep in the Datadog ecosystem who want unified alerting across infrastructure and business metrics, and don't mind the per-metric cost.
Approach 3: dbt tests + alerting
If you're running dbt for your data transformations, you already have a test framework that can detect data quality issues. dbt tests can assert things like "this table should never have null values in the email column" or "revenue should never be negative."
You can extend this pattern to business alerts: write a dbt test that fails when a metric crosses a threshold, then pipe dbt test failures to Slack via Elementary, re_data, or a simple webhook.
The limitation: dbt runs on a schedule (usually hourly or daily). It's not real-time. If you need to know within 15 minutes that failed orders spiked, dbt isn't the right tool. It's designed for data quality validation during transformation runs, not for continuous monitoring.
Best for: Teams already using dbt that want to catch data quality issues and slow-moving metric degradation. Not for real-time threshold alerts.
Approach 4: SQL trigger platform (connect, write SQL, alert)
This is the approach that eliminates the maintenance burden without requiring a $5/metric/month bill. Platforms like Fastero, Census, and Hightouch let you connect your database, write a SQL query, define a condition, and choose an action — all through a UI.
The workflow is:
- Connect your database — Postgres, BigQuery, Snowflake, MySQL, Redshift. Read-only credentials, SSL encrypted.
- Write the SQL query that returns the metric you care about.
- Set the condition — "alert when result > 5" or "alert when result changes by more than 20%."
- Choose the action — Slack message, email, webhook, or run another query.
- Set the schedule — every 5 minutes, every hour, daily at 9 AM.
No Python scripts to maintain, no silent failures, full execution history visible in the UI.
Step-by-step: Setting up a SQL alert in Fastero
Let's walk through a concrete example. You want to be alerted when more than 5 orders fail in an hour.
Step 1: Write the SQL
SELECT COUNT(*) as failed_count
FROM orders
WHERE created_at > now() - interval '1 hour'
AND status = 'failed'Step 2: Set the condition
Alert when failed_count > 5. Fastero evaluates the first row of the result set against your condition.
Step 3: Choose the action
Send a Slack message to #ops-alerts with the template:
"{failed_count} orders failed in the last hour. Investigate in the payments dashboard."
Step 4: Set the schedule
Run every 15 minutes. Fastero executes the query, checks the condition, and only fires the Slack message when the threshold is crossed. If the count is 3, nothing happens. If it's 7, you get a message.
The entire setup takes about 3 minutes. You can see every execution in the trigger history — when it ran, what the query returned, whether the condition was met, and whether the action succeeded.
When you outgrow the script
The inflection point is usually around 5-10 alerts. That's when you start noticing:
- Silent failures — a script crashed last week and no one noticed. The alert didn't fire during an actual incident because the monitoring itself was broken.
- No audit trail — "Did this alert fire last Tuesday?" requires grepping through cron logs on whatever box runs the script.
- Threshold drift — someone hardcoded a threshold 6 months ago. The business has grown 3x since then. The alert either fires constantly (noise) or never fires (useless).
- No ownership — the engineer who wrote the script left. No one else knows where it runs or how to modify the SQL.
- No retry logic — if the database is briefly unreachable (maintenance window, connection pool exhaustion), the alert silently skips that interval.
These aren't theoretical problems. They're the reason every team eventually moves from scripts to a managed solution. The question is just which managed solution fits.
Decision guide
| Approach | Best for | Monthly cost | Setup time | Maintenance |
|---|---|---|---|---|
| Cron + Python | 1-2 alerts, technical team, no budget | $0 | 2 hours | High (silent failures) |
| Datadog custom metrics | Teams already on Datadog, unified alerting | $5/metric + existing bill | 1 hour | Low (but still need scripts to emit metrics) |
| dbt tests | Data quality checks, slow-moving metrics | $0 (OSS) to $100/mo | 30 min per test | Medium |
| SQL trigger platform (Fastero) | 5+ business metric alerts, team-friendly | Free tier available | 3 minutes per alert | Very low |
The honest answer: if you have exactly one alert and a technical team, the Python script is fine. Ship it and move on. But if you're reading this article, you probably have more than one metric you want to monitor — and the maintenance burden of scripts compounds faster than you'd expect.
Related reading:

