Morning data freshness board for your BigQuery tables

One grid of every table you track, when it last landed, and what broke, with stale tables pinned to the top and an agent that explains why.

App
Google BigQueryLinearSlack BotEngineeringOperationsResearch & MonitoringNotifications & Alerts
PromptCreate

Build me a data freshness board that my data team opens first thing every morning. The whole point is to answer one question fast: did last night's data land where it was supposed to? I want a single grid covering every table across the BigQuery datasets we track, and I want the broken things impossible to miss.

The main view is one table-per-row grid with these columns: table name (project.dataset.table), dataset, owner, last updated, row count, the freshness window we expect it to land inside, and a status. Anything past its window is stale and pins to the top of the board in red with the overdue amount spelled out ("4h late", "2 days late"). Everything healthy collapses into a section below that starts closed, with a count on it like "38 tables healthy". Sort the stale group by how badly overdue it is, worst first.

Build the grid with BigQuery handlers. Use List Projects to discover the projects the connected account can read, List Datasets to enumerate datasets in the projects we have chosen to track, and List Tables to enumerate the tables in each tracked dataset. Then call Get Table per table for lastModifiedTime and numRows, which are the last-updated and row-count columns. Cache the assembled board in app state and refresh it when someone opens the app or hits a Refresh button, rather than re-walking every table on every render, because a wide warehouse means a lot of metadata calls.

lastModifiedTime is cheap but it lies for tables written by streaming inserts, which get touched constantly whether or not new business data arrived. So let each table optionally declare a freshness timestamp column instead. When one is set, measure freshness with a Run Query (Synchronous) call that selects MAX of that column for the table, and use that value as last-updated rather than the metadata timestamp. Show in the row which measure is being used so nobody is confused about where the number came from.

Clicking a row opens a detail panel for that table. The panel runs Run Query (Synchronous) against INFORMATION_SCHEMA.JOBS_BY_PROJECT (region-qualified for the dataset's location) to list the recent load and query jobs whose destination was this table, showing job id, type, who or what submitted it, start time, duration, rows written, and outcome. Below that, show a row count trend for the last 14 days from the same job history so the team can see a load that ran but landed far fewer rows than usual. Use List Jobs on the project and Get Job on individual job ids to surface failed and cancelled jobs, including the error message, since a job that errored is usually the actual explanation for a stale table.

Every stale row gets an Investigate button that kicks off a background agent for that table. The agent should: read the table's configured upstream dependencies and check whether those upstream tables are themselves fresh (Get Table, or the MAX-timestamp query where configured); pull the recent job history for the table with List Jobs, Get Job, and an INFORMATION_SCHEMA query; and then write a short plain-English diagnosis back into the app card for that table. The diagnosis should classify what happened into one of three buckets, in plain words: the pipeline failed (a job errored or was cancelled, quote the error), it ran late (the job is still running or started behind schedule), or it landed empty (the job succeeded but wrote zero or far fewer rows than the usual daily volume). If the real cause is an upstream table rather than this one, say so and name the upstream table, because pointing at the symptom is what makes these boards useless. Show a running state on the card while the agent works, then replace it with the diagnosis and a timestamp.

Once a diagnosis exists, two follow-up actions appear on that card. The first files it as a Linear issue with Create Issue, prefilled with the table name in the title and the diagnosis plus recent job details in the description, letting the user pick or default the team and assign it to the table owner where that maps to a Linear user. Store the created issue key on the card and link to it so nobody files the same thing twice. The second posts the same summary to our data channel with the Slack Bot Send a Message action, formatted as a short readable update: table, how late it is, the diagnosis, and the Linear issue link if one was filed.

Freshness windows and table owners are configured per table inside the app, not in SQL, so anyone on the team can adjust the expected cadence when a pipeline's schedule changes. Each tracked table stores: expected freshness window (a duration, plus an optional expected-by time of day for daily tables), owner name or email, optional freshness timestamp column, and an optional list of upstream tables it depends on. Include a settings view for choosing which projects and datasets are tracked, and let people edit a table's config inline from the grid too.

The board must remember which stale tables have already been acknowledged, so the same known-broken table does not shout at the team every single morning. An Acknowledge button on a stale row moves it into a muted "known issues" group below the active stale group, keeping its diagnosis and any linked Linear issue visible, along with who acknowledged it and when. The acknowledgement clears automatically the moment the table lands fresh again, so a table that breaks a second time comes back to the top in red rather than staying quietly muted forever.

A few implementation notes. BigQuery returns numRows, lastModifiedTime, and other numeric fields as strings, so parse them carefully. Jobs and queries must run in the dataset's location, so read the location from List Datasets and pass it through on query and job calls. Keep the default board build to metadata calls only, and reserve actual queries for the detail panel, the optional MAX-timestamp freshness measure, and the investigate agent, so opening the board every morning stays cheap. Show a last-refreshed timestamp on the board so people know how current the view itself is.

What does this prompt do?

  • Shows every table across the BigQuery datasets you track in a single grid: when it last updated, how many rows it holds, who owns it, and the freshness window you expect it to land inside.
  • Pins anything past its window to the top in red and collapses the healthy tables underneath, so the morning check takes seconds instead of a spelunking session.
  • Click any row to see the recent jobs that wrote to that table, any that failed or were cancelled, and how its row count has moved over the last 14 days.
  • Hit Investigate on a stale table and a background agent checks its upstream tables and recent errors, then writes a plain-English verdict you can file as a Linear issue or post to your data channel in Slack.

What do I need to use this?

  • A Google account with read access to the BigQuery projects and datasets you want to watch
  • A rough idea of how often each table should update, which you set per table inside the app
  • A Linear workspace, if you want to file issues straight from the board
  • A Slack workspace where the app can post to your data channel

How can I customize it?

  • Set the freshness window per table: hourly, every morning by 6am, weekly, or whatever your team has promised the business.
  • Point tables that arrive by streaming at a timestamp column, so freshness reflects the newest row rather than the last time the table was touched.
  • Choose which projects and datasets appear on the board, and name an owner for each table so a stale row always has someone attached.
  • Pick the Slack channel and the Linear team that the follow-up buttons post into.

FAQs

Does this change anything in our warehouse?
No. The board only reads table metadata and runs read-only queries to build the freshness view and the history panel. The only things it ever writes are a Linear issue or a Slack message, and only when someone clicks the button.
How does it decide a table is stale?
It compares when the table last updated against the freshness window you set for it. A table with a six hour window that has not updated in nine hours is stale and jumps to the top of the board in red.
What about tables that are fed by streaming data?
The last-updated timestamp can be misleading for streaming tables, so you can optionally point a table at one of its own timestamp columns instead. The board then uses the newest row in the table as the freshness measure.
Will it keep shouting about a table we already know is broken?
Only until you acknowledge it. Acknowledged tables move into a quiet known-issues section and stay there until the table lands fresh again, at which point the acknowledgement resets on its own.
Do we need to write SQL to set this up?
No. Freshness windows and table owners are edited inside the app, so anyone on the team can adjust the expected cadence for a table without touching code or asking an analyst.

Related templates

Review desk for portal forms your team still fills in by hand

Stage a batch of filings overnight, then approve each completed form from a screenshot before anything is ever submitted.

Kernel
Google Sheets
Slack Bot
App
Client-by-client cold email pipeline review for agencies

Pick a client and a date range to see sent, replies, meetings booked and the real deal value your cold email produced, campaign by campaign.

Instantly
HubSpot
Slack Bot
App
Find the customers stuck contacting support again and again

A board that ranks the people who opened three or more separate support conversations this month, reads their threads, and files the real fix.

Kustomer
Linear
General Input Database
App
Audit what Intercom's Fin AI actually resolved before you pay

Review every conversation Fin closed as resolved, judge which ones actually stuck, and see what the gap is worth against your bill.

Intercom
Google Sheets
Slack Bot
App
One triage console for every Jira service desk queue

Merge your IT, HR and Facilities queues into one list ranked by SLA time left, then reply, change status and escalate without ever opening Jira.

Jira Service Management
Jira
Slack Bot
App
Run your Webflow site translations from one review desk

See every page's translation status at a glance, edit translations side by side with the English, and publish only what your team has actually approved.

Webflow
JigsawStack
Slack Bot
+1
App

Stop starting the day wondering whether the data landed.

Give your data team one board that answers it, explains what broke, and turns the answer into a ticket.