An SQS queue instead of one long-running function
Rather than one long-running function per batch, SQS orchestrated the whole migration. Each message was a small, idempotent unit that could fail and be retried without touching anything already done. The Lambda timeout stopped being a limit on how much could be migrated at once.
More moving parts and more infrastructure to reason about, in exchange for a job that could survive being interrupted at any point.