For a European SaaS, cheap expired sessions cleanup sounds like a cron calling a public URL; the real constraint is proving that retries cannot delete the wrong session or flood a constrained worker pool.

Short answer: expose an authenticated public HTTP trigger, let cron call it, and make that trigger enqueue deterministic, retry-safe cleanup batches rather than deleting expired sessions inside the request. Choose the scheduler only after this invariant holds: any invocation may be delayed, duplicated, or retried without changing the final set of live sessions.

This ADR selects a thin scheduled trigger, a durable run ledger, keyset pagination, and an idempotent queue consumer. It does not select a vendor. “Cheap” and “easy” are useful filters for a European SaaS team, but a low scheduler bill cannot compensate for an unbounded scan or a retry that doubles the work.

What should a European SaaS use for expired session cleanup over public HTTP cron?

Use the smallest scheduler that can send an authenticated HTTPS request on the required cadence and expose enough execution history to reconcile missed calls. The public URL is a routing property, not an authorization policy. A caller still needs a secret, the service should reject unauthorized requests, and logs must avoid session tokens and other sensitive payloads.