How to Schedule Python Scripts to Run Daily (Windows, Mac, Linux)

· 7 min read

Introduction

You wrote a Python script that sends a daily report, backs up files, or checks for price drops. It works perfectly — but only when you remember to run it manually.

That is where scheduling comes in.

Instead of opening a terminal every day and running the script yourself, you can let your computer do it automatically. Whether you are on Windows, macOS, or Linux, there are built-in tools that can run Python scripts on a fixed schedule.

In this guide, you will learn three common approaches:

  • Windows Task Scheduler
  • Linux/macOS cron jobs
  • The Python schedule library

You will also learn which option makes the most sense depending on your setup and use case.

All examples are tested on Python 3.12.


Option 1: Windows Task Scheduler

If you use Windows, the easiest and most reliable solution is Task Scheduler. It is built into Windows and requires no additional installation.

Step 1: Open Task Scheduler

Open the Windows search bar, type Task Scheduler, and open the application. On the right-hand side, click Create Basic Task.

Step 2: Name the Task

Give your task a descriptive name:

Daily Python Report
Nightly Backup
Price Tracker

Click Next.

Step 3: Choose a Trigger

Choose when the task should run:

  • Daily — runs every day at a set time
  • Weekly — runs on specific days
  • At startup — runs when Windows starts
  • At log on — runs when you log in

For most automation scripts, Daily at a fixed time is the most common choice.

Step 4: Set the Action

Select Start a program, then fill in two fields.

Program/script — the full path to python.exe. Find it by running:

where python

Example output:

C:\Python312\python.exe

Use that full path in the Program/script field.

Add arguments — the full path to your script:

C:\Users\YourName\scripts\report.py

Step 5: Test the Task

Right-click the task in Task Scheduler and select Run. Check whether the script executed correctly. The History tab shows execution records and any errors.

Important Tips

Always use absolute paths. Task Scheduler does not know your working directory, so relative paths like open("data.txt") will fail silently.

Use __file__ to locate files reliably. Instead of hardcoding paths, build them relative to the script itself:

from pathlib import Path

BASE_DIR = Path(__file__).parent
log_file = BASE_DIR / "run.log"
data_file = BASE_DIR / "data.txt"

This works correctly regardless of where Task Scheduler launches the script from.

Point to the correct Python interpreter. If your script uses a virtual environment, use the Python executable inside that environment:

C:\project\venv\Scripts\python.exe

Add logging to verify execution. Without logging, it is hard to know whether your scheduled script actually ran. A simple log entry helps:

from datetime import datetime
from pathlib import Path

BASE_DIR = Path(__file__).parent
log_file = BASE_DIR / "run.log"

with open(log_file, "a") as f:
    f.write(f"Script ran at {datetime.now()}\n")

Check this log file after the first scheduled run to confirm everything is working.


Option 2: cron (Linux / macOS)

cron is the standard task scheduler on Linux and macOS. It is lightweight, reliable, and available on virtually every Unix-based system.

Cron Syntax

Each cron job follows this format:

* * * * * command
│ │ │ │ │
│ │ │ │ └─ Day of week (0-6, Sunday = 0)
│ │ │ └─── Month (1-12)
│ │ └───── Day of month (1-31)
│ └─────── Hour (0-23)
└───────── Minute (0-59)

Common schedule expressions:

ScheduleExpression
Every day at 8 AM0 8 * * *
Every hour0 * * * *
Every 15 minutes*/15 * * * *
Every Monday at 9 AM0 9 * * 1
First day of every month0 8 1 * *

Creating a Cron Job

Open the cron editor:

crontab -e

Add a line for your script:

0 8 * * * /usr/bin/python3 /home/user/scripts/report.py

Save and exit. View existing jobs with:

crontab -l

Example output:

0 8 * * * /usr/bin/python3 /home/user/scripts/report.py

Important Tips

Use absolute paths. The cron environment has a minimal PATH that differs from your interactive shell. Always use full paths for both the Python executable and your script.

Use the virtual environment Python if applicable. If your script depends on packages installed in a virtual environment, point directly to that Python executable:

0 8 * * * /home/user/project/venv/bin/python /home/user/project/report.py

Redirect output to a log file. By default, cron discards all output. Redirect both stdout and stderr to a file so you can debug failures:

0 8 * * * /usr/bin/python3 /home/user/script.py >> /home/user/cron.log 2>&1

Check file permissions. If cron fails silently, make sure the script is executable:

chmod +x script.py

Option 3: Python schedule Library

The schedule library is a pure Python solution that works identically on Windows, macOS, and Linux — with no system configuration required.

Install it with pip:

pip install schedule

Basic usage:

import schedule
import time

def send_report():
    print("Sending daily report...")

def backup_files():
    print("Running backup...")

# Schedule different tasks at different times
schedule.every().day.at("08:00").do(send_report)
schedule.every().monday.at("09:00").do(backup_files)
schedule.every(30).minutes.do(send_report)

# Keep the script running
while True:
    schedule.run_pending()
    time.sleep(60)

Expected output (when a scheduled time is reached):

Sending daily report...

Advantages:

  • Cross-platform — identical behavior on all operating systems
  • Easy to read — the schedule is defined in plain Python
  • Beginner-friendly — no system configuration needed
  • Flexible — combine multiple tasks in one script

Disadvantages:

  • The script must stay running continuously
  • If the machine reboots or the script crashes, the schedule stops
  • Less reliable than OS-level schedulers for critical production tasks

The schedule library is best suited for development environments, personal automation, or situations where you want a self-contained Python-only solution.


Which Option Should You Use?

SituationBest Option
Windows desktop automationTask Scheduler
Linux or macOS serverscron
Cross-platform, Python-only setupschedule library
Complex workflows with retriesAPScheduler or Celery

For most personal automation projects on Windows, Task Scheduler is the simplest choice. For server deployments on Linux, cron is the standard. The schedule library works well when you want to keep everything in Python without touching system configuration.


Common Issues and Fixes

Script Does Not Run

The most common cause is using relative paths. Task Scheduler and cron both run scripts from a different working directory than your terminal. Use absolute paths everywhere, or use __file__ to build paths relative to the script itself.

Script Runs But Results Are Wrong

This is usually an environment mismatch. The scheduled environment may use a different Python version or lack packages your script needs. Verify which Python is being used:

# Linux/macOS
which python3

# Windows
where python

If your script uses a virtual environment, make sure the scheduled task points to the Python executable inside that virtual environment, not the system Python.

cron Job Never Runs

Check the system log to see whether cron attempted to run the job:

grep CRON /var/log/syslog

Common causes: incorrect cron syntax, wrong Python path, or insufficient file permissions.

Task Scheduler Errors

Open the History tab in Task Scheduler to see the last run status and any error codes. For more detail, check Event Viewer under Windows Logs → Application.


Wrap-Up

Scheduling Python scripts turns one-time tools into reliable automation systems that run in the background without any manual effort.

For most setups: Windows users should start with Task Scheduler, Linux and macOS users should use cron, and anyone who wants a Python-only cross-platform solution should use the schedule library.

Scheduling becomes especially useful when combined with other automation scripts. For example, you can schedule the Python email automation script to send a daily report automatically, or run the file renaming script every night to organize your downloads folder.