Atlas expedition

Channel watching & new-upload automation: how self-hosted YouTube tools poll, filter, and catch new videos

How PinchFlat, TubeArchivist, ytdl-sub, TubeSync and MeTube watch channels for new uploads — scheduling models, download filters, the RSS-vs-yt-dlp detection layer, and 2026 throttle/ban etiquette.

41 sources ~8 min read #211 self-hosted · youtube · yt-dlp · automation · channel-monitoring · pinchflat · tubearchivist
Decision — which watcher to run:
  • PinchFlat ⭐ 5.0k — best turnkey channel watcher for a media library: per-source interval-after-completion scheduling, the richest new-upload filters (title regex, date cutoff, min/max duration), RSS-by-default detection with optional API-key fast indexing, plus Apprise + SponsorBlock + custom lifecycle scripts.[3][30]
  • TubeArchivist ⭐ 8.1k — pick it for in-browser playback + full-text search alongside watching, but its cron scheduler has a once-per-hour floor and it has the weakest download filtering (no title/date/duration filters, only per-channel page-size caps).[1][12]
  • ytdl-sub ⭐ 2.8k — most powerful filtering (date ranges, raw yt-dlp match-filters, rolling retention) for people who live in YAML; no UI and you bring your own cron.[9][5]
  • TubeSync ⭐ 2.7k — flexible per-source filters and retention, but its tracker carries open reports of stalled and en-masse "skipped" downloads; ⚠ verify before trusting it set-and-forget.[37][38]
Underneath, every one of these wraps yt-dlp ⭐ 169k[21]. New-upload detection is either the 15-item YouTube RSS feed[15] (cheap, can miss bursts) or a full --flat-playlist index (complete, heavier). Poll hourly at most — YouTube's 2026 bot wall punishes aggressive watchers.[24]

1. How each tool schedules its watch

Three distinct scheduling models are in play. The difference matters: a "60-minute" setting means something different in each.

ToolScheduling modelDefault cadencePer‑source?Key knob
PinchFlat ⭐ 5.0kInterval-after-completionUser-set per sourceIndex Frequency + Fast Indexing[3]
TubeArchivist ⭐ 8.1kCron (min/hour/dow), once-per-hour floorUser-set, ≥1h✗ globalRescan Subscriptions schedule[1]
TubeSync ⭐ 2.7kPer-source interval (Django bg tasks)≤ 24h recommendedindex frequency[6]
ytdl-sub ⭐ 2.8kExternal cron (no internal scheduler)None (e.g. 0 */6 * * *)n/aCRON_SCHEDULE env[5]
MeTube ⭐ 14kFixed global interval60 min✗ globalSUBSCRIPTION_DEFAULT_CHECK_INTERVAL[2]
YoutubeDL-Material ⭐ 3.2kSingle global cycle interval5 min to cycle all subs✗ globalsubscriptions_check_interval[7]

The traps hide in the model, not the number:

  • PinchFlat schedules the next run only after the current one finishes → a 60-min Index Frequency plus a 30-min indexing pass yields a real 90-min cadence. With an optional YouTube Data API key, fast indexing polls ~65 sources at a 10-min interval; RSS fast indexing is the no-key default.[3][4]
  • YoutubeDL-Material's interval is the time to cycle through every subscription, not per-channel. 10 subs at a 100-second interval ⇒ one sub checked every 10 seconds; effective per-channel spacing = interval ÷ sub count.[7]
  • TubeArchivist uses real cron (three fields: minute, hour, day-of-week) but rejects non-standard n/n step syntax in the first field and will not run more than once per hour.[1]
  • ytdl-sub has no scheduler at all — its Docker image bolts on optional cron via CRON_SCHEDULE. Avoid CRON_RUN_ON_START: it re-fires on every reboot, dockerd restart, and image pull, which can trigger throttles and bans.[5]

2. Which new uploads actually download

Watching a channel is only half the job — the other half is deciding which of its uploads you keep. This is where the tools diverge most.

ToolTitle regexDate cutoffMin/max durationContent-type toggleResolution floorRetention / keep-N
PinchFlat✓ match[8]✓ YYYY-MM-DD[3][3]✓ shorts/live[8]profile
ytdl-sub✓ match_filters[9]✓ date_range[9][9]✓ exclude shorts/live[9]format✓ rolling + keep_max_files[10]
TubeSync✓ + invert[13]✓ filter_seconds[13]limited✓ source_resolution[13]✓ days_to_keep[13]
TubeArchivist[12]page-size 0[11]quality[11]auto-delete watched[12]
MeTubeformat[2]

✓ supported · ✗ absent · ⚠ partial. "Content-type toggle" = selectively include/exclude videos vs Shorts vs livestreams.

  • PinchFlat exposes per-source Title Filter Regex, a Download Cutoff Date, and min/max duration — and lets you dry-run them: disable "Download Media" and inspect the Pending Media tab to see exactly what the filters and shorts/livestream handling would pull before committing.[8]
  • ytdl-sub is the power tool: the date_range plugin filters on before/after (upload or release date), and match_filters passes raw yt-dlp expressions like original_url!*=/shorts/ & !is_live to drop Shorts and livestreams. Its Only Recent presets hold a rolling window (default 2months) and prune anything older, with keep_max_files for a hard cap.[9][10]
  • TubeSync filters at the Source model — filter_text (title regex) with filter_text_invert to reject matches, filter_seconds/filter_seconds_min for min/max duration, source_resolution as a quality floor, and days_to_keep/delete_old_media for retention. These knobs grew out of feature request #266.[13][14]
  • TubeArchivist has no title/date/duration filter at all. The only lever is per-channel Page Size Overrides — set Live or Shorts page size to 0 to disable that type for a channel — plus Auto-Delete-Watched for retention.[11][12]
  • MeTube's new subscriptions auto-queue uploads but offer no title/date/duration/content-type filter beyond yt-dlp's global format options.[2]

3. Under the hood: RSS vs --flat-playlist

Every watcher detects new uploads one of two ways, and the choice is a real trade-off between request cost and completeness.

The cheap path — YouTube channel RSS

Every public channel exposes a free, unauthenticated feed at youtube.com/feeds/videos.xml?channel_id=UC…. It is trivial to poll — but it only ever returns the 15 most recent uploads, a hard YouTube cap that an entire cottage industry of third-party services exists to work around.[15][16][17] It also carries propagation latency: a freshly published video can lag up to an hour, and YouTube's WebSub "push" pings are non-spec-compliant — they tell you to re-fetch the feed rather than carrying the new entry.[18]

The complete path — yt-dlp playlist extraction

yt-dlp's --flat-playlist enumerates every entry on a channel/uploads playlist (IDs, URLs, metadata) without downloading. No 15-item window, full back-catalog — at the cost of many more requests per poll.[19][22] This is why PinchFlat distinguishes RSS fast indexing (cheap, default) from API-key indexing (accurate) and why its FAQ warns RSS "can miss videos in some weird edge cases."[3]

Bookkeeping — not re-downloading what you already have

The de-dup layer is yt-dlp's --download-archive FILE, which records downloaded video IDs and skips anything listed. --break-on-existing short-circuits a run at the first already-archived video (so incremental polls stop early), and --break-per-input rescopes that break — plus --max-downloads and match-filters — to each input URL.[19] There is a documented quirk: with --break-per-input on, --break-on-existing breaks per input rather than per playlist.[20] The simplest DIY watcher is exactly this: yt-dlp --download-archive watched.txt <channel-URL> on a cron.[39]

How uploads slip through: RSS-based watchers miss videos when more than 15 drop inside one poll interval, and either method can miss premieres or private-then-public videos that publish with a back-dated timestamp falling below the feed cursor. Subarr ⭐ 405, a "Sonarr for YouTube," is refreshingly candid about this: it polls RSS every ~15 minutes but is "limited to the last 15 items in feeds" and "may miss videos if many uploads occur rapidly."[35]

4. Watcher etiquette: throttling, the 2026 bot wall, and cookies

Polling YouTube on a tight loop is the fastest way to get your IP fought back. Every serious tool ships conservative defaults and says so:

  • TubeArchivist advises a ~3-second sleep between requests, spreads metadata refreshes across a 90-day window, and warns that residential IP ranges get throttled — suggesting a shared proxy/VPN IP as mitigation.[23]
  • TubeSync tells you to keep the index frequency "as long as possible, up to 24 hours," because crawling a lot quickly can get your IP "throttled and/or banned."[6]
  • PinchFlat self-throttles via worker concurrency (YT_DLP_WORKER_CONCURRENCY), recommending 1 when IP-limited.[3]

The 2026 pressure point is the bot wall. In February 2026 (yt-dlp 2026.02.04) even public, login-free videos began returning LOGIN_REQUIRED — "Sign in to confirm you're not a bot" — across multiple player clients, with the error itself pointing to cookies, a nightly/master update, or PO tokens.[24] PO (proof-of-origin) tokens are minted by BotGuard/DroidGuard/iOSGuard, bound to the video/session, and expire fast; enforcement keeps shifting, so guidance is provisional.[25] The practical fix is the bgutil POT provider ⭐ 559, ideally an always-on HTTP server (prebuilt Docker image) that yt-dlp consumes automatically.[26] Crucially, a PO token "does not guarantee bypassing 403 errors or bot checks" — it only makes traffic look more legitimate.[27]

On cookies: watching public channels generally needs no cookies. Reaching for them to dodge the bot wall is the risky lever — YouTube rotates and invalidates cookies on continued browser use, so yt-dlp's guide says to export from a fresh incognito window and never reopen it,[28] and users report cookie auth carries account-ban risk.[29] The cat-and-mouse means running yt-dlp nightly/master, not stable, when the wall moves.[24]

5. After the catch: downstream automation

What fires once a watched channel's new video lands separates a downloader from an automation hub.

ToolNotificationsSponsorBlockMedia-server metadataCustom hooks
PinchFlatApprise[30]⚠ timing[33]Plex/Jellyfin/Kodi[30]lifecycle scripts[31]
ytdl-sub✓ native[9]NFO tags (Kodi/JF/Plex)[9]YAML presets
TubeArchivistvia JF plugin[32]JF plugin
TubeSyncJellyfin/Plex update[6]
  • PinchFlat is the most automation-rich: Apprise notifications, SponsorBlock, first-class Plex/Jellyfin/Kodi metadata, and podcast RSS feeds out of the box.[30] Its standout is a single lifecycle script at <config>/extras/user-scripts/lifecycle, called with an event type plus a JSON payload for app_init, media_pre_download, media_downloaded, and media_deleted — bash or Python 3, with jq bundled — so any webhook or library refresh is a few lines.[31] ⚠ One caveat: SponsorBlock segment quality depends on download timing, so users ask for a configurable delay between indexing and download to let crowd-sourced segments aggregate.[33]
  • ytdl-sub handles SponsorBlock natively (sponsorblock_categories to embed segment chapters, remove_sponsorblock_categories to cut them) and writes per-entry nfo_tags / output_directory_nfo_tags for Kodi/Jellyfin/Plex.[9]
  • TubeArchivist keeps SponsorBlock data internally; surfacing it in Jellyfin needs a separate community plugin mapping it to Jellyfin Media Segments (installed alongside the existing TubeArchivist metadata plugin).[32]
  • TubeSync acts as a Sonarr-style PVR — it fetches metadata and thumbnails and updates an attached Jellyfin or Plex server after download.[6]

6. Beyond the big tools: purpose-built and DIY watchers

A whole tier of lighter, watch-first tools exists, plus the always-available cron script:

  • Youtarr ⭐ 1.2k (Jun 2026) — a yt-dlp web app that subscribes to channels and auto-downloads new videos, shorts, and streams on a cron schedule with per-tab controls and Plex/Kodi/Jellyfin/Emby integration.[36]
  • ChannelTube ⭐ 314 (Jun 2026) — a Docker web UI that fetches new channel content on a comma-separated list of hours and can trigger Plex/Jellyfin library scans.[34]
  • Subarr ⭐ 405 (Jun 2026) — minimal RSS-polling "Sonarr for YouTube"; useful, but its own README flags the 15-item RSS ceiling and rapid-burst misses.[35]
  • Plain cron + yt-dlpyt-dlp --download-archive on a timer is the zero-dependency baseline every other tool is built on top of.[39] ytdl-sub ⭐ 2.8k is the same idea wrapped in declarative YAML and scheduled via CRON_SCHEDULE.[40]

7. Reliability sentiment

The recurring community ask is an "*arr-style app I can give a list of channels and have it keep the archive up to date indefinitely" — a 2025 Hacker News thread on exactly this points people to Youtarr and TubeArchivist (praised for Jellyfin integration) and RSS scripts.[41] The trust gap is real on TubeSync: despite advertised back-off retry logic, its tracker carries open reports of all downloads stalling[37] and large batches of videos marked "skipped" with a standing request for a batch-restart button.[38] The net read for set-and-forget channel watching in 2026: PinchFlat for a single-container watcher with the best filters and the API-key accuracy option, TubeArchivist when you also want playback and search, and a cron + yt-dlp + bgutil POT stack when you want full control over the cat-and-mouse.

Citations · 41 sources

Click the Citations tab to load…