Skip to content

Set and change a refresh schedule

Pick a cadence and an anchor time for a dashboard, understand when a run actually fires, and know what happens after a failed run.

A published dashboard re-runs its own SQL on the cadence you set, with no AI in the loop. This page is how to set that cadence, change it, and read what happens afterwards.

Any non-manual cadence needs a paid plan

Arming an automatic schedule is refused on a free plan with a paid plan is required to schedule automatic refresh. See what is gated.

Setting a schedule back to manual is always allowed, on any plan.

Two places to set it

WhereWhat it can set
The Schedules page at dashies.xyz/app/schedulesEverything, including the sub-hourly cadences.
Your AI tool, via set_refresh_scheduleEverything except sub-hourly.

Your AI can also set the coarse cadence at publish time, in the spec's source.schedule. That takes manual, hourly, daily, weekly, or monthly, and you refine the exact timing afterwards.

Sub-hourly is a web-app-only setting

The set_refresh_schedule tool takes no sub-hour argument, so an AI cannot set every 15 or 30 minutes however confidently it offers to. Use the Schedules page.

Cadences, intervals, and anchors

CadenceInterval allowedAnchor
manualnonenone. It runs only when triggered.
Sub-hourlyevery 15 or 30 minutesnone. Runs on an absolute UTC grid.
hourlyevery 1, 2, 3, 4, 6, 8, or 12 hoursoptional hour, which then needs a time zone
dailyevery 1 to 30 daysoptional hour and time zone
weeklyevery 1 to 4 weeksday of week, hour, and time zone: all three or none
monthlyevery 1 to 12 monthsday of month, hour, and time zone: all three or none

The model behind this table is in cadences and intervals.

Anchor values:

  • Hour is 0 to 23.
  • Day of week is 0 to 6, with 0 meaning Sunday.
  • Day of month is 1 to 28.
  • Time zone must be a real IANA zone name, such as America/New_York.

Three of those constraints surprise people, so here is why each exists:

  • Hourly takes only divisors of 24. "Every 5 hours" is rejected, because a non-divisor drifts across the daily hour grid instead of repeating cleanly.
  • Day of month stops at 28. If you could ask for the 31st, February would silently skip. The clamp guarantees every month has the day you picked.
  • A sub-hourly schedule takes no anchor at all. It runs on an absolute UTC minute grid, at :00/:15/:30/:45 or :00/:30, which makes it immune to time zones and daylight saving by construction. It is also personal dashboards only today.

When a run actually fires

The displayed next run is the nominal time. Runs are claimed on a grid, and each dashboard carries a small fixed offset so that thousands of dashboards sharing an 09:00 anchor do not all fire in the same instant.

The practical consequence, worth knowing before you file a bug:

  • An anchored schedule fires within roughly 30 minutes of its nominal time.
  • A sub-hourly schedule is tighter, within a few minutes.
  • A dashboard sitting slightly past its displayed next run is normal, not late.

The offset is never shown, because it is not a property of your schedule. See the precision you actually get.

Daylight saving

An anchored schedule keeps its local wall-clock time across a transition. Daily 09:00 America/New_York stays 09:00 local; it does not drift to 08:00 or 10:00.

On the transition day itself, the real gap between two daily runs is 23 or 25 hours. A wall time that does not exist in spring, or happens twice in autumn, is normalized rather than lost or doubled. The next-run time the app shows and the time the run actually fires agree across the boundary.

Sub-hourly and unanchored hourly schedules are unaffected, because they are absolute instants. The policy in full: daylight saving, and anchors and time zones.

Running one now

The Schedules page has a Run now control on every dashboard.

Your AI can only trigger personal dashboards

The trigger_refresh tool is personal-only today:

Triggering a refresh on demand isn't available for workspace dashboards yet - it works on personal dashboards only.

Use Run now in the web app for a workspace dashboard.

On-demand refresh needs a paid plan, and who pays differs by scope

For a personal dashboard the payer is you:

{ "ok": false, "error": "Refreshing on demand requires a paid plan.", "code": "tier_required" }

For a workspace dashboard the payer is whoever connected the data source, who may be someone else entirely:

{ "ok": false, "error": "This dashboard's data source is on a plan that no longer includes refresh. The member who connected it needs an active paid plan.", "code": "tier_required" }

If you hit the second one, upgrading your own plan will not clear it. Find the member who created that data source.

Repeat triggers within 60 seconds of a previous attempt short-circuit and report back that they were coalesced, unless the last attempt failed. A pipeline retrying seconds after a failure genuinely re-runs, because the data is still stale.

After a failed run

A failed run does not strand a dashboard, and it does not retry at full rate either.

  • Retries back off at 5 minutes, then 10, 20, 40, 80, doubling until they cap at one full period of that dashboard's own cadence. A permanently broken daily dashboard retries about once a day rather than 96 times.
  • On the next success, the failure count resets and the schedule re-anchors normally.
  • In the UI a failing schedule reads Retrying with the actual retry time, rather than a red Failed sitting beside a blue Due now.

Pausing or archiving the dashboard is how you stop the retries.

Failure alert emails

You get an email once a dashboard has failed a chosen number of times in a row. Set the threshold in Settings, then Alerts: the options are 2, 3, or 5, and the default is 3.

  • One email per outage, not one per failed run, plus a reminder roughly every 7 days while it stays broken. A monthly dashboard reminds every 30 days.
  • One recovery email on the next run that records a real success.
  • Alerts can be muted per dashboard from the schedule dialog. A muted dashboard never alerts, and unmuting mid-outage does not retroactively fire.
  • A free plan never receives the email, but the outage is still tracked, so upgrading during one alerts on the next failure rather than swallowing it.

If your plan lapses

Refresh does not fail and nothing is deleted. Each due run records a skipped run with the reason tier_lapsed, the schedule is preserved, you get one notice email, and re-subscribing resumes it automatically.

A tier_lapsed skip does not send a failure alert, and it does not count as the recovery that closes an outage.

Check it worked

  1. Open dashies.xyz/app/schedules. Your dashboard shows the cadence you set and a next run time.
  2. Wait for that time to pass, plus the half hour described above, then open the History tab. A run should be listed.
  3. A successful run marked No change is a healthy result, not a failure. It means the SQL re-ran and produced byte-identical numbers.
  4. If nothing appears at all, check the dashboard is actually refreshable: ask your AI for its refresh status. A dashboard with no schedule and no next run was published without a working refresh manifest, which is usually a data source scope problem. See Work as a team.