A cron trigger should enqueue small, repeatable work, while queue workers own the long-running shipment fanout. The deciding constraint is not the timer; it is making retries harmless when a worker, network call, or subscriber fails halfway through.
A 15-minute execution cap changes the shape of the system. Instead of keeping one scheduled process open while it contacts every clinic, pharmacy, and patient-facing app, let the scheduler publish bounded tasks and let workers resume from durable state. I use an outbox row plus an idempotency key for each subscriber delivery. That pairing is less exciting than a clever cron expression, but it survives restarts.
Shipment event data contract and retention
A shipment status such as in_transit looks like one event. In a healthtech workflow it can fan out to dozens of subscribers, each with a different timeout and authentication policy. If the cron process sends notifications inline, one slow endpoint holds every later delivery hostage. A retry then risks sending the earlier messages twice.
The safer unit is a delivery record: shipment ID, subscriber ID, event version, attempt count, next attempt time, and a stable deduplication key. The scheduler finds due records and enqueues them. A worker claims one record, sends the update, and marks the exact version as delivered. A crash before the mark causes a retry; the receiver must therefore treat the key as idempotent too. In practice, that record is also the audit trail a support engineer needs when a care team says an update arrived late. It should tell you which event version was selected, which attempt owned the lease, when the request left your system, and whether the response was accepted, rejected, or unknown after a timeout. I have seen teams keep only a final sent boolean, then spend hours reconstructing a timeline from scattered logs. That is a bad trade for a workflow where a duplicate can confuse a patient or trigger a second downstream action. Keep the state transitions explicit, retain enough history to explain them, and let retention policy—not convenience—decide when old delivery rows leave the database.






