Home/Use cases/Database alert notifications
Use case · Database thresholds

Get a push notification when a database value crosses a threshold

Stock dips below ten. A queue table passes a thousand rows. Today's ad spend crosses your cap. These are the numbers you'd otherwise catch by remembering to run a query. Point a scheduled query at Lert and your phone buzzes only when the value crosses the line — not a second sooner.

Put the threshold in the query

The trick to a quiet, useful alert is to make the database do the comparison. Write a query that returns a row only when the condition is met — a low-stock WHERE, say — and the shell just has to check whether anything came back before it fires the POST.

check-stock.sh
#!/usr/bin/env bash
LERT_URL="https://lert.dev/p/your-id"

# -t: tuples only, -A: unaligned — returns just the value(s)
LOW=$(psql "$DATABASE_URL" -tA -c \
  "SELECT sku || ' (' || qty || ' left)'
     FROM products WHERE qty < 10 ORDER BY qty;")

if [ -n "$LOW" ]; then
  COUNT=$(printf "%s\n" "$LOW" | wc -l)
  curl -X POST "$LERT_URL" \
    -H "Content-Type: application/json" \
    -d "$(jq -n --arg b "$LOW" \
      '{title:"Low stock ⚠️", body:$b, tag:"stock"}')"
fi

Because the WHERE qty < 10 lives in SQL, the script sends nothing on a normal run and a full list of the offending SKUs when there's a problem. jq builds the JSON safely so a product name with a quote in it can't break the payload.

Set it up in three steps

1. Copy your Lert URL

Open the Lert app and copy your unique endpoint — something like https://lert.dev/p/your-id. Keep it server-side, in the script or an environment variable; treat it like a password.

2. Write the query that returns the value

Return exactly what you'd want on your lock screen. A SELECT count(*) for a queue depth, a SUM(amount) for spend, a list of rows for low stock. Keep the message short and specific — "Ad spend $512 / $500 cap" beats "threshold exceeded."

3. Schedule it — and POST only when it crosses

Run the check on a cron schedule. The conditional is what makes this pleasant to live with: no rows, no notification. Add the line to your crontab:

crontab
# Check stock every 15 minutes during the day
*/15 8-20 * * *  /opt/scripts/check-stock.sh

Getting the same alert every 15 minutes? Add a marker after you notify — a row in a small alerts_sent table, or a touched file — and skip the POST while it's set, clearing it once the value recovers. That turns a lingering condition into one notification instead of a stream. The same pattern powers uptime checks and server monitoring.

The spend-cap pattern

A single-value threshold reads cleanly when you compute the number in SQL and compare in the shell:

spend-cap.sh
SPEND=$(psql "$DATABASE_URL" -tA -c \
  "SELECT coalesce(sum(amount),0)::int
     FROM charges WHERE created_at::date = current_date;")

if [ "$SPEND" -ge 500 ]; then
  curl -X POST "$LERT_URL" \
    -d "{\"title\":\"Daily spend cap hit 💸\",\"body\":\"\$$SPEND today / \$500 cap\"}"
fi

Where this earns its keep

  • Low stock: know before a customer finds the "out of stock" page.
  • Queue depth: a jobs or outbox table climbing past its normal ceiling means a worker is stuck.
  • Spend / usage caps: daily ad spend, API usage, or metered costs crossing a budget line.
  • Data freshness: alert when the newest row in a table is older than an hour — an upstream feed has stalled.

Why Lert for database alerts

A full monitoring platform is overkill for "tell me when this number gets big." Lert needs no agent on your database host and no account — the endpoint URL is the authentication, so the whole alert is a query, an if, and one curl. Because it's a real iOS push, a threshold you'd otherwise notice tomorrow reaches you in seconds tonight.

FAQ

How do I avoid getting the same alert every few minutes?

Only send when the value crosses the threshold, or write a marker — a row in a state table or a touched file — after alerting so the job stays quiet until the condition clears and re-triggers. That turns a lingering problem into a single notification.

Where should the threshold check live?

Put the comparison in SQL with a WHERE or HAVING so the query returns rows only when the condition is met. The shell then just checks whether any rows came back before sending the POST.

Does this work with MySQL or SQLite too?

Yes. Any client that runs a query and hands a value to the shell works — psql, mysql, or the sqlite3 CLI. The Lert POST is the same one-line curl regardless of the database.

Do I need an API key or account?

No. Your Lert endpoint URL is the authentication — there's no separate key, token, or login. Keep it in the script or an env var.

How fast does the notification arrive?

Typically within a second or two of the POST. It's a real push, so it wakes a locked phone and buzzes a paired Apple Watch.

Let the data tap you on the shoulder.

Download Lert, copy your URL, schedule one query. Your phone buzzes only when the number crosses the line.

Get the app iOS