Publishing YouTube videos on a schedule sounds trivial until you actually try to sustain it. Recording, editing, rendering, uploading, setting metadata -- each step has friction. Cron-based scheduling eliminates the timing friction entirely. You batch your production work whenever it suits you, and cron handles the "when does this go live" part with zero manual intervention.

The Core Idea: Separate Production From Publishing

Most creators conflate making a video with publishing it. These are two different problems. Production is creative work that happens in bursts. Publishing is a mechanical task that should happen on a clock. Cron is the clock.

The workflow looks like this: you produce videos throughout the week, and each finished video lands in a /ready directory with its metadata (title, description, tags, thumbnail) stored in a sidecar JSON file. A cron job runs at your scheduled publish time, picks the next video from the queue, and uploads it.

Setting Up the Cron Job

# Edit crontab
crontab -e

# Publish one video every day at 9:00 AM UTC
0 9 * * * /usr/bin/node /opt/vidno/publish.js >> /var/log/vidno-publish.log 2>&1

# Publish Mon/Wed/Fri at 2:00 PM UTC
0 14 * * 1,3,5 /usr/bin/node /opt/vidno/publish.js >> /var/log/vidno-publish.log 2>&1

Always use absolute paths in crontab. Cron runs with a minimal environment -- your PATH, NODE_PATH, and environment variables from .bashrc are not loaded. Either hardcode paths or source your env file at the top of the script.

Stop editing. Start shipping.

VidNo turns your coding sessions into YouTube videos — scripted, edited, thumbnailed, and uploaded. Shorts included. One command.

Try VidNo Free

The Publish Script

The publish script needs to do four things:

  1. Check the ready queue for the next video
  2. Read the metadata sidecar file
  3. Upload via YouTube Data API v3
  4. Move the published video to an archive directory

Keep a publish-order.txt file or simply sort by filename with embedded dates. I prefer embedding the intended publish date in the filename: 2026-03-28_react-hooks.mp4. The script checks if today's date matches, uploads it, and skips if no video is scheduled for today.

Handling Failures

YouTube API uploads can fail for several reasons: quota exhaustion, expired OAuth tokens, network timeouts. Your publish script needs retry logic:

  • On quota exhaustion: log and retry next cron cycle (quota resets at midnight Pacific)
  • On auth failure: refresh the token automatically using the stored refresh token
  • On network error: retry up to 3 times with exponential backoff

Combining With a Processing Pipeline

The real power emerges when you chain two cron jobs. The first one processes raw recordings overnight:

# Process raw recordings at 2 AM
0 2 * * * /usr/bin/node /opt/vidno/process-queue.js

# Publish finished video at 9 AM
0 9 * * * /usr/bin/node /opt/vidno/publish.js

Your raw recordings go into /inbox, get processed into /ready overnight, and publish the next morning. You could record on Monday, and Tuesday through Friday videos are processed and published without you touching anything.

Systemd Timers as an Alternative

If you want better logging, dependency management, and failure notifications, consider systemd timers instead of cron. They integrate with journald for structured logs and can send email on failure via OnFailure directives. The tradeoff is more configuration files, but the reliability is worth it for production publishing workflows.

A local-first pipeline like VidNo pairs naturally with cron because every step runs on the same machine. There is no cloud API to poll, no webhook to wait for. Cron triggers the process, the process runs locally, the only network call is the final YouTube upload.