TL;DR
The engineering decision is conditional: multipart is justified for a large AI-generated image when retrying a whole object would harm the upload SLO; the application should create and complete the session, the uploader should send presigned parts directly to S3-compatible object storage, and abort plus lifecycle cleanup belong in the initial design. A single presigned upload remains the least complex choice for modest files and dependable links.
The useful unit here is not an object. It is an upload session with an owner, an expiry, and one terminal state. Treating it that way keeps the data plane out of Node.js while leaving authorization and reconciliation in a service that can be observed.
The incident lesson: bytes are cheap; unfinished state is not
A production review of an image pipeline should start with a boring question: what remains after the process that began an upload has gone away?…