Updated June 10, 2026

How do I keep a Drafty canvas updated automatically?

Quick answer

Have Claude write a small refresh script — pull your data, render the canvas, push it — then schedule it with a plain local cron (the `drafty-cron` skill in the plugin sets this up). The cron re-runs the script on a timer with no Claude in the loop, so it costs nothing and the canvas stays current on its own. It pushes a new version only when the data actually changed.

A Drafty canvas is normally a snapshot — it shows what was true when it was published. To keep one current — a metrics dashboard, a funnel, a status board — you re-run the report and push a new version. Doing that by hand gets old fast, so you automate it.

The key idea: a refresh is mechanical. Query the data, render the canvas, push it — the same three steps every time, with no decision to make. So it shouldn't run through Claude at all. Claude writes the script once; a plain cron runs it forever.

Claude writes the refresh, once

Ask Claude to keep a canvas updated — for example, "refresh this dashboard from BigQuery every ten minutes." It writes a small script that:

  1. Pulls the data (a query, an API call — whatever the canvas shows).
  2. Renders a self-contained HTML canvas with the fresh numbers in it.
  3. Pushes it to the same link, but only when the data actually changed.

That last step matters: the script hashes the rendered output (ignoring the "generated at" line) and skips the push when nothing moved. That's what lets you run it often without filling your version history with no-op revisions.

A plain cron runs it, forever

The script is then scheduled with an ordinary operating-system cron — on macOS, a launchd job. The drafty-cron skill in the Claude Code plugin sets this up for you:

You only bring Claude back when the report itself needs to change — a new metric, a different chart, a bot pattern to filter. Refreshes are hands-off.

How often should it run?

As often as you want. Because each run is essentially free, every five minutes is fine. The only real costs are the data query — keep it cheap — and version history, which the push-only-if-changed guard already protects. For most dashboards, 5–15 minutes is plenty.

The one caveat

A local cron runs while your machine is awake. It survives reboots and logging out; it doesn't run while your laptop is powered off, and it catches up once on wake after sleeping. For most dashboards — something you glance at during the day — that's exactly enough. If you need it fresh while your laptop's closed, you'd host the loop in the cloud instead.

For the full walk-through of the pattern, see How to make a Drafty canvas live.

Read the full guide

Frequently asked

Does this use up Claude credits on every refresh?
No. The refresh is just a shell command on a timer — query, render, push. There's no model in the loop, so each run is free. Claude only does the one-time work of writing the script and installing the cron. Don't use `/loop` or `claude -p` for this; both re-invoke the model on every run.
Won't running it every few minutes flood my version history?
Not if the script pushes only when the data changed. The reference script hashes the rendered output (ignoring the "generated at" line) and skips the push when nothing moved — so a new version appears only when the numbers actually change, even on a five-minute schedule.
How aggressive can the schedule be?
As aggressive as you like — every five minutes is fine, because each run is essentially free. Match the interval to how fast your data actually moves; most dashboards are happy at 5–15 minutes.
Does it keep running when my laptop is closed?
A local cron runs while your machine is awake — it survives reboots and logging out, but not a powered-off laptop, and it catches up once on wake after sleeping. For always-on refresh while your laptop is closed, you'd host the loop in the cloud instead (same script, different runner).

Related