Separating storage key from original filename early is one of those decisions that quietly prevents a long list of later problems - path traversal, unicode collisions, two users uploading report.pdf, and the awkward day you need to rename a file without touching the object. Content hashing next to derivative assets is the other pairing I would highlight, since hashing is what lets you notice that a supposedly new upload is byte-identical to one you already processed, and reprocessing is usually the expensive part. On orphaned object detection: the direction that bites is deleting the database row while the object survives, because the object costs money forever and nothing references it any more. Worth deciding explicitly which side is the source of truth for existence, and reconciling in that direction only.