Pricing

How to Set Up Data Alerts in Google Sheets

ALERT!!Alert triggeredRevenue dropped 12% WoW→ Slack #finance-alerts
JW
James Whitfield

The four working ways to alert on Sheets changes — Tools > Notification rules (any account), Conditional Notifications (Workspace, 20-rule limit since Sep 2025), Apps Script with onEdit for real-time, and time-driven triggers for threshold checks — plus Slack webhook integration and the three non-triggering scenarios with fixes.

Most data lives in Sheets long enough to develop a problem before anyone notices. Revenue trends down for three weeks, a vendor's invoices stop landing in QuickBooks, a custom dimension in GA4 starts returning nulls — and the spreadsheet just sits there, factually accurate and silently wrong. The fix is monitoring: a layer that watches the underlying data continuously and alerts you the moment something matters.

This guide covers every realistic way to set up data monitoring and alerts in 2026: Google Apps Script with onEdit and time-driven triggers, native conditional formatting, Zapier-style trigger flows, the alerts buried in Coefficient and Supermetrics, and Brooked's AI-defined alerts — where you describe the condition in plain English and the agent sets up the query, threshold, and schedule.

Quick comparison: 5 ways to set up alerts on your data

MethodCostSetupAuto-refreshCodeBest for
Apps Script + onEdit / time-driven triggersFree2–4 hoursTrigger-based or scheduleRequiredOne-developer custom alerts with hard-coded thresholds
Conditional formatting + manual reviewFree10 minLive in-sheet onlyNoneVisual flagging when someone has the sheet open
Zapier / Make trigger flowsFrom $20/month30–60 min per alertTrigger-based (sheet edit, schedule)NoneNotify the team on a specific cell or row event
Coefficient or Supermetrics alertsPro tier $83+/user20 min per alertScheduledNoneTeams already paying for one of those tools
Brooked AI alertsFree tier · Pro $29/userUnder 2 min per alert15 min / hourly / daily / weeklyNoneTeams who want alerts they can describe rather than rebuild every time the metric changes

Method 1 — Apps Script with onEdit and time-driven triggers

Google Apps Script supports two trigger types for alerting: onEdit(e) fires whenever a human edits a cell; time-driven triggers fire on a schedule (every 1 hour, every 6 hours, daily). Combine these with MailApp.sendEmail or a Slack webhook posted via UrlFetchApp.fetch and you have a working alert system.

Apps Script
function checkRevenueDrop() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Weekly Revenue');
  const data = sheet.getRange('B2:B5').getValues().flat(); // last 4 weeks
  const lastWeek = data[3];
  const priorWeek = data[2];
  const drop = (lastWeek - priorWeek) / priorWeek;

  if (drop < -0.1) {
    const url = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK');
    UrlFetchApp.fetch(url, {
      method: 'post',
      contentType: 'application/json',
      payload: JSON.stringify({
        text: `:warning: Revenue dropped ${(drop * 100).toFixed(1)}% WoW (${lastWeek} vs ${priorWeek})`,
      }),
    });
  }
}

Schedule it with Apps Script Triggers → Add trigger → Time-driven → Hour timer.

Pros: Free, full control, no third party. Cons: You write and maintain every alert. onEdit only fires for human edits, not for changes by other scripts or by connectors like Brooked. The 6-minute execution limit is fine for alerts but bites you if you do anything complex.

Method 2 — Conditional formatting + manual review

Sheets' built-in conditional formatting flags cells visually based on rules: red when below threshold, green when above, bold when changed. Set up via Format → Conditional formatting → Add a rule.

This isn't really alerting — there's no notification when no one is looking at the sheet — but it's free, instant, and useful for in- session review. Use it alongside one of the other methods, not instead of.

Method 3 — Zapier / Make / n8n trigger flows

Zapier (and Make, n8n) have rich Sheets triggers: new row, updated row, new spreadsheet, value in cell changes. Chain them to Slack, email, PagerDuty, custom webhooks.

Pros: No code. Trigger model is natural for per-row events. Wide destination support. Cons: Per-task pricing scales fast at high volume. Sheet-only triggers can't see what's happening in the underlying database. Building a "did this metric change more than 10% week-over-week" alert in Zapier is awkward — it's really designed for row-event flows, not analytical thresholds.

Method 4 — Coefficient or Supermetrics alerts

Coefficient and Supermetrics both have alerting built into their Pro tiers. Define a query, set a threshold, pick a delivery channel. Mature and reliable. The downsides are both pricing-related: alerts are gated to Pro ($83+/user annual on Coefficient, $159+/month on Supermetrics), and adding an alert is a manual UI process per alert.

Method 5 — Brooked AI-defined alerts

Brooked's alerts are different in two important ways. First, they run against the live data source (Snowflake, Postgres, QuickBooks, HubSpot, GA4, anything Brooked connects to), so the alert is based on what's true in the database — not on what's in a sheet. Second, you describe the alert in plain English and the AI agent generates the query, threshold, and schedule for you. Editing an alert is editing the description.

Step 1 — Install Brooked and connect a data source

Install Brooked from the Google Workspace Marketplace. Free tier covers 100 imports per month and 5 active alerts. Connect at least one data source (see the connector guides for Snowflake, PostgreSQL, QuickBooks, etc.).

Step 2 — Describe the alert in plain English

Open the Brooked sidebar and click Alerts → New alert. Describe what you want to be alerted about. Examples:

  • "Alert me on Slack when weekly revenue drops more than 10% week-over-week"
  • "Email me when any customer's MRR drops more than 25% in a single month"
  • "Tell me when AR over 60 days old exceeds $500K"
  • "Notify the #support channel when ticket volume spikes more than 2× the trailing weekly average"
  • "Page me if any production database error rate exceeds 1% for 5 minutes"

Step 3 — Review the AI-generated condition

Brooked shows you what it generated:

  • The data source it picked
  • The query it'll run (full SQL or HubSpot/GA4 filter)
  • The threshold and the comparison logic
  • The schedule (15 min / hourly / daily / weekly)
  • The result of running the query against current data (so you see what would trigger today)

Edit any of them. The query in particular is worth glancing at — it's an auditable artifact you can paste into your SQL IDE if you want a second opinion.

Step 4 — Configure delivery

Pick delivery channels: a Slack channel (Brooked posts as a bot with a slash-command for acknowledgment), an email address (or list), or a webhook URL for custom destinations like PagerDuty or Discord. You can pick multiple channels per alert — finance alerts often go to both Slack and email for redundancy.

Step 5 — Pick a schedule and save

For most business data alerts (revenue, AR, pipeline, marketing spend), daily is the right cadence. For operational alerts (production error rates, queue depth), 15-minute. For monthly close items, weekly. Brooked surfaces the right default based on the nature of the metric the AI inferred.

Save. The alert runs immediately so you see the first result; from there it runs on the configured schedule. If the condition is already true today, Brooked sends a one-time backfill summary so you don't miss what's already happening.

Beyond alerts: schema drift and freshness monitoring

Alerts handle the threshold question — "did this metric cross a line?" — but the harder question is often "did something silently break upstream?" Brooked's monitoring layer watches connected sources continuously for two specific failure modes:

  • Schema drift — a column was added, removed, or had its type changed. Brooked posts the diff and pauses any imports that depend on the changed column until you acknowledge.
  • Data freshness — a source that should be refreshing isn't (e.g., the QuickBooks sync stalled because a token expired). Brooked alerts on freshness regressions automatically.

These are on by default for every connected source. No setup required. They catch the class of problem that makes spreadsheets silently wrong — the one the team doesn't notice until the board deck a week later.

Real-time alerts with onEdit — the pattern most guides skip

Time-driven triggers check every hour or every day. If you want an alert the instant a cell changes — the moment someone marks a deal Closed-Lost, the moment a status flips to Blocked — you need the installable onEdit(e) trigger. It fires within a second or two of the edit and gives you the event object with old value, new value, range, and editor.

Apps Script
function onEditAlert(e) {
  if (!e || !e.range) return;
  const sheet = e.range.getSheet();
  if (sheet.getName() !== 'Deals') return;          // only watch the Deals tab
  const col = e.range.getColumn();
  if (col !== 5) return;                            // only watch column E (Stage)

  const newValue = e.value;
  const oldValue = e.oldValue;
  if (newValue === oldValue) return;
  if (newValue !== 'Closed-Lost') return;           // only fire on this transition

  const row = e.range.getRow();
  const dealName = sheet.getRange(row, 1).getValue();
  const owner = sheet.getRange(row, 2).getValue();

  MailApp.sendEmail({
    to: '[email protected]',
    subject: `Deal lost: ${dealName}`,
    body: `${owner} just marked "${dealName}" as Closed-Lost (was ${oldValue}).`,
  });
}

Save the script, then in the Apps Script editor click the Triggers icon (clock) in the left sidebar, click Add trigger, pick onEditAlert, set the event source to From spreadsheet and event type to On edit. Authorise the Gmail scope. The alert now fires within seconds of the change.

Slack alerts instead of email

For team-shared alerts, Slack beats email almost every time — ambient, threadable, no inbox decay. Create an Incoming Webhook in your Slack workspace (api.slack.com/messaging/webhooks → Create New App → From scratch → Incoming Webhooks → Activate → Add New Webhook to Workspace → pick a channel). Copy the URL, store it in Apps Script's Properties service so it isn't in plain text: Project Settings → Script properties → Add → key SLACK_WEBHOOK.

Apps Script
function postToSlack(message) {
  const url = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK');
  UrlFetchApp.fetch(url, {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify({ text: message }),
  });
}

Call postToSlack(...) from any of the patterns above. The webhook is unauthenticated; rotate it if it leaks.

Conditional Notifications: the limits and the silent-failure cases

Conditional Notifications (Workspace Business/Enterprise/Education only) raised the per-sheet rule limit from 10 to 20 in September 2025. That's the cap — once you have 20 rules on one sheet, the next save shows 'Maximum rules reached'. The fix is either consolidating logic (Add Condition lets you OR multiple value checks in one rule) or splitting alerts across multiple sheets.

Three categories of change that look like they should fire a notification but won't:

  • Number format changes (2.5 → 2.50, or applying currency formatting)

    Fix: Format changes aren't value changes. Wrap the trigger cell in a TEXT() formula so the comparison happens on the string representation, or move the threshold check into Apps Script with onEdit.

  • Volatile functions (TODAY(), NOW(), RAND()) recalculating in the background

    Fix: Volatile recalcs don't count as user edits. Avoid using them as the trigger cell. If you need a 'time-based' alert (e.g. 'fire when this date is more than 7 days old'), use an Apps Script time-driven trigger that runs daily and checks the condition.

  • Cell values changed by IMPORTRANGE, Connected Sheets, or another script

    Fix: Conditional Notifications fire only on direct user edits. For data that arrives via formula, connector, or script, use a time-driven Apps Script trigger that compares the current value against a stored 'last seen' value in a hidden tab.

Asking the AI agent to set up alerts

The Chat tab is a faster front door than the alerts UI for setup. Ask: "Alert me on Slack whenever weekly revenue drops more than 10% week-over-week" and the agent walks through the same steps above conversationally — picks the source, drafts the query, confirms threshold, asks for delivery channels.

BrookedBrooked AI — Brooked AI alerts
Live
Ask anything about your Brooked AI alerts data…

What about Microsoft Excel?

Excel has Power Automate (formerly Microsoft Flow) for sheet-event triggers and email/Teams notifications. It's the Excel analog to Apps Script + Zapier combined. Coefficient supports alerts for Excel users on its Pro tier. Brooked is Sheets-only for now; teams that want AI-defined alerts on Excel data typically pull the data into Sheets via Brooked, set the alert there, and export the underlying analysis back to .xlsx when needed.

The verdict — which method when

  • I want a visual flag when the sheet is open

    Conditional formatting. Native to Sheets, free, takes 10 seconds. Right answer for in-session visual cues — but no notifications when the sheet isn't open.

  • I want a Slack ping when a specific cell crosses a threshold

    Zapier or Apps Script. Both are well-suited to row/cell-level triggers. Zapier if you don't want code; Apps Script if you do.

  • I want alerts on database / warehouse data, not just sheet data

    Brooked. Brooked alerts run against the live data source on a schedule — so the alert fires when the underlying database changes, not when someone opens the sheet.

  • I want to describe alerts in plain English

    Brooked AI alerts. Describe what you want to be alerted about; the AI translates to a query + threshold and sets up the schedule. Updating an alert is editing the description.

  • I want to be alerted on schema changes or data freshness issues

    Brooked monitoring. Brooked's monitoring layer detects schema drift (new columns, removed columns, type changes) and data freshness regressions automatically — these are infrastructure-level alerts that Apps Script and Zapier don't really cover.

Troubleshooting common issues

Frequently asked questions

What's the difference between monitoring and alerts?

Monitoring is the passive layer that watches your data continuously (freshness, schema, anomalies). Alerts are the active notifications that fire when something monitored crosses a threshold. You want both — monitoring catches the things you didn't know to look for; alerts catch the things you did.

Can I alert on data in a connected database, not just on a sheet?

Yes. Brooked alerts run against the connected data source on a schedule, so the alert is based on what's true in the database (or warehouse, ERP, CRM) at sync time — not on what happens to be in the sheet. This is the right model for any alert where the source-of-truth lives outside the spreadsheet.

How quickly does an alert fire after a change?

Brooked's minimum schedule is 15 minutes — so worst case, an alert fires 15 minutes after the underlying data crosses the threshold. For most use cases (variance, monthly close, AR aging), daily is the right cadence. For operational alerts (production database error rates, inventory levels), use the 15-minute schedule.

Does the AI agent understand finance and ops vocabulary?

Yes. 'AR aging buckets', 'MRR drop', 'gross margin compression', 'days-to-resolve on support tickets', 'WoW MAU' — all of these map to query patterns the agent knows. If the agent isn't sure, it asks a clarifying question before creating the alert.

What delivery channels are supported?

Slack (per-channel or per-user DM), email (any address, multiple recipients), and webhook for custom destinations (PagerDuty, Opsgenie, Discord, your own service). All three on every Brooked tier.

Can I review the AI-generated query before the alert goes live?

Yes. After you describe the alert, Brooked shows you the SQL query + threshold + schedule, lets you edit any of them, and runs the query once against current data so you see what would trigger today. You only save the alert after confirming it's right.

How does Brooked handle schema drift?

Schema drift is a separate alert category in Brooked. When a column is added, removed, or has its type changed in a connected source, Brooked posts a notification with the diff and pauses any imports that depend on the changed column. You acknowledge, decide how to handle, and resume.

Will alerts cost extra on top of my Brooked plan?

No. Alerts are included on every tier including the free plan. The free tier limits the number of active alerts (5 alerts/month); Pro is unlimited.

How does this compare to PagerDuty or Datadog?

PagerDuty and Datadog are operational monitoring tools for engineering teams — they sit in front of production systems and route incidents. Brooked is for business data alerts — finance, ops, growth — that live in spreadsheets. Different category. You'd use PagerDuty for 'API is down', Brooked for 'AR is up 30% this week'.

Describe an alert in English. Get notified when it matters.

Brooked's free tier includes 5 active AI alerts, Slack + email delivery, and automatic schema-drift and freshness monitoring on every connected source — no credit card.

Install Brooked free →

Get your spreadsheet hours back

Brooked installs in seconds. Your team is querying live data before lunch.

Install for Google Sheets