The drag-and-drop is the easy part. Everything underneath is the actual ticket.

The browser side of file upload is a few hours’ work. The rest of it is a feature. Size limits get hit by the first user with a 4K phone camera. Virus scanning is non-negotiable the moment you accept anything from the public. Resumable uploads matter as soon as someone tries a 2GB file on hotel wifi. Object-storage costs become real once retention is unbounded and someone starts uploading their backups.

The estimate depends on which of these the team is in scope for, and which are deliberately punted. “Upload a file” without that context is sizing the picker, not the system.

What gets said in the room

Frontend: “Drag-and-drop with a progress bar — half a day.”

Backend: “Where do the bytes go? S3? Disk?”

Security: “Are we virus-scanning? What’s the max size?”

SRE: “Resumable uploads, or do they have to start over on a dropped connection?”

Finance: “Storage costs? How long do we keep them?”

Questions worth asking before voting

  • Max file size, max files per user, max total per account?
  • Allowed MIME types — and is the check authoritative or advisory?
  • Storage backend: S3, local disk, bring-your-own bucket?
  • Virus scanning — synchronous, async, or none?
  • Retention: forever, time-limited, user-deletable?
  • Resumable uploads, or single-shot only?
  • Public URLs, signed URLs, or auth-gated download?

Each “yes” here is a slice of scope. If the answers pull in scanning, resumability, and retention all at once, that’s not one number — it’s a story worth splitting.

Size the storage, the scanning, and the retention — the picker is the cheapest part.

Adjacent: estimating a payment integration for the same operational-tail shape, and the other worked estimation examples. Open a free planning poker session when storage and retention have answers.