Reviewed by Jonathan West · Updated Aug 10, 2026

How to Run a Script on a Schedule

You built something that works when you run it. Here is how to make it run at 8am every day without you.

Reviewed by Jonathan West · Updated Aug 10, 2026

To run a script on a schedule, put it on a machine that stays on, then give that machine a schedule to fire it. The schedule is usually written as a cron expression, a five-field line like 0 8 * * * that means 8am every day.

This is the step most people miss after they build something with AI help. The script works on your laptop. Your laptop sleeps. Nothing runs.

This guide covers where the code has to live, how to read and write a cron expression, the four realistic ways to fire it, the difference between a job that stores a result and a page that recomputes on load, and how you find out whether the run actually worked.


Where Does the Code Have to Live?

Your script has to live on a machine that stays awake, which almost never means your laptop. A scheduled job only fires if something is running at that moment to fire it.

Close the lid and the clock stops for your script. Sleep, a dead battery, a hotel wifi drop, or a restart all silently skip the run. You will not get an error, because nothing tried.

So the first move is moving the code somewhere always-on. That can be a cloud server you rent, a hosting platform that already runs your app, or a managed service that runs the job for you. All three are covered below.

  • Your laptop: fine for testing, unreliable for anything daily.
  • A rented server: always on, you keep it patched and alive.
  • Your existing host: if your app is already deployed, the scheduler often lives there too.
  • A managed service: you supply the job, the vendor supplies the machine.
Rule one: a schedule needs a machine that never sleeps. Everything else on this page assumes you have solved that.

Built something with AI that only runs when you run it? We will help you host it, set the schedule, and confirm it keeps updating without you.

Book a Consultation

How Do You Read a Cron Expression?

A cron expression is five values separated by spaces, and each value answers one question about when to run. Read them left to right: minute, hour, day of month, month, day of week.

An asterisk means every. A number means only that value. So 0 8 * * * reads as minute 0, hour 8, every day of the month, every month, every day of the week, which is 8:00 every morning.

Two more symbols do most of the remaining work. A comma lists values, a hyphen gives a range, and a slash sets a step. 0 9,17 * * * runs at 9am and 5pm. */15 * * * * runs every 15 minutes.

PositionFieldAllowed valuesIn 0 8 * * *
1Minute0-590 — on the hour
2Hour0-23, 24-hour clock8 — 8am
3Day of month1-31* — any date
4Month1-12* — any month
5Day of week0-6, Sunday is 0* — any weekday
Say it out loud in field order and the line decodes itself: minute, hour, date, month, weekday.

How Do You Write Business-day and First-of-month Schedules?

Business days are easy: put a range in the fifth field. 0 8 * * 1-5 runs at 8am Monday through Friday, because 1 is Monday and 5 is Friday.

The first business day of the month is the case cron cannot express. There is no symbol for the first weekday of a month, so no single line will do it.

The standard fix is to over-schedule and then filter inside the script. 0 8 1-3 * * fires at 8am on the 1st, 2nd, and 3rd of every month. Your script then checks the date and exits immediately unless today is the first business day. Leave the fifth field as * here — adding 1-5 would trigger the OR rule below and fire the job on every weekday of the month as well.

  • 0 8 * * * — 8am every day.
  • 0 8 * * 1-5 — 8am on business days only.
  • 0 8 1 * * — 8am on the 1st of every month, weekend or not.
  • 0 8 1-3 * * — the first-business-day pattern, with a guard in the script.
  • 0 9-17/2 * * 1-5 — every two hours during working hours, weekdays only.
The trap: if you restrict day of month AND day of week, cron runs when EITHER matches, not both. 0 8 1 * 1-5 fires on the 1st and on every weekday.

What Time Zone Does a Cron Job Use?

A cron job uses the clock of the machine it runs on, and most cloud servers are set to UTC. Your 8am job will fire at 8am UTC, which is the middle of the night in the United States.

Check the server clock before you trust a schedule, and set the time zone explicitly if the platform lets you. Daylight saving shifts catch people twice a year on the platforms that do not.

Test the expression before you deploy it. Paste it into crontab.guru and it prints the plain-English description of what your line means and the next times it will fire.

  • Confirm whether the runner uses UTC or a time zone you set.
  • Write the description in a comment so the next person can read it.
  • Check the next few fire times before you walk away.
  • Avoid scheduling on the hour if the job hits a busy shared API.

What Are the Four Ways to Actually Run It?

Four options cover almost every real case: a managed AI routine service, cron on a server, GitHub Actions on a schedule, and a serverless scheduler. Pick by what you already have running.

A managed AI routine service is the shortest path when the job needs judgment rather than fixed steps. You save a prompt, pick a cadence, and the vendor owns the machine. Claude Code Routines work this way, and we cover them in Claude Code Routines explained.

Server cron is the classic option and still the most flexible. You rent a small always-on box, add a line to the crontab, and your script runs with full access to files, shell, and installed tools. You also own uptime, patching, and everything that breaks at 3am. The full ops version of this lives in scheduling AI agents in the cloud.

GitHub Actions gives you a scheduler for free if your code already sits in a repository. Add a schedule trigger to a workflow file and the job runs on a hosted machine with no server to rent. Runs can start late under load, so keep it off hard deadlines.

A serverless scheduler suits jobs that fire an HTTP endpoint rather than run a whole environment. Google Cloud Scheduler and Amazon EventBridge Scheduler both take a cron expression and call your function or URL on time. If your app is already hosted on a platform like Render or Vercel, check its own scheduled-job feature first, because that is one less account to manage.

On Windows, the local equivalent is Task Scheduler, which can run a Python script daily with a wizard instead of a cron line. It is a fine way to learn the idea. It still stops when the machine sleeps, so move the job off the desktop once it matters.

CriteriaManaged AI routineServer cronGitHub ActionsServerless scheduler
SuitsJobs needing judgment or draftingFull control, custom toolsCode already in a repositoryCalling one endpoint on time
You manageThe promptThe whole serverA workflow fileA schedule and a function
Effort to startMinutesHoursUnder an hourUnder an hour
Watch out forVendor limits and capsPatching, uptime, silent stopsRuns starting lateTimeouts and cold starts
VerdictStart here for AI workChoose for controlChoose for free and simpleChoose for endpoint pings

Does It Refresh Constantly, or Only When I Open It?

A scheduled job runs at a set time and stores the result, so the page you open is showing a saved number; a live page computes the answer at the moment someone loads it. Which behaviour you get depends entirely on which of those two designs was built — they are not settings you toggle, they are different architectures.

Batch is the 8am pattern. The job wakes, pulls the data, does the work, and writes the output to a database, a file, or an email. When you open the page later, you are reading a saved result that is as old as the last run.

Live is the on-open pattern. Nothing happens until a visitor arrives, then your code fetches and computes right there. The number is current, the page is slower, and every visit costs you an API call.

Most business dashboards should be batch. Data that changes hourly does not need recomputing on every page view, and batch keeps costs flat no matter how many people look. Go live only when a stale number would be wrong in a way that matters. If the cost side is what you are weighing, our AI model cost calculator and the API key vs subscription guide show how per-call pricing adds up.

  • Batch: runs on a schedule, stores the result, page loads are fast and free.
  • Live: runs on page load, always current, costs scale with traffic.
  • Hybrid: batch the heavy work overnight, compute only the small live parts on open.
  • Tell your users: show the timestamp of the last run so nobody mistakes stale for broken.
If your page shows a number and you cannot say when it was calculated, you have not decided between batch and live yet.

How Do You Know Whether It Ran?

You know it ran by reading the logs, and you know it worked by checking the output. Those are two separate questions, and the second one is the one that bites.

Every runner keeps a record of each run with a start time, an end time, and an exit status. A green status means the job finished without crashing. It does not mean the job did anything useful, because a script that fetched nothing and wrote nothing still exits cleanly.

The scheduled routines we run across our own portfolio fail quietly far more often than they fail loudly, which is why we alert on silence rather than on errors. Have the job report a result you can measure, such as rows written or a file timestamp, and alert when that number is zero or the expected run never checked in.

For the deeper reliability setup, including health checks and rollback, see the reliability section of scheduling AI agents in the cloud.

  • Log the start, the end, and one number that proves work happened.
  • Alert on a missing run, not only on a failed one.
  • Watch the first several runs of any new schedule before you trust it.
  • Keep the last run timestamp somewhere a human sees it.

Frequently Asked Questions

  • It is a five-field line that tells a machine when to run something. The fields are minute, hour, day of month, month, and day of week, in that order. An asterisk means every, so 0 8 * * * means minute 0 of hour 8 on every date, which is 8am daily.
  • 0 8 * * 1-5 is the most common business one. It runs at 8:00 in the morning on Monday through Friday. Change the 8 to any hour from 0 to 23, and change 1-5 to * if you want weekends included.
  • Put the script somewhere that stays on, then attach a daily trigger to it. On a server, add a crontab line like 0 8 * * * that calls Python with the script path. On a hosting platform, use its scheduled-job feature. On a repository, add a schedule trigger to a workflow file.
  • Use Task Scheduler, the built-in Windows tool. Create a basic task, set it to daily, and point the action at your Python executable with the script as an argument. The job only fires while the machine is awake, so move it to a server once the result actually matters to someone.
  • Restrict the fifth field to 1-5. In cron, 0 is Sunday, 1 is Monday, and 5 is Friday, so 0 8 * * 1-5 covers the working week. Public holidays are not built in, so skip them with a check inside the script.
  • Cron cannot express it in one line. The usual approach is 0 8 1-3 * *, which fires on the 1st, 2nd, and 3rd of every month, plus a check at the top of the script that exits unless today is the first business day. Keep the fifth field as * — restricting both day of month and day of week makes cron fire when either matches, which would run the job every weekday too.
  • Yes, if the schedule lives on your computer. A sleeping laptop simply skips the run and gives you no error. That is why daily jobs belong on a server, a hosting platform, or a managed service that stays awake.
  • It depends on which of the two designs was built: a scheduled (batch) dashboard refreshes only at its set times, and a live dashboard recalculates every time you open it. A scheduled job updates the stored data at set times, so the page shows the last saved result. A live page recalculates on every load, which is current but slower and more expensive. Show the last-updated timestamp so the difference is visible.
  • The time zone of the machine running it, which is UTC on most cloud servers. Check the server clock before you trust the schedule, and set the time zone explicitly if the platform supports it.
  • Check the output, not the status. A green run means the script exited without crashing, which a script that did nothing also does. Log a number that proves work happened, such as rows written, and alert when a run is missing or that number is zero.

Got something built that only runs when you run it?

Book a free 30-minute AI workflow audit with Layer3 Labs. We will look at what you have built, pick the right place to host it, and set up the schedule so it updates on its own.

Book Your Free AI Workflow Audit