How to Configure CRON Schedules for Multiple Accounts in MoneyPrinterV2
To configure CRON schedules for multiple accounts in MoneyPrinterV2, register separate jobs with the schedule library for each account UUID via the interactive CLI in src/main.py, then keep the process alive with a persistent loop that calls schedule.run_pending().
MoneyPrinterV2 automates content posting across YouTube and Twitter using an in-process scheduler. When you configure CRON schedules for multiple accounts, the application builds distinct command chains for each account UUID and registers them with the global schedule instance. This guide explains the exact mechanism using the source code from FujiwaraChoki/MoneyPrinterV2.
How the Scheduling Flow Works
The scheduling system follows a five-step pipeline implemented in src/main.py. Each account you configure spawns a separate job function that embeds the account's unique identifier.
- Select an account –
main()loads cached accounts fromsrc/cache.pyand presents them in a menu. - Choose a frequency – You select an option defined in
src/constants.py(Once a day,Twice a day, etc.). - Build the command – A list like
["python", "src/cron.py", "youtube", "<account-id>", "<model>"]is assembled (lines 95-96 insrc/main.py). - Create a job function –
def job(): subprocess.run(command)(line 97). - Register with
schedule– Depending on the frequency, the job attaches viaschedule.every().day.do(job)orschedule.every().day.at("HH:MM").do(job)(lines 101-108 for YouTube, lines 132-140 for Twitter).
All jobs reside in the same global scheduler instance. Adding a second account repeats steps 1-5, registering an additional job carrying its own account UUID. When the scheduler loop runs, each job invokes cron.py with the appropriate arguments to process the correct account.
Scheduling Multiple Accounts
Because the scheduler is global, you can configure jobs for any number of accounts during a single run of main(). The typical workflow involves entering the YouTube or Twitter menu, selecting an account, picking a frequency, and returning to the top-level menu to repeat the process for another account.
When you exit the UI, the process terminates, so scheduled jobs only fire while the program remains alive. To keep the scheduler active after configuration, add a persistent loop at the end of main():
import time
while True:
schedule.run_pending()
time.sleep(1) # keep CPU usage low
Placing this after the top-level menu (or in a dedicated "Run Scheduler" command) allows all previously registered jobs—even for different accounts—to execute automatically at their configured times.
Code Examples
Adding a Second YouTube Account
After scheduling a job for account A, repeat the same menu steps for account B:
# First account (A) - already scheduled
# User selects "YouTube Shorts Automater" → picks account A → sets "Twice a day"
# Second account (B) - new job
# User selects "YouTube Shorts Automater" → picks account B → sets "Twice a day"
# This creates a new job() embedding B's UUID
Both jobs now exist in the global scheduler:
# Example scheduled jobs after configuration
schedule.every().day.at("10:00").do(job) # runs cron.py for account A
schedule.every().day.at("16:00").do(job) # runs cron.py for account A
schedule.every().day.at("11:30").do(job) # runs cron.py for account B
schedule.every().day.at("17:30").do(job) # runs cron.py for account B
Extending Frequency Options
To add a custom schedule like "Every 4 hours," modify the constants and add the corresponding logic:
# src/constants.py
YOUTUBE_CRON_OPTIONS = [
"Once a day",
"Twice a day",
"Once every hour",
"Every 4 hours" # new option
]
# In src/main.py, add the corresponding elif branch
elif user_input == 4: # index of "Every 4 hours"
schedule.every(4).hours.do(job)
success("Set up CRON Job for every 4 hours.")
Key Files
| File | Role |
|---|---|
src/main.py |
Core interactive CLI containing the menu logic that creates schedule jobs for both YouTube and Twitter accounts |
src/cron.py |
Headless runner executed by the scheduler; receives <platform> <account-id> <model> arguments and performs the actual upload or tweet |
src/constants.py |
Defines selectable CRON frequency options (YOUTUBE_CRON_OPTIONS, TWITTER_CRON_OPTIONS) |
src/cache.py |
Handles reading and writing account data; get_accounts() supplies the list of stored accounts used when scheduling |
src/config.py |
Provides configuration helpers (e.g., ROOT_DIR) used to build absolute paths to cron.py |
Summary
- MoneyPrinterV2 uses the
schedulelibrary for in-process CRON-like automation rather than system-level cron. - Each account requires a separate job registration via the CLI in
src/main.py, embedding the account UUID in the command arguments passed tosrc/cron.py. - The global scheduler supports multiple concurrent jobs, allowing you to configure different frequencies for different accounts in a single session.
- Jobs only execute while the Python process remains alive; add a
while Trueloop withschedule.run_pending()to keep the scheduler active.
Frequently Asked Questions
Can I schedule different frequencies for different accounts?
Yes. The global schedule instance maintains independent jobs for each account. When you configure account A with "Once a day" and account B with "Twice a day," src/main.py registers two separate job functions with distinct timing parameters. Each job carries its own account UUID, ensuring the correct account processes when the trigger fires.
What happens if I close the terminal?
The scheduled jobs terminate immediately. Because MoneyPrinterV2 uses the in-process schedule library rather than the system CRON daemon, all jobs exist only in memory. If the Python process exits, the scheduler disappears. To run jobs persistently, either keep the terminal open with the while True loop running, or wrap the script in a process manager like systemd or pm2.
How do I stop a scheduled job?
The schedule library does not provide a direct deletion method in the current implementation used by MoneyPrinterV2. To stop a job, you must restart the Python process and reconfigure only the desired accounts. Alternatively, you can modify the source code to capture the returned job object from schedule.every().day.do(job) and call .cancel() on it, but this requires editing src/main.py to store job references.
Can I use the system CRON instead of the Python scheduler?
Yes, but it requires manual configuration. Instead of using the interactive menu in src/main.py, you can write a system CRON entry that directly invokes src/cron.py with the required arguments: python src/cron.py <platform> <account-id> <model>. This bypasses the schedule library entirely and allows the operating system to handle timing, even when the main MoneyPrinterV2 process is not running.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →