Mike's Notes
Deployment roadmap
Later in the year, Pipi will be able to deploy infrastructure on any platform using Infrastructure as Code (IaC).
Options on how to do this include;
- CL (Command Line)
- REPL (Read-Eval-Print-Loop)
- API
Implementing a REPL (Read-Eval-Print-Loop) programmatically in CFML
I asked Google Search AI Mode (powered by Google Gemini) how to use CFML to write and read REPL.
The Google output has been reformatted but not edited, and the code needs to be tested. The questions were turned into headings. There is a lot of duplication.
I find that carefully using Gemini to write CFML code and then checking everything is making me more productive.
There is now enough here to set up REPL.
Once this automation is complete, productivity will increase by at least x10.
Resources
- https://www.blog.ajabbi.com/2026/02/having-data-centre-changes-roadmap.html
- https://www.blog.ajabbi.com/2026/04/cfml-64-bit-and-32-bit-datasource.html
- https://www.geeksforgeeks.org/node-js/node-js-repl-read-eval-print-loop/
References
- Reference
Repository
- Home > Ajabbi Research > Library >
- Home > Handbook >
Last Updated
04/04/2026
Pipi autonomous Read-Eval-Print-Loop (REPL)
Mike is the inventor and architect of Pipi and the founder of Ajabbi.
Gemini is still cool.
A Read-Eval-Print-Loop (REPL) is an interactive computer programming environment that accepts single-user input, executes it, and returns the result immediately. It is also known as an interactive toplevel or language shell. [1, 2, 3]
The Four Steps of the Loop
The name describes the precise cycle the environment follows: [4, 5]
- Read: The system accepts a line of input (usually a single expression or command) from the user.
- Eval: It parses and evaluates the input code to determine its value or effect.
- Print: The resulting value or output is displayed back to the user on the screen.
- Loop: The process repeats, returning to the prompt to wait for the next input. [1, 5, 6, 7, 8, 9, 10]
Why Developers Use REPLs
REPLs are highly valued for their tight feedback loop, which allows for: [6, 7, 11]
- Interactive Prototyping: Quickly testing small snippets of code without creating and saving files.
- Debugging: Investigating the state of a program and testing potential fixes in real-time.
- Learning: Experimenting with new language features or libraries with instant results.
- Calculations: Using the environment as a high-powered calculator for mathematical expressions. [1, 12, 13, 14, 15, 16, 17]
Common Examples
Most modern programming languages provide a built-in REPL or have popular third-party versions: [1, 18]
- Python: Accessed by running Python in a terminal; features a >>> prompt.
- JavaScript: Available in the [Node.js REPL](https://nodejs.org/en/learn/command-line/how-to-use-the-nodejs-repl) or the Developer Console in web browsers.
- Lisp: The classic environment where the term originated.
- Others: Ruby (irb), PHP (php -a), and Java ([JShell](https://en.wikipedia.org/wiki/Replit)). [1, 6, 14, 16, 17, 19, 20, 21]
References
- [1] [https://en.wikipedia.org](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)
- [2] [https://www.electronjs.org](https://www.electronjs.org/pt/docs/latest/tutorial/repl#:~:text=REPL.%20Read%2DEval%2DPrint%2DLoop%20%28REPL%29%20is%20a%20simple%2C%20interactive,and%20returns%20the%20result%20to%20the%20user.)
- [3] [https://glssry.org](https://glssry.org/software/read-eval-print-loop)
- [4] [https://www.geeksforgeeks.org](https://www.geeksforgeeks.org/node-js/node-js-repl-read-eval-print-loop/)
- [5] [https://www.cs.utexas.edu](https://www.cs.utexas.edu/ftp/garbage/cs345/schintro-v13/schintro_114.html)
- [6] [https://realpython.com](https://realpython.com/ref/glossary/repl/)
- [7] [https://createlang.rs](https://createlang.rs/01_calculator/repl.html)
- [8] [https://dev.to](https://dev.to/rijultp/let-the-ai-run-code-inside-the-repl-loop-26p)
- [9] [https://www.youtube.com](https://www.youtube.com/watch?v=4h_jY6zzDDI&t=4)
- [10] [https://www.youtube.com](https://www.youtube.com/watch?v=jfnFk8QB9Uo&t=5)
- [11] [https://www.lenovo.com](https://www.lenovo.com/ca/en/glossary/repl/)
- [12] [https://mintlify.com](https://mintlify.com/GandelXIV/dryft/compiler/repl)
- [13] [https://support.hackerrank.com](https://support.hackerrank.com/articles/6745090586-repl-%5B-read%E2%80%8A%E2%80%94%E2%80%8Aeval%E2%80%8A%E2%80%94%E2%80%8Aprint%E2%80%8A%E2%80%94%E2%80%8Aloop%5D-)
- [14] [https://www.lenovo.com](https://www.lenovo.com/in/en/glossary/repl/)
- [15] [https://www.lenovo.com](https://www.lenovo.com/us/en/glossary/repl/)
- [16] [https://realpython.com](https://realpython.com/python-repl/)
- [17] [https://www.digitalocean.com](https://www.digitalocean.com/community/tutorials/what-is-repl)
- [18] [https://www.computerhope.com](https://www.computerhope.com/jargon/r/repl.htm)
- [19] [https://nodejs.org](https://nodejs.org/en/learn/command-line/how-to-use-the-nodejs-repl)
- [20] [https://wiki.c2.com](https://wiki.c2.com/?ReadEvalPrintLoop)
- [21] [https://php-dictionary.readthedocs.io](https://php-dictionary.readthedocs.io/en/latest/dictionary/repl.ini.html)
Implementing REPL programmatically in CFML
Implementing a REPL (Read-Eval-Print-Loop) programmatically in CFML involves creating a loop that captures user input, evaluates it as live code, and returns the result. [1, 2, 3]
While Adobe ColdFusion (2018+) and CommandBox include built-in REPLs for terminal use, you can build your own programmatic version using the following core functions: [2, 4]
1. The Evaluation Engine
The most critical part of a REPL is the Eval step. CFML provides two primary ways to execute strings as code:
- Evaluate(): Best for executing single expressions and returning a value.
- Render(): (Lucee specific) Similar to Evaluate, but specifically designed to execute CFML tag or script code and return the generated output as a string. [5, 6]
2. Building a Basic Web-Based REPL
A programmatic REPL usually consists of a simple loop (often via a form submission) that maintains state.
inputCode = form.myScript ?: "";
if (len(trim(inputCode))) {
try {
// 2. EVAL: Execute the code
// Note: Evaluate() is powerful but dangerous with untrusted input
result = evaluate(inputCode);
// 3. PRINT: Output the result
writeOutput("Result: " & result);
} catch (any e) {
writeOutput("Error: " & e.message);
}
}
// 4. LOOP: Handled by the user submitting the form again
3. Advanced Implementation Details
To create a more robust "shell-like" experience:
- Persistent State: To keep variables alive across multiple inputs, store a "context" structure in a persistent scope like Session or Application.
- Capturing Console Output: If the code uses writeOutput(), you may need to use cfsavecontent to capture that output before it hits the main buffer.
- Safety: Never expose a REPL to public users. It allows for arbitrary code execution, which can delete files or access sensitive server data.
- Multi-line Support: For more complex scripts, you may need to detect if a block (like an if statement or function) is complete before evaluating, similar to how [CommandBox's REPLParser](https://community.ortussolutions.com/t/replparser-multiline-support/9559) works. [6, 7, 8]
Summary of Tools
| Feature [2, 3] | Function/Tool | Platform |
|---|---|---|
| Expression Eval | Evaluate(string) | Adobe & Lucee |
| Full Code Execution | Render(string) | Lucee Only |
| Terminal REPL | cf.bat / cf.sh | Adobe (2018+) |
| CLI REPL | box repl | CommandBox |
References
- [1] [https://www.youtube.com](https://www.youtube.com/watch?v=vzKKKdK7eDA&t=72)
- [2] [https://modern-cfml.ortusbooks.com](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters)
- [3] [https://coldfusion.adobe.com](https://coldfusion.adobe.com/2018/07/repl-coldfusion-2018-release/)
- [4] [https://helpx.adobe.com](https://helpx.adobe.com/coldfusion/using/command-line-interface.html)
- [5] [https://docs.lucee.org](https://docs.lucee.org/categories/core.html)
- [6] [https://www.bennadel.com](https://www.bennadel.com/blog/3861-evaluating-database-records-that-contain-coldfusion-interpolation-expressions-in-adobe-coldfusion-2018.htm)
- [7] [https://community.ortussolutions.com](https://community.ortussolutions.com/t/replparser-multiline-support/9559)
- [8] [https://coldfusion.adobe.com](https://coldfusion.adobe.com/2018/07/repl-coldfusion-2018-release/)
Using workflows written in CFML to write and read REPL
To build a workflow in CFML that programmatically reads from and writes to a REPL, you need to treat the REPL as an external process. This is most effectively done using CommandBox, which provides a robust CLI and REPL environment for CFML. [1, 2]
1. Using CommandBox via cfexecute
The standard way to interact with a REPL from a running CFML workflow (like a background task or a web request) is to use <cfexecute> or the execute() function to call the [CommandBox binary](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters).
- Writing to REPL: You can pass CFML code directly to the CommandBox repl command using the --code flag or by piping input.
- Reading from REPL: The output of the command is captured in a variable for your workflow to process. [3, 4, 5]
Example: Running a Snippet and Capturing the Result
replInput = "x = 10; y = 20; writeOutput(x + y);";
// Execute CommandBox REPL with the code
execute(
name = "box",
arguments = "repl --code=""#replInput#""",
variable = "replOutput",
timeout = 10
);
// Read the result back into your workflow
writeOutput("The REPL returned: " & replOutput);
2. Interactive Workflows with Piping
If your workflow needs to chain multiple operations, you can use the cfml command in CommandBox. This allows you to [pipe data](https://commandbox.ortusbooks.com/usage/execution/cfml-functions) between CFML functions as if they were terminal commands.
- Workflow logic: #listGetAt www.foo.com 2 . | #ucase | #reverse
- Result: The REPL processes each step and passes the "Read" result of one to the "Eval" of the next. [6, 7]
3. Asynchronous "Daemon" REPL
For a long-running workflow that needs to keep a REPL "warm" (to avoid startup overhead), consider using an Event Gateway or a persistent background thread. [8]
- Start a process: Use java.lang.ProcessBuilder via CFML to open a persistent connection to the CommandBox shell.
- Write to Stream: Send commands to the process's OutputStream.
- Read from Stream: Use a separate CFML thread to constantly poll the InputStream for the REPL's response. [9, 10]
4. Safety and Best Practices
- Sanitisation: If the input for your REPL comes from an external source, treat it as unsafe. Programmatic REPLs can execute fileDelete() or access system environment variables.
- Timeouts: Always set a timeout in your execute calls to prevent a "loop" in the REPL from hanging your entire server.
- Context: Remember that code executed in a separate REPL process does not share the same variable scope (like Session or Request) as your main workflow unless you explicitly pass those values in. [11]
References
- [1] [https://modern-cfml.ortusbooks.com](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters)
- [2] [https://modern-cfml.ortusbooks.com](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters)
- [3] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/execution/cfml-functions)
- [4] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/repl)
- [5] [https://modern-cfml.ortusbooks.com](https://modern-cfml.ortusbooks.com/cfml-language/variables)
- [6] [https://blogg.bekk.no](https://blogg.bekk.no/creating-a-repl-in-haskell-efcdef1deec2#:~:text=How%20to%20make%20a%20REPL%20As%20stated,will%20be%20covering%20in%20the%20sections%20below.)
- [7] [https://medium.com](https://medium.com/@josh.cheek/write-a-repl-in-ruby-fbef30c9f4e#:~:text=Simple%20beginnings%20A%20REPL%20must%20%E2%80%9C%20Read%E2%80%9D,So%2C%20lets%20start%20with%20those%20four%20steps.)
- [8] [https://learn.microsoft.com](https://learn.microsoft.com/en-us/archive/msdn-magazine/2014/april/mvvm-multithreading-and-dispatching-in-mvvm-applications#:~:text=Similarly%2C%20long%20operations%20in%20your%20applications%20should,background%20operation%20that%20runs%20a%20long%20loop.)
- [9] [https://practical.li](https://practical.li/clojure/introduction/repl-workflow/)
- [10] [https://brianklaas.net](https://brianklaas.net/aws/coldfusion/2019/03/01/Using-AWS-Lambda-In-CFML-Part-4.html#:~:text=This%20may%20not%20be%20possible%20without%20building,your%20CFML%20application%20continues%20to%20hum%20along.)
- [11] [https://www.codementor.io](https://www.codementor.io/@garethdwyer/building-a-crm-app-with-nodejs-repl-it-and-mongodb-119r72mczg#:~:text=To%20solve%20this%20problem%2C%20we%27ll%20be%20using,environment%20and%20are%20accessible%20in%20our%20code.)
Pass complex data (like a Struct) between your workflow and a CommandBox REPL
To pass complex data, such as a Struct or Array, between a CFML workflow and a REPL, the most reliable method is to use JSON serialisation. Since the REPL and your main application run in separate memory spaces, JSON acts as a universal bridge for data exchange.
1. Passing a Struct into the REPL (Write)
When calling the REPL, convert your CFML Struct into a JSON string and inject it into the command as a literal. CommandBox’s REPL is smart enough to interpret a JSON string as a native Struct if it's the first input to certain functions or assigned directly. [1, 2]
userData = {
"id": 123,
"roles": ["admin", "editor"],
"settings": { "theme": "dark" }
};
// Serialize to JSON (use single quotes for the shell command)
jsonInput = serializeJSON(userData);
// Build the REPL command
// Note: We assign the JSON string directly to a variable inside the REPL
replCommand = "data = #jsonInput#; writeOutput(data.roles[1]);";
execute(
name = "box",
arguments = "repl --code=""#replCommand#""",
variable = "replResponse"
);
writeOutput("REPL processed role: " & replResponse); // "admin"
2. Getting a Struct back from the REPL (Read)
To read complex data back into your workflow, have the REPL print the result as JSON. You then use deserializeJSON() in your main workflow to turn that string back into a live CFML Struct. [3]
replCode = "result = { 'status': 'success', 'timestamp': now() }; writeOutput(serializeJSON(result));";
execute(
name = "box",
arguments = "repl --code=""#replCode#""",
variable = "rawJsonResponse"
);
// Read the complex data back into your workflow
if (isJSON(rawJsonResponse)) {
finalData = deserializeJSON(rawJsonResponse);
writeOutput("Status received: " & finalData.status);
}
Key Considerations for Data Integrity
- Key Casing: Adobe ColdFusion typically converts struct keys to UPPERCASE during serialisation unless you quote the keys (e.g., {"name": "value"}).
- Shell Escaping: Be careful with double quotes inside your JSON. When building the arguments string for execute(), ensure you escape quotes correctly so the shell doesn't break the command.
- Performance: If you are passing very large datasets (multi-MB structs), the overhead of serialisation and shell execution will increase. For high-frequency workflows, consider writing the data to a temporary JSON file and having the REPL read that file instead of passing it as a command-line argument. [4, 5, 6, 7]
- [1] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/repl)
- [2] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/execution/cfml-functions)
- [3] [https://modern-cfml.ortusbooks.com](https://modern-cfml.ortusbooks.com/cfml-language/json)
- [4] [https://helpx.adobe.com](https://helpx.adobe.com/id_id/coldfusion/cfml-reference/coldfusion-functions/functions-s/serializejson.html)
- [5] [https://cfdocs.org](https://cfdocs.org/serializejson)
- [6] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/repl#:~:text=You%20can%20use%20environment%20variable%20expansions%20in,so%20the%20resulting%20CFML%20code%20is%20valid.)
- [7] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/execution/cfml-files#:~:text=test.cfm.%20%23now%28%29%23%20We%20can%20execute%20this%20file,command:%20CommandBox%3E%20execute%20test.cfm%20%7Bts%20%272015%2D02%2D19%2020:12:41%27%7D)
Using temporary files to handle larger datasets between your workflow and the REPL
To handle larger datasets between your CFML workflow and a REPL, using temporary files is the most reliable method. This avoids shell character limits and prevents memory issues. [1]
1. The Workflow: Writing to a Temp File
First, your main application serialises the data into a JSON file. Use getTempFile() to ensure a unique filename that won't collide with other processes. [2, 3]
complexData = {
"users": queryToArray( myLargeUserQuery ), // Assume 10k rows
"metadata": { "source": "workflow_alpha", "processed": now() }
};
// 2. Create a unique temp file
tempFilePath = getTempFile( getTempDirectory(), "repl_data" );
// 3. WRITE: Save the JSON to the file
fileWrite( tempFilePath, serializeJSON( complexData ) );
2. The REPL: Reading the File
When you execute the REPL, pass the file path as a variable. The REPL code will then read the file from disk and deserialise it back into a native CFML object. [4, 5]
replCode = "
data = deserializeJSON( fileRead('#tempFilePath#') );
// Perform complex logic on the data
resultCount = data.users.len();
writeOutput( resultCount );
";
// 5. EXECUTE: Call CommandBox REPL
execute(
name = "box",
arguments = "repl --code=""#replCode#""",
variable = "replOutput"
);
3. Cleaning Up
Because these files are stored in the system's temporary directory, they will eventually be cleared, but it is best practice to delete them manually once your workflow is finished to save disk space. [1, 6]
if ( fileExists( tempFilePath ) ) {
fileDelete( tempFilePath );
}
writeOutput( "REPL processed #replOutput# records." );
Why use files instead of variables?
- Memory Efficiency: Large strings in shell commands can lead to "Out of Memory" (OOM) errors or exceed operating system command-line length limits.
- Data Integrity: Files eliminate the need for complex shell quoting and escaping of special characters in your JSON.
- Persistent Context: If the REPL crashes, the data remains safely on disk for debugging or a retry attempt. [1, 7]
References
- [1] [https://stackoverflow.com](https://stackoverflow.com/questions/79336536/loading-and-processing-large-file-120mb-in-memory-throws-oom-when-ram-is-still)
- [2] [https://docs.lucee.org](https://docs.lucee.org/reference/functions/gettempfile.html)
- [3] [https://docs.lucee.org](https://docs.lucee.org/categories/files.html)
- [4] [https://medium.com](https://medium.com/@itsuki.enjoy/command-box-an-npm-for-coldfusion-46f1326c43e7)
- [5] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/parameters/file-paths)
- [6] [https://cfdocs.org](https://cfdocs.org/cfexecute)
- [7] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/repl)
CommandBox Task Runners to make these multi-step REPL workflows even cleaner
While a REPL is great for ad-hoc snippets, CommandBox Task Runners provide a more structured way to handle multi-step workflows. A Task Runner is a CFML component (.cfc) that runs directly from the command line, allowing you to pass complex arguments naturally and use built-in helpers for file and shell interaction. [1, 2, 3, 4]
1. Create the Task Runner (MyTask.cfc) [5]
Instead of cramming logic into a string for the REPL, you write a standard CFML function. You can create one by running task create --open in [CommandBox](https://commandbox.ortusbooks.com/task-runners). [2, 3, 6]
2. Execute the Task from your Workflow [5]
In your main application, you call the task just like you did with the REPL, but it’s much cleaner because the logic is encapsulated in its own file. [7, 8]
Why Task Runners are better for workflows:
- Portability: Tasks are self-contained in a CFC and can be dropped into any folder without being a full module.
- Built-in Helpers: You get access to the print helper for formatted console output and filesystemUtil for easy path resolution.
- Named Parameters: Unlike the REPL, tasks support [named parameters](https://commandbox.ortusbooks.com/task-runners/running-other-tasks), making it easy to pass file paths, IDs, or configuration flags.
- Readability: Your code is written in a standard IDE with syntax highlighting and error checking rather than as a string inside an execute() call. [1, 3, 9, 10, 11]
References
- [1] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/task-runners)
- [2] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/task-runners)
- [3] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/task-runners)
- [4] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/repl#:~:text=CommandBox%20contains%20a%20REPL%20command%20which%20is,execution%20of%20both%20CF%20script%20or%20tags.)
- [5] [https://docs.tilebox.com](https://docs.tilebox.com/workflows/concepts/task-runners)
- [6] [https://2023.intothebox.org](https://2023.intothebox.org/into-the-box/sessions/detail?slug=sessions/commandbox-taskrunners)
- [7] [https://medium.com](https://medium.com/@itsuki.enjoy/command-box-an-npm-for-coldfusion-46f1326c43e7)
- [8] [https://github.com](https://github.com/ortus-docs/commandbox-docs/blob/6.3.0/developing-for-commandbox/commands/README.md)
- [9] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/task-runners)
- [10] [https://github.com](https://github.com/ortus-docs/commandbox-docs/blob/6.3.0/task-runners/README.md#:~:text=Build%20your%20first%20task&text=Aaaaand%2C%20now%20we%20run%20it!%20CommandBox%3E%20task,how%20to%20pass%20parameters%20to%20your%20tasks.)
- [11] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/usage/execution/cfml-functions)
Scheduling these tasks to run automatically at specific intervals
To schedule CommandBox Task Runners at specific intervals, you have three primary approaches depending on whether you want to use the operating system, a background process (daemon), or the ColdFusion engine itself. [1]
1. The Daemon Approach (Self-Scheduling)
For workflows that need to run continuously in the background without external dependencies, you can write your task as a daemon. This involves a while(true) loop and a sleep() command within the CFC. [2, 3]
* ScheduledTask.cfc
* Run: box task run taskFile=ScheduledTask.cfc
*/
component {
function run() {
try {
while( true ) {
print.blueLine( "Running workflow at #now()#..." );
// INSERT YOUR WORKFLOW LOGIC HERE
// Sleep for 5 minutes (300,000 milliseconds)
sleep( 300000 );
}
} catch( any e ) {
print.redLine( "Task interrupted: #e.message#" );
}
}
}
2. OS-Level Scheduling (Cron / Task Scheduler)
This is the most "production-ready" method for strictly timed intervals (e.g., every day at 2 AM). You simply tell your OS to execute the CommandBox binary and your specific task file. [3, 4, 5, 6]
-
Linux (Crontab): Add a line to your crontab using crontab
-e:
0 2 * * * /usr/local/bin/box task run /path/to/MyTask.cfc - Windows (Task Scheduler): Create a new task that runs the box.exe program with the arguments task run taskFile=C:\path\to\MyTask.cfc. [7, 8, 9]
3. CFML Engine Scheduling (cfschedule) [10]
If you want to manage the schedule from within your web application's admin interface or code, you can use the native <cfschedule> tag or cfschedule() function to call the CommandBox CLI. [10, 11]
action = "update",
task = "HourlyWorkflow",
operation = "HTTPRequest",
url = "http://localhost/run_my_task.cfm", // A script that runs the task
interval = "3600" // Every hour
);
Note: Your run_my_task.cfm file would then contain the execute() call to trigger the CommandBox task.
4. Advanced: ColdBox Scheduled Tasks
If you are using the [ColdBox Framework](https://coldbox.ortusbooks.com/digging-deeper/scheduled-tasks), you can use the built-in Async Scheduler to define tasks with a fluent, human-readable API. [1, 9, 12]
task( "CleanTempFiles" )
.call( function(){
// CommandBox execution logic here
} )
.every( 1, "hours" )
.delay( 5, "minutes" );
References
- [1] [https://shiftinsert.nl](https://shiftinsert.nl/scheduled-tasks-in-coldbox/)
- [2] [https://commandbox-service-manager.ortusbooks.com](https://commandbox-service-manager.ortusbooks.com/task-services)
- [3] [https://commandbox-service-manager.ortusbooks.com](https://commandbox-service-manager.ortusbooks.com/task-services)
- [4] [https://helpx.adobe.com](https://helpx.adobe.com/coldfusion/developing-applications/developing-cfml-applications/using-the-coldfusion-debugger/using-scheduler.html)
- [5] [https://www.bluehost.com](https://www.bluehost.com/blog/cron-job-schedule/)
- [6] [https://commandbox.ortusbooks.com](https://commandbox.ortusbooks.com/task-runners)
- [7] [https://serverfault.com](https://serverfault.com/questions/739352/schedule-tasks-at-specific-intervals-but-not-fixed-times)
- [8] [https://github.com](https://github.com/ortus-docs/commandbox-docs/blob/6.3.0/task-runners/passing-parameters.md)
- [9] [https://coldbox.ortusbooks.com](https://coldbox.ortusbooks.com/digging-deeper/scheduled-tasks)
- [10] [https://cfdocs.org](https://cfdocs.org/cfschedule)
- [11] [https://cfdocs.org](https://cfdocs.org/cfschedule)
- [12] [https://community.ortussolutions.com](https://community.ortussolutions.com/t/coldbox-scheduled-tasks-a-couple-of-suggestions/9330)
