TutorialNov 7, 20263 min read

How to Run a Python Script 24/7 on a VPS

Four ways to keep a Python script running around the clock on a server: tmux for testing, systemd for long-running scripts, cron or timers for scheduled jobs, and Task Scheduler on a Windows VPS. With logs and restarts.

Short answer: rent a small Linux VPS, copy the script over, and run it as a systemd service if it should run forever, or with cron if it should run on a schedule. Both survive logouts, crashes and reboots. A server with 1 vCPU and 1 GB RAM costs $3.90 a month; scrapers with a headless browser or data work want 2–6 GB.

python script.py in an SSH window stops the moment the window closes. nohup and & survive that, but not a crash or a reboot, and you lose track of the logs. Here are the ways that hold up, from quick test to production.

01Pick the Right Tool

Your scriptUseRestarts after crashSurvives reboot
Testing, watching it livetmuxNoNo
Runs forever (bot, listener, monitor)systemd serviceYesYes
Runs every X minutes or dailycron or systemd timerNext runYes
Needs Windows or a visible browserWindows VPS + Task SchedulerConfigurableYes

02Get the Script onto the Server

On Ubuntu 24.04 or Debian 12, logged in as root:

bash
adduser --disabled-password --gecos "" app
apt update && apt install -y python3-venv
su - app
mkdir myscript && cd myscript      # copy files here with scp or git clone
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

Ubuntu and Debian don't let pip install into the system Python any more; the virtual environment is the clean way around it. Keep API keys in a file like /home/app/app.env (chmod 600) and read them with os.environ.

03tmux: Quick and Visible

bash
apt install -y tmux        # as root
tmux new -s script         # as the app user
.venv/bin/python script.py

Press Ctrl+B, then D to detach; the script keeps running after you log out. tmux attach -t script brings it back. Good for testing; it won't restart after a crash or a reboot.

04systemd: For Scripts That Should Never Stop

Create /etc/systemd/system/myscript.service as root:

ini
[Unit]
Description=My Python script
After=network-online.target
Wants=network-online.target

[Service]
User=app
WorkingDirectory=/home/app/myscript
EnvironmentFile=/home/app/app.env
ExecStart=/home/app/myscript/.venv/bin/python -u script.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
bash
systemctl daemon-reload
systemctl enable --now myscript
journalctl -u myscript -f

The -u flag stops Python from buffering output, so print() shows up in the log right away.

05cron: For Scheduled Scripts

If the script does a job and exits, let cron start it. As the app user, crontab -e and add:

cron
# every 5 minutes
*/5 * * * * cd /home/app/myscript && .venv/bin/python job.py >> job.log 2>&1
# every day at 06:30 server time
30 6 * * * cd /home/app/myscript && .venv/bin/python report.py >> report.log 2>&1

That beats a while True: ... sleep(300) loop: a crash only skips one run, and memory leaks don't build up. Server time is UTC unless you change it with timedatectl set-timezone.

06On a Windows VPS

Some scripts need Windows: they drive a Windows program, use pywinauto, or run Selenium with a visible Chrome. On a Windows RDP:

  1. 1Install Python from python.org and tick "Add python.exe to PATH".
  2. 2Open Task Scheduler and choose Create Task.
  3. 3Trigger: "At startup", or a schedule.
  4. 4Action: program C:\path\to\.venv\Scripts\python.exe, argument script.py, start in the script's folder.
  5. 5Settings: "If the task fails, restart every 1 minute", and untick "Stop the task if it runs longer than".

Choose Run whether user is logged on or not for scripts without a window. Scripts that need the desktop, like a visible browser, must run in a signed-in session: close the Remote Desktop window instead of signing out, and they keep going.

07Which Server

Nano1 vCPU · 1 GB · 10 GB NVMe$3.90/mobilled monthlyBuy
Most popularSpark1 vCPU · 2 GB · 20 GB NVMe$6.50/mobilled monthlyBuy
Pulse2 vCPU · 2 GB · 20 GB NVMe$6.50/mobilled monthlyBuy
Surge2 vCPU · 6 GB · 40 GB NVMe$13.00/mobilled monthlyBuy
Storm6 vCPU · 10 GB · 40 GB NVMe$26.00/mobilled monthlyBuy
Apex6 vCPU · 10 GB · 80 GB NVMe$39.00/mobilled monthlyBuy

Full root SSH access · NVMe storage · DDoS protection · No setup fee

  • $3.90 (1 GB RAM): API pollers, alerts, small bots, cron jobs
  • $6.50 (2 GB RAM): scripts with pandas, a database, or Playwright and headless Chromium
  • $13 (6 GB RAM): several browsers at once, larger data jobs, or a Windows VPS

For a quick test, tmux. For anything that should keep running, a systemd service.

  • run python script 24/7
  • keep python script running
  • python script on vps
  • run script on server
  • python systemd service
  • host python script

Keep reading

All articles