Short answer: use a scheduled HTTP trigger to start a bounded cleanup run, then drain a queue-backed worker pool when the e-commerce workload is large, rate-limited, or likely to outlive one run. Keep the trigger small, make each batch idempotent, and measure recovery time rather than admiring a green schedule.

This is a retention problem with a recovery requirement. An online store may have expired carts, abandoned checkout attempts, or old event rows to remove while the same database is serving shoppers. The cleanup must yield to the rate limit, survive duplicate delivery, and resume after a worker or scheduler disappears.

The schedule is only the signal. The batch is the unit of recovery.

Start with the retention ledger

Start with a stable cutoff, not an exact minute. At the beginning of a run, record the retention policy and a timestamp such as “older than this cutoff.” Select a bounded page of records, process it, and commit the result before acknowledging its work item. A later run can use the same age predicate and collect anything left behind by a missed or paused trigger.