SEO / Portfolio / Public Site

Making the Daily Brief Run Unattended: Durable Scheduling and Minimal State for PHP Shared Hosting

Report summary

The engineering of an unattended, durable control plane for executing complex daily workflows—such as the aggregation, analysis, and composition of a publication brief—presents a unique class of distributed systems challenges when deployed within a legacy shared hosting ecosystem. In modern, unconst

Status
Research archive item
Category
SEO / Portfolio / Public Site
Length
4,858 words
Reading time
23 minutes
Report type
evaluation

Key topics

  • SEO / Portfolio / Public Site
  • SEO
  • Portfolio
  • Public Site
  • AI
  • WordPress
  • .NET
  • MySQL
  • Runtime

Research provenance

Archive status
Research archive item
Content identity
sha256:c22d6c48f004118ac008b6ca6b505ce6411832feab0f0f8a56903cf565e0c3d4

For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.

This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.

Full report

On this page

The Architectural Reality of Constrained Environments

The engineering of an unattended, durable control plane for executing complex daily workflows—such as the aggregation, analysis, and composition of a publication brief—presents a unique class of distributed systems challenges when deployed within a legacy shared hosting ecosystem. In modern, unconstrained architectures, background workflows are typically delegated to persistent supervisor daemons, message brokers (e.g., RabbitMQ, Kafka), or fast in-memory data structures (e.g., Redis). However, in a strictly constrained shared hosting environment running PHP 8.2 under a LiteSpeed web runtime and managed by cPanel and CloudLinux, these standard paradigms are fundamentally unavailable. The application architecture has historically accumulated significant technical debt through the implementation of repository-controlled runtime directories containing fragmented JSON files, including supervisor, pipeline, task-ledger, provider-outbox, recovery, and health-state records. This fragmentation, combined with the reliance on organic browser fallback pulses to drive background execution, creates a fragile ecosystem highly susceptible to race conditions, silent data corruption, and catastrophic resource exhaustion. Furthermore, the explicit requirement that public GET requests must not create artificial intelligence work or mutate publication state entirely invalidates the browser fallback pulse mechanism. A reader should never be forced to keep a browser tab open to drive background compute cycles. The primary research objective is to design the absolute smallest, most durable control plane capable of operating within these hostile constraints. This control plane must wake up reliably, select a single target date, resume existing workflows, submit a bounded number of AI requests to the OpenAI Batch API, poll for accepted work, validate generated evidence, compose and publish the final brief, move seamlessly to the next missing date, and terminate cleanly when caught up. Achieving this requires an exhaustive deconstruction of the physical host limitations, scheduling mechanisms, state-storage algorithms, and finite state machine transitions.

The CloudLinux and LiteSpeed Crucible

To engineer a durable workflow engine on shared hosting, the physical limitations enforced by the host operating system and web server must dictate the software architecture. Shared hosting environments managed via cPanel overwhelmingly rely on the CloudLinux operating system to enforce strict resource isolation through Lightweight Virtual Environments (LVE)1. An application that attempts to mimic a traditional long-running daemon via PHP will be swiftly and silently terminated by the LVE kernel module.

CloudLinux LVE Restrictions

CloudLinux tracks and restricts several critical metrics that directly impact unattended PHP execution. The Entry Processes (EP) limit is a hard cap on the number of concurrent connections to Apache or LiteSpeed dynamic scripts4. If a webhook or cron job triggers a PHP script that hangs indefinitely while waiting for an external API response, it consumes an EP slot1. Exhausting this limit results in a 508 Resource Limit Reached error, which instantly takes the entire website offline for all public visitors4. Furthermore, CloudLinux tracks the Physical Memory (PMEM) utilized by the PHP processes. If a script attempts to load a large dataset into memory—such as parsing a massive JSON event log or an OpenAI Batch API JSONL output file—it will rapidly breach the PMEM limit. When this threshold is crossed, CloudLinux invokes the Out of Memory (OOM) killer. This mechanism immediately terminates the offending PHP process without warning, resulting in a Killed message in the command-line interface or a 500/503 error via the web server, simultaneously incrementing the fPMEM fault counter4. The Number of Processes (NPROC) limit caps the total number of processes operating within the user's LVE, including shell sessions and child processes spawned by PHP4. Finally, sustained high CPU usage or excessive Input/Output Operations Per Second (IOPS) will result in kernel-level throttling, artificially extending the execution time of the script until it violates the web server's connection timeouts1.

LiteSpeed Connection Lifecycle Dynamics

The LiteSpeed web server is engineered for maximum throughput and is highly aggressive regarding connection lifecycle management. By default, to conserve EP and CPU limits, LiteSpeed will silently terminate a PHP process the exact moment the client connection is closed8. For example, if a background worker relies on a webhook from an external service, and the external service drops the connection due to a timeout, LiteSpeed immediately halts the PHP script mid-execution. While it is technically possible to bypass this behavior by setting the noabort environment variable (e.g., placing RewriteRule .\* \- \[E=noabort:1\] in the .htaccess file) or by utilizing the PHP ignore\_user\_abort(true) function, deploying this configuration within a CloudLinux LVE environment is exceptionally dangerous8. Various WordPress security and backup plugins recommend this setting to prevent timeouts during large operations10. However, if a control plane script enters a retry loop or hangs on a network socket while noabort is active, the process will remain alive in the background indefinitely. Because the client has disconnected, the script is orphaned, yet it permanently consumes an EP and PMEM slot until the server administrator intervenes or the LVE faults catastrophically5. Therefore, the architectural conclusion is definitive: the control plane must be explicitly designed to execute in rapid, discrete pulses that exit cleanly and quickly. The system must never rely on long-running aborted scripts, sleep loops, or blocking network connections.

Evaluating Wake-Up Mechanisms and Scheduling Durability

The foundational requirement of the control plane is the ability to wake up reliably without human intervention. In the absence of a persistent supervisor daemon, the system must rely on episodic invocations to drive the state machine forward. To determine the optimal approach, seven distinct hosting and triggering options must be evaluated across critical operational dimensions.

Comparative Analysis of Hosting and Scheduling Options

The following table provides a structural comparison of the available scheduling mechanisms, evaluating their viability for driving a durable, state-based workflow engine.

OptionReliabilityCostSecurityState ConsistencyObservabilityRecovery After RestartSuitability for OpenAI Batch
cPanel Cron (PHP CLI)Low to ModerateFreeHigh (Internal execution)Poor (Risk of overlaps)Poor (Silent failures)ExcellentLow (Still bound by PMEM/NPROC)
External Web-Cron ServiceHighLowHigh (Requires signed endpoint)Moderate (Dependent on locking)Excellent (HTTP logs)ExcellentModerate (Bound by HTTP timeouts)
Provider Webhook DeliveryN/AN/AHighHighModeratePoor (Lost events)Poor (Unsupported by OpenAI Batch)
Managed Queue / ServerlessExceptionalLowExceptionalExceptionalExceptionalExceptionalHigh (As a trigger mechanism)
Small VPS WorkerExceptionalModerateHigh (VPN/IP Whitelist)ExceptionalExceptionalExceptionalExceptional (Unconstrained resources)
Stay on Shared (Browser Pulses)PoorFreeModerateDangerous (Race conditions)PoorFastPoor (Unpredictable execution)
Move Worker Off SharedExceptionalModerateHighExceptionalExceptionalExceptionalExceptional (Decoupled execution)

Option 1: cPanel Cron Invoking PHP CLI

This traditional approach utilizes the native cPanel cron interface to execute the PHP Command Line Interface (CLI) binary at scheduled intervals. While theoretically robust, its reliability on shared hosting is historically poor. Shared hosting administrators frequently throttle or silently drop cron executions if the server is under high load to preserve resources13. Furthermore, environment execution paths are highly volatile; /usr/bin/php might point to a CGI wrapper rather than the true CLI binary, leading to unexpected headers or parsing errors, requiring hardcoded paths like /opt/cpanel/ea-php82/root/usr/bin/php \-q14. Operational complexity is high because debugging failures requires SSH access to read /var/spool/cron or parsing raw emails piped to /dev/null13. If cron executes while a previous invocation is still running (due to CPU throttling), it causes severe concurrent execution race conditions unless strict atomic locking is implemented.

Option 2: Authenticated External Web-Cron Service

This strategy involves a reliable third-party service (such as EasyCron) sending an HTTP POST request to a secure endpoint on the shared host every minute. The endpoint must be cryptographically secured (e.g., via HMAC signatures or bearer tokens) to prevent malicious actors from triggering the workflow loop. This outsources the scheduling reliability to a dedicated infrastructure designed for observability, providing immediate logs of HTTP response codes and response times17. While the script is executed through the web server (LiteSpeed) and thus consumes an EP slot, designing the script to execute and terminate within 5 seconds entirely mitigates the risk of LiteSpeed timeouts8. Recovery after a host restart is seamless; the external service will log HTTP 503 errors during the downtime and resume successful triggers once LiteSpeed is back online.

Option 3: Provider Webhook Delivery

Instead of polling, the system could theoretically rely on the AI provider to send a webhook when a batch is complete, waking the system up to process the next step. However, the OpenAI Batch API currently requires polling and does not natively support outbound webhooks for batch completion notifications19. Implementing this would require building an external intermediary server to poll the API and forward the webhook, defeating the purpose of minimizing infrastructure. Furthermore, if the shared host is restarting when the webhook arrives, the event is permanently lost unless the intermediary supports exponential backoff and retry queues.

Option 4: Managed Queue or Serverless Scheduler

Utilizing AWS EventBridge, Google Cloud Scheduler, or an Amazon SQS queue triggering an AWS Lambda function to hit the shared hosting API provides enterprise-grade SLA guarantees. State consistency is exceptional because message queues provide native visibility timeouts and dead-letter queues (DLQ) to ensure messages are processed exactly once. However, the operational complexity is significant. It requires maintaining infrastructure as code (Terraform or AWS CloudFormation) entirely separate from the cPanel ecosystem, complicating the deployment pipeline.

Option 5: A Small VPS Worker

Provisioning a dedicated Linux Virtual Private Server (VPS) strictly to run a supervisor daemon or cron that interfaces with the shared host and the OpenAI API bypasses all cPanel LVE restrictions. The worker daemon lives outside the shared ecosystem, capable of holding long-running network connections and large memory footprints. However, this introduces high operational complexity. The engineering team is now responsible for managing a Linux server, tracking OS updates, security patches, and daemon management (systemd)21. It also requires two distinct deployment targets.

Option 6: Staying Entirely on Shared Hosting (Browser Fallback Pulses)

This approach embraces the constraints by relying on organic public traffic to "pulse" the background worker via asynchronous HTTP requests (fsockopen or cURL with a 1-second timeout), supplemented by native cron for low-traffic periods. Using fsockopen to spawn non-blocking requests is a known PHP pattern, allowing the script to return a response to the user immediately while the background process continues23. However, this violates the core project requirement that public GET requests must not create AI work or mutate state. Furthermore, relying on organic traffic pulses is chaotic and highly susceptible to race conditions when traffic spikes trigger dozens of overlapping background pulses, instantly exhausting the CloudLinux EP limit4.

Option 7: Moving Only the Worker Off Shared Hosting

This hybrid approach leaves the public-facing application on cPanel but delegates the state machine, scheduling, and OpenAI Batch API polling to an external worker. This is the most reliable architecture for large-scale applications. However, the project constraints dictate that we must not assume a long-running worker is available, forcing the control plane to survive locally on the shared host.

Scheduling Conclusion

Given the strict constraint eliminating external long-running workers, Option 2 (Authenticated External Web-Cron Service) emerges as the optimal approach. Relying on organic traffic pulses (Option 6\) is volatile and explicitly prohibited by the requirements, while native cPanel cron (Option 1\) is too opaque and prone to arbitrary administrative throttling13. An external web-cron guarantees a consistent, observable HTTP pulse. The PHP script it targets will be explicitly designed to execute a single atomic chunk of work and exit cleanly within seconds, entirely sidestepping LiteSpeed timeouts, the need for the dangerous noabort directive, and CloudLinux EP bloat.

State-Storage Options and Concurrency Control

A durable state machine requires an atomic, corruption-resistant storage mechanism to track the target publication date, the current step of the workflow, and the task ledger. In a shared hosting environment lacking Redis or RabbitMQ, the architecture is restricted to file-based or relational database storage. The historical implementation relied on fragmented repository-controlled runtime directories (JSON files), which proved inadequate.

Comparative Analysis of Storage Mechanisms

Storage OptionAtomicity & LockingConcurrent Cron SafetyCrash RecoveryQueryability & SchemaShared-Host Compatibility
Multiple JSON FilesNone (Requires flock())Highly DangerousPoor (Partial writes corrupt data)PoorHigh
Append-Only JSON LogHigh (Append locking)Safe for writes, poor for readsExcellentPoor (Requires full parsing)High
SQLiteDatabase-level (WAL limits)Fatal on NFS without WALGoodExcellentPoor (WAL mode fails frequently)
MySQL / MariaDBRow-level (InnoDB)Exceptional (FOR UPDATE)Exceptional (Daemonized)ExceptionalNative / Highly Optimized
Hybrid (DB \+ Files)Row-level (DB)ExceptionalExceptionalExceptionalNative / Highly Optimized

The Failure of Multiple JSON Files

Writing to a JSON file in PHP requires reading the file into memory, decoding it, modifying the data structure, encoding it, and writing it back to disk. If two web-cron pulses fire concurrently, the second process will overwrite the first, resulting in catastrophic state loss. While file locking via flock() exists, it is notoriously unreliable on shared hosts utilizing Network File Systems (NFS), frequently resulting in deadlocks or silently ignored locks26. Furthermore, if the CloudLinux OOM killer terminates PHP during file\_put\_contents(), the JSON file is left empty or malformed, permanently destroying the workflow state7.

The Append-Only JSON Event Log

An event-sourcing model using an append-only log solves the write-corruption issue. PHP can use FILE\_APPEND with LOCK\_EX to safely append event strings to a log file. However, reconstructing the state machine requires reading and parsing the entire file. If the log grows to 50MB, reading it into memory will immediately breach the CloudLinux PMEM limit, crashing the site on every cron pulse4. Queryability is non-existent, making it impossible to efficiently query which dates are missing or pending.

The SQLite Concurrency Trap

SQLite is a highly capable database that offers full ACID compliance. However, its concurrency model is fundamentally incompatible with the constraints of shared cPanel hosting. Standard rollback journals lock the entire database file during a write, blocking all readers and other writers22. Write-Ahead Logging (WAL) mode solves this by allowing concurrent readers and a single writer22. However, WAL mode requires the creation of a shared memory (-shm) sidecar file. On cPanel servers, home directories are frequently mounted via NFS or Virtuozzo filesystems that do not fully support mmap or the specific POSIX locking required for WAL. In fact, CloudLinux explicitly disables WAL for its own internal statistics daemons because it triggers persistent "database is locked" errors for non-root users27. Without WAL, concurrent cron pulses will inevitably collide, causing fatal exceptions.

MySQL / MariaDB (InnoDB)

MySQL provides full ACID compliance and utilizes the InnoDB storage engine, which features Multi-Version Concurrency Control (MVCC) and row-level locking22. A SELECT ... FOR UPDATE query perfectly solves the concurrent cron invocation problem by blocking subsequent queries until the first transaction commits. Furthermore, because MySQL runs as a separate daemon (mysqld) outside the user's direct PHP LVE memory space, querying large datasets does not count against the PHP process PMEM limit, preventing OOM terminations21.

The Hybrid Database Plus Immutable Files Architecture

While MySQL is ideal for tracking the state machine, it should not be used to store massive 200MB JSONL payloads from the OpenAI Batch API. Storing large binary blobs in MySQL degrades buffer pool efficiency and increases backup times. The optimal architecture is a hybrid model: MySQL stores the highly mutable, strictly locked state machine (Target Date, Current State, Lock Expiry Timestamp), while the filesystem stores large, immutable artifacts (OpenAI JSONL requests/responses, composed HTML evidence). This leverages MySQL's row-level locking to guarantee atomicity when the web-cron pulses, while offloading heavy payload storage to immutable files that do not require complex locking21. By utilizing a single MySQL table named workflow\_ledger, the PHP script can execute an atomic lock acquisition query:UPDATE workflow\_ledger SET state \= 'processing', lock\_expires\_at \= NOW() \+ 60 WHERE date \= '2026-08-08' AND state \= 'queued' AND (lock\_expires\_at IS NULL OR lock\_expires\_at \< NOW()); If the affected row count returned to PHP is exactly 1, the script has safely acquired the lock and proceeds. If the affected row count is 0, another process is handling it, and the script exits cleanly, preventing duplicate work.

Designing the Minimal State Machine

A workflow engine running in a fragmented, episodic environment must act as a mathematically precise finite state machine (FSM). The states proposed in the research objective must be evaluated for minimality and sufficiency. The core philosophy is that no single PHP execution should run longer than a few seconds, completely avoiding LiteSpeed connection aborts and CPU throttling.

Critique and Validation of Proposed States

The proposed state array consists of:

1. queued

2. research-submitted

3. research-waiting

4. research-ready

5. composition-submitted

6. composition-waiting

7. ready-to-publish

8. published

9. needs-review

10. failed

While seemingly verbose, this 10-state structure is perfectly optimized for a constrained environment characterized by abrupt process termination. If an architect attempted to reduce the states by merging research-submitted and research-waiting into a single researching state, the system would lose critical idempotency information. In a shared host where a PHP script can be instantly killed by the CloudLinux OOM killer7, the FSM must explicitly track the boundary between the internal system and the external provider. It must differentiate whether a network request to the AI provider was successfully dispatched (submitted) versus when the system is merely waiting for the asynchronous provider to finish its background compute (waiting). If a script is killed during a unified researching state, the subsequent cron pulse would have no deterministic way of knowing if the OpenAI Batch API was actually called. This ambiguity risks a duplicate submission, doubling API costs and corrupting the ledger.

State Machine Transition Matrix

The following table defines the minimal safe FSM, mapping the entry conditions, actions, exit conditions, and failure recovery mechanisms for each state.

Current StateAction Executed by Cron PulseNext State on SuccessFailure Recovery Mechanism
queuedGenerate JSONL prompt payload and write to local disk.research-submittedRestartable. No external API mutations have occurred.
research-submittedUpload .jsonl to OpenAI, create Batch, save batch\_id.research-waitingIf killed during network call, query OpenAI for orphaned batches before retrying.
research-waitingPoll OpenAI /v1/batches/{batch\_id} for completion status.research-readyCompletely safe. Cron pulse simply exits if status is not completed.
research-readyDownload output .jsonl, validate evidence, prepare composition payload.composition-submittedIf validation fails heavily, transition to needs-review.
composition-submittedUpload composition .jsonl, create Batch, save new batch\_id.composition-waitingSame recovery as research-submitted.
composition-waitingPoll OpenAI for composition batch completion.ready-to-publishSafe to poll indefinitely.
ready-to-publishParse final HTML, inject into CMS/Database via transaction.publishedUses MySQL transaction. Rollback on failure, preventing partial publishes.
publishedTerminal State. Bootstrap query triggers next missing date.N/AN/A
needs-reviewTerminal State (Human intervention required due to bad data).Manual UnblockN/A
failedTerminal State (Systemic API error, missing files).Manual UnblockN/A

Deadlock Resolution via Lock Expiry

Because the PHP process can be killed abruptly without executing a catch block or shutdown function, the state machine must utilize a locked\_until column in the database to prevent permanent deadlocks. When the web-cron pulse picks up a state (e.g., research-ready), it issues an UPDATE query setting locked\_until \= NOW() \+ 120 seconds. If the PHP script is suddenly killed by the CloudLinux OOM killer because the JSONL file was slightly too large, the database state remains research-ready, but the lock is now ticking down. The next cron pulse will query the table, see the lock is active, and cleanly exit. Once the 120 seconds have elapsed, a subsequent pulse will "steal" the expired lock, allowing the system to self-heal and retry the phase.

Integrating the OpenAI Batch API Flow

The OpenAI Batch API is specifically designed for asynchronous, deferred execution, offering a 50% cost reduction and a 24-hour completion window, bypassing rate limits associated with synchronous endpoints19. The engineering challenge is bridging a stateless, constrained PHP script with the large JSONL file payloads required by the Batch API.

Overcoming JSONL Memory Constraints

The Batch API requires payloads to be formatted as JSON Lines (.jsonl), with each line representing an independent API request containing a unique custom\_id used to map results back to the source19. The maximum batch size is 200MB or 50,000 requests30. While the Daily Brief will likely be smaller than 200MB, even a 15MB JSONL file can cause fatal issues if manipulated entirely in memory via json\_encode() or file\_get\_contents() on a strict shared host. The system must stream the JSONL file to and from the disk line-by-line using PHP's native fopen(), fwrite(), fgets(), and fclose() functions. This streams the data sequentially, utilizing only kilobytes of RAM rather than megabytes, completely bypassing the PMEM limits of CloudLinux and eliminating OOM terminations.

The Asynchronous Submission Flow

When the FSM enters the research-submitted state, the following atomic sequence occurs:

1. The PHP script opens the previously generated local .jsonl file.

2. It uploads the file to OpenAI via POST /v1/files using cURL with the CURLOPT\_INFILE parameter to stream the payload off the disk directly to the network socket, avoiding memory bloat.

3. It receives a file\_id from OpenAI.

4. It calls POST /v1/batches with the file\_id and the target endpoint (e.g., /v1/chat/completions)19.

5. It receives a batch\_id.

6. It updates the MySQL FSM row to research-waiting and saves the batch\_id to the ledger.

7. The PHP script exits cleanly. This entire network sequence takes approximately 3 to 5 seconds, remaining well within the LiteSpeed connection timeout window and utilizing minimal EP time.

The Polling and Retrieval Flow

When the FSM is in the research-waiting state:

1. The external web-cron hits the PHP endpoint.

2. The PHP script reads the batch\_id from the MySQL ledger.

3. It calls GET /v1/batches/{batch\_id}.

4. If the response status is validating, queued, or in\_progress, the batch is still computing30. The PHP script simply exits with an HTTP 200 OK response. Time elapsed: \~1 second.

5. If the response status is completed, the script updates the state in the database to research-ready and immediately exits.

Crucially, the system defers the heavy download phase to the next cron pulse. By separating the status check from the file download, the system ensures that no single HTTP pulse attempts to perform too much work, which is the primary cause of LiteSpeed timeouts and CloudLinux CPU throttling1. When mapping the output back to the database, the custom\_id in the JSONL payload must encapsulate the target date and the specific component index (e.g., dbrief\_2026-08-08\_section\_1). When the results are downloaded line-by-line in the research-ready state, the FSM uses this custom\_id to map the responses back to the local CMS database accurately.

Orchestrating the Control Plane: Ensuring Reliability and Pure GET Requests

The architecture detailed above is inherently resilient, but specific operational requirements from the research objective must be explicitly mapped to the system's behavior to guarantee unattended operation.

Bootstrapping and Finding Missing Dates

To fulfill the requirement of moving to the next missing date, the web-cron pulse utilizes a "bootstrap" query mechanism. When the pulse fires, it first checks if any row in the workflow\_ledger is currently active (i.e., not in the published, failed, or needs-review terminal states).

  • If an active row exists, the system processes that row's next state transition.
  • If no active row exists, it queries the publication calendar, identifies the oldest date that lacks a corresponding published state, and creates a new FSM row for that date in the queued state.

This mechanism ensures that missing dates are processed strictly sequentially, completely unattended. Once the system is caught up and no missing dates exist, the bootstrap query returns null, and the PHP script exits immediately in milliseconds. This satisfies the requirement to "stop cleanly when caught up," consuming negligible CPU and entirely freeing the host's resources1.

Protecting Public GET Requests and Ensuring State Consistency

A foundational requirement is that public GET requests must not create AI work or mutate publication state, and a reader should never need to keep a page open. The legacy architecture violated this by relying on browser fallback pulses. This new architecture rigidly bifurcates reads from writes. Public GET requests to the Daily Brief interface only read from the finalized published tables in MySQL. The FSM is triggered only by the secured external web-cron endpoint via an HTTP POST request. The web-cron script authenticates via a pre-shared cryptographic key, executes exactly one transition in the workflow\_ledger, and terminates. Organic visitors to the website have absolutely no code path that intersects with the FSM, ensuring that traffic spikes cannot inadvertently trigger AI work, exhaust EP slots, or mutate the publication state.

Recovery After Host Restart or Deployment

Because the workflow state is heavily persisted in MySQL before any network action is taken, a host restart is a non-event. If the host reboots, the external web-cron will receive HTTP 503 errors and temporarily fail. Once the host is back online, the cron will hit the endpoint, query the workflow\_ledger table, find the row with a lapsed locked\_until timestamp, and resume exactly where it left off. If a code deployment occurs (overwriting PHP files) while a pulse is actively executing, the current execution might crash with a fatal require() error. Again, the system relies on the lock expiry mechanism. The lock will expire, and the subsequent pulse will simply run the newly deployed code against the existing, uncorrupted database state.

Conclusion

Designing a durable control plane within the confines of a legacy PHP shared hosting environment requires discarding the paradigms of modern persistent microservices and embracing the constraints of episodic, stateless execution. The assumption that a background worker daemon is available must be replaced by a mathematical reliance on atomic database locks and strictly bounded execution windows. The optimal, minimal control plane for the Daily Brief relies on an authenticated external web-cron service to provide reliable, observable HTTP pulses. These pulses drive a 10-state finite state machine stored securely within a MySQL InnoDB table, which leverages row-level locking to prevent concurrency collisions and race conditions. Large artifacts, specifically the JSONL payloads required by the OpenAI Batch API, are streamed to and from the immutable filesystem to bypass CloudLinux PMEM limitations, while the API's asynchronous nature offloads the compute burden from the web server entirely. By restricting every PHP execution to a single, rapid state transition, the system guarantees immunity from LiteSpeed connection aborts and CPU throttling, ensuring the Daily Brief runs unattended, recovers seamlessly, and publishes reliably.

Works cited

1. CloudLinux LVE Limits Explained \- Shared License, https://sharedlicense.com/cloudlinux-lve-limits-explained/

2. Understanding LVE Resource Limits \- Ultra Web Hosting Documentation, https://docs.ultrawebhosting.com/cloudlinux/lve-limits

3. Understanding CloudLinux and LVE Limits \- WebGee Community, https://community.webgee.com/d/19-understanding-cloudlinux-and-lve-limits

4. Limits \- CloudLinux Product Documentation, https://docs.cloudlinux.com/cloudlinuxos/limits/

5. CloudLinux Issues | Troubleshooting | LiteSpeed Web Server, https://docs.litespeedtech.com/lsws/cp/cpanel/ts-cloudlinux/

6. What does the PMEM LVE limit affect \- CloudLinux, https://cloudlinux.zendesk.com/hc/en-us/articles/5503038402844-What-does-the-PMEM-LVE-limit-affect

7. Long running PHP process randomly stops with message 'Killed' \- Server Fault, https://serverfault.com/questions/770948/long-running-php-process-randomly-stops-with-message-killed

8. PHP Without Timeout | LiteSpeed Web Server, https://docs.litespeedtech.com/lsws/cp/cpanel/long-run-script/

9. LiteSpeed Web Server: Enable "noabort" \- CSSIgniter, https://www.cssigniter.com/kb/litespeed-web-server-enable-noabort/

10. Wordfence and LiteSpeed, https://www.wordfence.com/help/advanced/system-requirements/litespeed/

11. Printing “Demo Content Import issue with LiteSpeed webservers” \- Ticksy, https://amentotech.ticksy.com/article/15237/?print

12. Using Noabort to fix Wordfence issues on Litespeed \- Russ Michaels Consulting, https://michaels.me.uk/using-noabort-to-fix-wordfence-issues-on-litespeed/

13. cPanel cron jobs: setup, debugging, and when to stop using them \- Crontap, https://crontap.com/guides/cpanel-cron-jobs

14. Setting up cronjob questions \- cPanel Support, https://support.cpanel.net/hc/en-us/community/posts/19128094391575-Setting-up-cronjob-questions

15. EasyApache 4 and the ea-php-cli Package \- cPanel & WHM Documentation, https://docs.cpanel.net/ea4/php/easyapache4-and-the-ea-php-cli-package/

16. What is the Correct Path to Use for PHP Binaries? \- Hawk Host, https://www.hawkhost.com/kb/programming/php/what-is-the-correct-path-to-use-for-php/

17. How to Configure Cron Jobs in cPanel: A Complete Technical Guide \- AlexHost, https://alexhost.com/faq/how-to-configure-cron-jobs-in-cpanel/

18. How to disable LiteSpeed connection timeouts \- Krystal Hosting Knowledge Base, https://help.krystal.io/web-hosting/how-to-disable-lite-speed-connection-timeouts

19. Batch API \- OpenAI Developers, https://developers.openai.com/api/docs/guides/batch

20. Save 50% on OpenAI API Costs Using Batch Requests \- Miko Engineering Blog, https://engineering.miko.ai/save-50-on-openai-api-costs-using-batch-requests-6ad41214b4ac

21. SQLite vs MySQL CMS: When the Small Database Wins \- UnfoldCMS, https://unfoldcms.com/blog/sqlite-vs-mysql-for-cms

22. SQLite vs MySQL: Architecture, Performance, and When Each Actually Matters \- AlexHost, https://alexhost.com/faq/sqlite-vs-mysql-what-is-the-difference-and-does-it-matter/

23. 18738 (Improving cron spawning and other non-blocking HTTP requests) \- WordPress Trac, https://core.trac.wordpress.org/ticket/18738

24. fsockopen \- Manual \- PHP, https://www.php.net/manual/en/function.fsockopen.php

25. PHP: Visit URL async and get response without blocking \- Stack Overflow, https://stackoverflow.com/questions/17487305/php-visit-url-async-and-get-response-without-blocking

26. Is PHP flock safe in multithreaded mode on linux? \- Stack Overflow, https://stackoverflow.com/questions/11415746/is-php-flock-safe-in-multithreaded-mode-on-linux

27. Fix the SQLite database is locked error in Hermes \- LumaDock, https://lumadock.com/tutorials/fix-hermes-database-locked-error

28. CloudLinux OS components, https://docs.cloudlinux.com/cloudlinuxos/cloudlinux\_os\_components/

29. SQLite vs MySQL: Which Database Should You Use? | Contabo Blog, https://contabo.com/blog/sqlite-vs-mysql-which-database-should-you-use/

30. How to Use Batch Inference | DigitalOcean Documentation, https://docs.digitalocean.com/products/inference/how-to/use-batch-inference/

31. GitHub \- hesenp/openai\_batch\_helper: Helper library to make OpenAI batch API calls easier. No need to wrestle with JSONL any more., https://github.com/hesenp/openai\_batch\_helper