OperationsTutorial9 min

How to build a live metrics dashboard that updates itself

A live metrics dashboard in Zo is an automation writing numbers to a file plus a page that reads it. No BI tool rented. Here is the full build.

This weekvs last
Revenue $12.4k+8%
Signups 86+12
JK
Joanna Kurylo

A live metrics dashboard in Zo is two moving parts: an automation that writes your numbers to a workspace file on a schedule, and a Zo Space page whose API route reads that file every time it opens. The file is the single source of truth. It lives on your own server, not inside a BI tool you rent.

Key takeaways

  • A self-updating dashboard is a pull-then-serve loop: one automation appends a dated row to a file, one page reads that file at request time.
  • The source of truth is a file you own, a CSV or JSONL or a SQLite data.db next to your project, not a hosted database with a monthly bill and its own login.
  • Numbers come from three places: a file you already keep, a connected plugin like Stripe or Google Sheets, or a figure Zo reads out of a login-gated dashboard with its browser.
  • Not every metric needs a page. A three-line digest texted every Friday is the low-effort version, and the live page is the upgrade you build once the digest is landing.
  • The most common silent failure is a lapsed plugin token: the schedule keeps firing, the pull fails, the run looks fine, the dashboard reads stale. Tell the automation to flag a failed source, never write a zero.

Why does a dashboard go stale, and how do you fix it for good?

Most dashboards rot because a human has to feed them. You export a CSV on Monday, paste it into a sheet, refresh a chart, and by Thursday the numbers are three days old and nobody trusts them. A self-updating dashboard fixes this by removing you from the loop. Not with a fancier chart. By splitting the job in two.

One process writes the current numbers to a file on a schedule. Another reads that file and shows it. The writer runs whether you are at your desk or on a plane. The reader runs the instant someone opens the page. Nobody exports anything by hand. That split is the whole design behind an automated business dashboard, and every choice below is a version of "which half does this belong in."

Where do the numbers actually come from?

Before you build anything, answer one question: where does each number live right now? Three answers, each with its own setup and its own way of breaking.

SourceWhat it needsThe gotcha
A file you already keepNothing. Export the spreadsheet to CSV, or point Zo at existing JSON or SQLite. Zo reads it directly, plain English, no setupStop updating the source and the dashboard faithfully shows old numbers, looking fine while it does
A connected plugin (Stripe, Google Sheets, GA)The plugin connected once in Settings. The automation then calls it on schedule the way a chat wouldThe token can lapse. A changed password kills the connection, the call fails silently, the run still reports success
A number behind a loginA signed-in browser session. You log in through Zo's browser once, then Zo reuses the sessionSlow and fragile. Rendering a real page takes seconds, and the site can log you out or change its layout

The distinction that trips people up is read versus browse. If a logged-out stranger could see the number at that URL, Zo reads it fast. If it needs your session, Zo drives the browser, slower and more breakable. Once you are signed into that site, Zo reaches for the browser on its own for anything gated. A plain read only hands you a sign-in wall when you are not signed in there at all.

How do you build the automation that pulls the numbers?

This is the writer half, where kpi dashboard automation actually happens. It runs on a schedule, gathers the numbers, and appends one dated row to your source-of-truth file. The single most important line in the prompt tells it what to do when a source fails.

  1. Pick your file and its exact absolute path, like /home/workspace/Projects/metrics/metrics.csv. A relative path resolves against wherever the automation runs, so you get a "file not found" while the run still reports success.
  2. Decide the interval realistically. Daily suits most solo operators. Match it to how fast the number moves, because every scheduled run spends credits whether it notifies you or not.
  3. Write the prompt in plain English, name each source, and Zo converts your schedule to a rule and confirms it before saving.

A starting prompt. Change the sources, path, and time.

text
Every weekday at 6:00pm Eastern, gather my current business numbers:
- from Stripe: today's payment count and total revenue
- from my Google Sheet "signups": today's new signup count
- from /home/workspace/Projects/metrics/expenses.csv: this month's spend so far

Append ONE row to /home/workspace/Projects/metrics/metrics.csv with
columns: date, revenue, payments, signups, spend_mtd.

If ANY source fails to return a number, text me that the pull failed and which source broke. Do NOT write a zero and do NOT write the row. A missing number must never look like a real number of zero.

That last paragraph is the part almost everyone skips. A failed Stripe call that writes 0 is worse than no row: a zero on a chart reads as a real, terrible day you then burn an afternoon chasing. Flagging beats guessing. Always.

Run it under a focused persona that has only the scopes this job needs, so an unattended job touching your Stripe and inbox has a small blast radius if the prompt goes sideways. Keep write and send actions off it and review anything outbound yourself. The persona scopes guide covers what you can grant.

How do you make a page that reads the file so the dashboard is live?

Now the reader half. A Zo Space page is the fast way to publish a simple dashboard, and its API route reads a workspace file at request time. That is what makes it a real-time metrics dashboard rather than a snapshot: it reads the file fresh on every visit, not once at build. Ask for it in one message:

text
Make a Zo Space page at /dashboard that reads
/home/workspace/Projects/metrics/metrics.csv through an API route on every request. Show the latest row as four number cards (revenue, payments, signups, spend this month), and a small line chart of revenue over the last 30 rows. Dark, clean, glanceable on a phone. Then make the page public.

That is a no-code metrics dashboard: you described it once and never opened an editor. Two things to know. New Space pages are private until you say otherwise, so the "make it public" line matters if you want the dashboard on your phone without signing in. An API route, though, is public the moment it exists, so gate anything sensitive in the code. Never put a raw secret or API key in a route or file. Those belong in Settings, Advanced.

When the dashboard grows past a page or two, or you want a queryable database instead of a flat file, it wants to become a Zo Site with SQLite. Bun ships a SQLite driver, so the database is one data.db file next to your code, nothing to install.

Do you even need a page? The three-line version

Here is the downgrade nobody selling dashboards will tell you. Often you do not want a page. You want the number in your pocket once a week, no tab to open. That is the founder recipe called your real metrics in three lines: the same writer automation, minus the page, texting you the summary instead of writing a file.

text
Every Friday at 4:00pm Eastern, pull this week's Stripe payments and
refunds and compare them to last week. Text me a three-line summary with the direction each number moved. If a field isn't available, say so instead of guessing. Define my week as Monday through Sunday.

Build this one first. It earns the whole idea in a day and tells you whether a live page is worth the extra hour. The page is the upgrade for when three lines a week stops being enough.

What goes wrong

Five failure modes account for nearly every broken metrics setup.

The lapsed token that reads stale. A connected app's authorization expires, the schedule keeps firing, the call fails, and the run looks fine from outside while your dashboard shows last week's number forever. The flag-on-failure line from the pull prompt is the fix. A failed pull that surfaces beats a silent zero.

Credit burn from too fast a pull. A 5-minute schedule fires 288 times a day and bills for all 288, most writing a number that did not move. Revenue does not change every five minutes. Match the interval to the metric, and let conditional delivery handle "only ping me if it moved."

A browser session that breaks the pull. Login-gated sources are the fragile ones. A site logs you out, changes its layout, or throws a captcha, and the browser pull fails. Tell the automation to flag it, then re-sign-in through Zo's browser. Prefer a plugin or plain file over a browser pull wherever one exists.

Fuzzy "how's the business" asks. "How are we doing" has no truth condition, so Zo guesses what you meant. Ask for named numbers over a named window: "revenue and new signups this week versus last, Monday to Sunday" gives the same answer every time.

Assuming the dashboard acts on the numbers. It does not. Zo drafts and reports. It will not send an invoice, pause an ad, or email a customer off a metric unless you wire that yourself and drop the human gate, which you should never do for money-moving actions. It tells you; you decide.

Frequently asked questions

What is a live metrics dashboard?

A live metrics dashboard is a page that shows your current business numbers and updates itself without you touching it. In Zo it is a scheduled automation writing numbers to a file plus a page whose API route reads that file on every request. The data lives on your own server, no BI tool to rent.

How does the dashboard update itself automatically?

An automation runs on a schedule you set in plain English, pulls each number, and appends a dated row to a workspace file. A Zo Space page reads that file at request time, so it shows the newest row every time you open it. You never export or paste anything by hand.

Can I build a dashboard from a spreadsheet I already have?

Yes. Export the spreadsheet to CSV, drop it in your workspace, and Zo reads it directly in plain English with no setup. Point the dashboard page at that file, or have an automation append fresh rows. To ask the data questions instead of charting it, turn the spreadsheet into a database, the next article.

How do I pull a number from a dashboard that needs a login?

Sign into that dashboard once through Zo's browser, then tell the automation to open the page in the browser and read the number. Zo reuses your session. Once you are signed in there, Zo reaches for the browser on its own for that page. A plain read only returns a sign-in wall when you are not signed in at all. Browser pulls are slower and more fragile than a plugin or file.

Does this replace a real BI tool like Tableau?

For a solo operator or small team wanting a handful of numbers without a data team, yes. You lose session replay and drag-and-drop chart builders. You gain a data file you own, no monthly bill, and a summarizer you re-point with a sentence. Paid acquisition against a checkout funnel is where the heavy tool still wins.

How much does it cost to run?

Every scheduled run spends AI credits whether it notifies you or not, so cost is set by how often the automation fires, not by the page. A daily pull is cheap. A 5-minute pull is 288 runs a day. Pricing is at zo.computer/pricing. The page itself just reads a file, costing nothing to serve.

Put it to work

Open Zo, connect the tools this guide uses, and ask it to build the workflow with you.

Try Zo