2026-08-25 · Guide
Schedules vs Event Triggers: Building Routines That Do Not Fail Silently
A routine that stopped firing looks exactly like a routine with nothing to report. Both produce silence. You will notice the difference somewhere between four days and never, and which one it is depends entirely on choices you make before you switch the thing on.
This is about the object model first, because the constraints on a Grok Bot routine are specific and published, and they change what a sensible design looks like.
What a routine actually is
The documented shape, from skills, routines and automations:
A routine assigns a workflow to one bot. Not to a team, not to a pool, to one bot. There is a ceiling of 50 routines per bot, and the app keeps the 20 most recent run records per routine. Deleting a bot also deletes its routines, and nothing is stored at team level.
Four consequences fall straight out of that, and each one changes a design decision.
There is no single place to see your schedule. Because routines belong to bots and nothing is team-level, a five bot setup means configuring and checking scheduling five times, in five places. If you want one view of when everything runs, you have to keep it yourself, and you should, because you will otherwise discover the overlap by reading five identical notifications at 09:00.
The bot is the unit of deletion. Delete a bot to tidy up and you have deleted its routines with it. There is no orphaned-routine state to recover from, which is clean, and no warning that you are about to lose a schedule you spent an afternoon on, which is not.
Deleting a bot is the wrong kind of cleanup. This is the sharp edge. The routines go, but the shared computer keeps its files and browser sessions: deleting a bot does not remove them (approvals, security and privacy). So the delete removes the part you built and leaves the part you were worried about. If your goal was to revoke access, deleting the bot is not the action that does it.
Your phone is a kill switch, not a console. On iPhone you can pause and resume routines only. Editing, history, testing and deleting all need a desktop (mobile). That is a reasonable division of labour, but plan around it: if you are away from a laptop, your only available response to a misbehaving routine is to stop it. Which is an argument for making every routine safe to stop at any point, and for never scheduling something whose half-completed state is worse than not running.
Schedule triggers and event triggers, side by side
The choice is not really "which is better". It is whether the work has a clock or a cause.
A schedule fires whether or not anything happened. That is a feature for anything that must exist by a certain time regardless of activity, and a waste everywhere else. An event fires when reality changed, so it never runs for nothing and never runs at a predictable time.
| Trigger | Good fit | How it fails, and what you will see |
|---|---|---|
| Daily schedule | Morning briefs, overnight change reports | Fires in a timezone you did not intend, so it lands at 3am and you stop reading it |
| Weekday schedule | Standups, pipeline reviews, working-week work | Runs on public holidays and while you are away, producing output nobody reads |
| Weekly schedule | Reconciliation, planning, metric reviews | Too coarse to warn you, so it becomes a post-mortem of a problem that started Tuesday |
| Monthly schedule | Invoicing, access reviews, subscription audits | Collides with every other system's month-end batch, so data is slow and unsettled |
| Event trigger | Inbound mail, new PR, form submission | The matching rule silently stops matching after a label, channel, or form is renamed. No error, just nothing |
| Manual run | New routines, irregular but repeated work | Never gets run, and the bot decays into a bookmark you feel guilty about |
| Tight polling interval | Almost nothing | Overlapping runs, duplicated actions, rate limits, and burn on runs that find nothing |
The event trigger row is the one worth staring at. Its failure mode produces no error and no output, which is indistinguishable from a quiet week. Every event trigger you rely on needs a companion check, and there is a pattern for that further down.
For the mechanics of picking between trigger types, and cron-style thinking without cron syntax, there is a fuller treatment in the Grok Bot scheduling guide. This article picks up where trigger choice ends.
Timezone traps that survive a correct schedule
Three of these, briefly, because they are the most common cause of a routine that fired perfectly and still produced the wrong thing.
The routine's timezone and your timezone are different settings. Name the intended timezone in the charter text as well as in the schedule, so that when you read the charter in November you can tell what the intent was rather than inferring it from a dropdown.
Daylight saving moves your local clock, and the region you coordinate with does not switch on the same date. For a few weeks each spring and autumn, a routine anchored to your clock is an hour away from the person it serves. Anchor time-critical runs to the timezone of whoever consumes the output.
The third one silently corrupts data rather than timing. A routine that asks a connected tool for "yesterday" gets that tool's definition of yesterday, which may be UTC, or a company default, or a choice someone made years ago. Write explicit date ranges into the charter and require the bot to state the range it used in every report. An invisible mismatch becomes a line you can read.
One bot, many routines, and the overlap problem
Because routines attach to a single bot, all of a bot's routines share that bot. The documentation describes each bot as having its own screen on a shared computer, which is a work surface rather than a second machine. Our advice is to plan as though a bot does one thing at a time and treat simultaneous routines as contention rather than parallelism. That is the assumption that fails safely; the opposite assumption fails at 09:00 on a Monday.
Three rules follow.
Never schedule two routines on the same bot at the same minute. Stagger by at least the length of the longer job, plus margin for a slow run. Fifteen minutes of buffer costs nothing.
If two workflows genuinely must run at once, that is a second bot. But remember what a second bot is and is not: it is a second screen and a second set of routines, sharing the same computer, the same browser sessions, and the same credentials. The documentation is direct that separate bots are not a security boundary, so use the split for throughput, never for isolation.
Treat 50 routines per bot as a ceiling you never approach. Past roughly eight per bot you cannot hold the schedule in your head, and there is no team-level view to hold it for you. A bot with thirty routines is not an automation setup, it is an outage waiting for a reason.
The stagger is easier when each bot has one clear job. Chief of Staff Briefing runs early and reads, never sending, scheduling, or acting externally without approval. Standup Scribe runs later and writes only to your own direct message, never a shared channel. Two bots, two slots, two boundaries, and no contention.
What silent failure looks like, and the watcher that catches it
Start with the diagnosis, because two very different problems present identically.
A failed run means the trigger fired and the work broke: an expired authorisation, a redesigned page, a login challenge, an export that timed out. The run record exists and it says so.
No run at all means the trigger never fired: the routine is disabled, the schedule is wrong, the bot was deleted, or access is paused. There is no run record, and nothing generated a notification about the absence of an event.
Plan for the least forgiving version of both: the run stops, nothing retries, and no message arrives. That turns "silent success" into a genuinely dangerous default, and it produces the first rule.
The heartbeat. Require a report on every single run, including runs where nothing happened. One line saying nothing changed costs you two seconds a day and converts silence from ambiguous into meaningful. Without it, you cannot distinguish a healthy quiet week from a routine that died on the 4th.
The heartbeat handles failed runs. It cannot handle no run at all, because a routine that does not execute cannot report that it did not execute. There is no clever charter clause that fixes this. Something outside the routine has to notice the absence.
The watcher. A second routine, on a different bot, whose only job is to read the record the first routine should have written and complain when it is stale. Put it on a bot you are not going to delete, since deleting a bot takes its routines with it, and the watcher is the last thing you want to lose quietly.
// HEARTBEAT: add to every scheduled routine
At the end of every run, append one line to /state/heartbeat.md:
<routine name> | <ISO timestamp with offset> | ok | <items processed>
If the run found nothing to do, still append the line with 0 items.
If a step failed, append the line with "failed" and the step name.
Always send me the report, even when every section of it is empty.
State the exact date range you covered at the bottom of the report.
// WATCHER: one routine on a different bot, daily at 09:15 Europe/London
Read /state/expected.md, which lists each routine and its cadence.
Read /state/heartbeat.md.
For each expected routine, compare its newest timestamp against its
cadence. If a routine has not written a line within its cadence plus two
hours, report it: the routine name, its cadence, and how long it has been
silent. If everything is current, reply with one line saying so.
// RETRY CEILING
Two attempts at any single step, then stop and report. Never a third.
Never look for another route to the same result.
// WHERE YOU STOP
Never restart, re-run, edit, enable, pause, or delete a routine or a bot.
Never modify /state/heartbeat.md. You read it, you do not write it.
Report the gap and wait for me.
The boundary on the watcher is not decoration. A watcher that can restart things is a watcher that can restart a broken thing repeatedly, at which point you have built an automated retry loop with no ceiling and given it a schedule. Detection and remediation are different jobs, and only one of them is safe to leave running.
Twenty run records is a short evidence window
The app keeps the 20 most recent run records per routine. Convert that into time and it stops sounding generous.
| Cadence | 20 records reaches back about | What that means when something breaks |
|---|---|---|
| Every 15 minutes | 5 hours | An overnight failure is gone before you wake up |
| Hourly | Under a day | You get one working day to notice and investigate |
| Every 4 hours | 3 days | A Friday problem is unreadable by Monday afternoon |
| Twice a day | 10 days | Enough to spot a pattern, not enough to date its start |
| Daily | 3 weeks | Workable, and the shortest cadence that really is |
| Weekdays only | 4 weeks | Comfortable for most reporting work |
| Weekly | 5 months | The only cadence with genuine history |
Read the first row again next to the earlier point about tight intervals. The fastest routines have the least forensic history, which is precisely backwards from what you need, because fast routines are also the ones that can do the most damage before anyone looks.
Now combine that with a second documented gap: an audit view of bot actions does not exist yet (teams and enterprises). Your evidence window is short and there is no system of record behind it.
Two design consequences, and they are the reason this section exists.
The charter must make the bot report, not rely on history. Anything you will want to compare across weeks has to be written by the bot into somewhere durable at the time, because it will not be reconstructable later. That is the heartbeat file above, and it is also why the run report should always state its date range and its counts.
The ceiling matters more than usual. When you cannot reconstruct what happened, the useful question shifts from "what did it do" to "what was it ever able to do". That is exactly the question a boundary answers, and it is why the boundaries guide argues for writing the line before you write the workflow. A bot that can only draft has a knowable worst case even with zero surviving history. A bot that can send does not.
If a routine has already gone quiet and you are trying to work out why, the symptom-by-symptom list is in the troubleshooting reference.
Designing around the ten minute demonstration cap
Teach by demonstration is the fastest way to get a workflow into a bot, and it comes with a specific set of limits: it records visible computer interaction for up to ten minutes, captures no microphone audio, covers browser workflows only, is unavailable on iPhone, and produces a draft skill rather than a finished one.
Ten minutes is not a recording quota to spend. It is a design constraint on what a single teachable unit can be, and the right response is to decompose rather than to rush.
Do the setup before you press record. Log in, close the notification banner, get to the page where the actual work starts. Every second of navigation you record is a second of workflow you are not recording, and login flows are the least reusable thing you could capture.
Start each segment from a URL, not from a click path. A segment that begins with "go to this address" can be replayed from a known state. A segment that begins with "click where the last one stopped" is only valid if the previous segment ended exactly as expected, which is the assumption that breaks first.
End each segment at a durable artifact. A saved record, an applied filter, a downloaded export, a submitted form. If a segment ends mid-form, its output is a screen state, and screen states do not survive the gap between runs.
Budget for narration you cannot give. No microphone audio is captured, so every "and this is why we skip the archived ones" you would have said out loud has to be typed into the draft afterwards. Reserve real time for that. The draft is the raw material, and editing it into something specific is the actual work.
Record on a desktop. The feature is not available on iPhone, and neither is editing the result.
A weekly reconciliation that takes forty minutes by hand becomes four segments: pull the export, reconcile the flagged rows, update the tracker, write the summary. Each is under ten minutes because each ends where a real document was saved. Those become separate routines chained by artifact, or one workflow assembled from four drafts, and either way the failure of segment three tells you exactly which artifact is missing.
That decomposition has a second benefit worth naming: shorter units are easier to bound. A four minute segment that only reads has an obvious boundary. A forty minute recording that touches six systems has no clean line anywhere in it, which is usually a sign it should never have been one routine. Marketing Calendar Sync is a good shape to copy here, touching only your local calendar and never editing the shared source, and Inbox Triage never sends, so every draft waits for approval.
Before you switch anything on
Five checks, in order, and none of them take long.
Run it manually for a week first and read every output, because scheduling too early converts "is this any good" into "this arrives automatically and I skim it". A test run is a real run, so if the routine can send or post, it will send or post during your test. Write the boundary before the first test, not after. Add the heartbeat line to the charter on day one, since retrofitting it means your evidence starts from the retrofit. And put the watcher on a bot you will not delete.
Then, once it is live, the only ongoing habit that matters: if a routine has gone quiet, check whether the run history shows a failed run or no run at all before you change anything. Those two diagnoses point at completely different fixes, and with 20 records to work from, you may only get one chance to read the evidence.
Frequently Asked Questions
How many routines can one Grok Bot have?
The documented ceiling is 50 routines per bot, and the app retains the 20 most recent run records for each routine. In practice the useful limit is far lower. Because routines belong to individual bots and nothing is stored at team level, there is no single view of everything scheduled across your setup, so you have to hold the picture yourself. Past roughly eight routines on one bot that becomes unrealistic, and overlapping start times start producing duplicated work and contention you will only notice from the output.
What happens to routines when you delete a Grok Bot?
They are deleted with it. Routines are owned by a single bot and nothing survives at team level, so removing the bot removes its schedule permanently. Importantly, this is not the cleanup people expect it to be: the documentation states that deleting a bot does not remove files or browser sessions on the shared computer. You lose the automation you built and keep the signed-in sessions you may have been trying to revoke. If revoking access is the goal, sign out of the services and rotate the credentials instead.
How do you tell a failed routine from a routine with nothing to report?
Make every run report, including runs where nothing happened, so silence stops being ambiguous. That distinguishes a healthy quiet week from a broken routine, but it cannot catch a routine that never fired, since a run that does not happen cannot send anything. For that you need a second routine on a different bot that reads a heartbeat file the first routine writes to and raises a flag when the newest entry is older than the expected cadence. Give that watcher a strict boundary: it reports gaps and never restarts anything.
How do you teach a workflow that takes longer than ten minutes?
Split it into segments that each finish inside the cap, and choose the split points carefully. Do all the logging in and navigation before you start recording, begin each segment from a specific address rather than from wherever the previous one left off, and end each segment at something durable like a saved record or a downloaded export. That way a later segment can start from a known state instead of an assumed one. Since no microphone audio is captured, budget time to type the explanation into the resulting draft.