Ask
96
@dockerfile_yuki ·

server action or route handler for 12mb video uploads, two devs and a month Mutations

Users upload short screen recordings, typically 8-14 MB. Sending the File in FormData to a server action 413s at about a megabyte. I can raise bodySizeLimit but I am nervous about pushing 12 MB through a serverless function that also has a duration limit, and there are two of us with roughly a month before we have to show this working.

8 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @wild_ferment · last mo. · 3 replies

    Neither. The bytes should never touch your function.

    Action A checks the session and returns a presigned PUT URL for R2 or S3. The browser PUTs the file straight to the bucket. Action B (or a bucket event) writes the row once the object exists. Your function moves a few hundred bytes per upload and there is no body limit to configure.

    Two details that will save you an afternoon each: sign the content-length so someone cannot swap in a 4 GB file against your URL, and use XHR rather than fetch if you want a real progress bar, because upload progress events are still the thing XHR does better.

    118
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @dax_darian · last mo.

      And if these recordings get watched more than once, R2's egress pricing is the difference between a hosting line item and a hosting problem. We moved 900 GB/month of video out of S3 for that reason alone.

      30
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
    • @wild_ferment · last mo.

      Expiry matters too — 15 minutes is plenty for a 12 MB upload. Long-lived signed URLs end up pasted into a chat somewhere and become an open write endpoint.

      14
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @gpio_gwen · last mo.

    If you insist on keeping it in the app: raising bodySizeLimit works, and it is genuinely fine for a 2 MB avatar. For 12 MB over a phone connection you are paying function wall-clock for the whole transfer, and a user on bad hotel wifi can sit there long enough to hit your duration limit. The failure mode is a timeout after 90 seconds of uploading, which is the most infuriating possible error.

    47
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @nadia_brill · last mo.

    On the one-month constraint specifically: presigned upload is an afternoon, including getting the CORS rule right, which is the only annoying part. I spent most of a week last year making streamed uploads through a serverless function behave, and then deleted it for presigned URLs anyway. Pick the boring one first.

    33
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @slowtrainjo · last mo.

    Multipart when you eventually support 500 MB files, not now. At 12 MB a single PUT with a retry is the whole feature.

    15
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @kitchen_table_talk · last mo. · 2 replies

    Base64 the file into the action payload and you avoid the FormData handling entirely.

    6
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @gradschool_gary · last mo.

      That is 33% bigger and still fully buffered, so it is worse on both axes he was worried about.

      5
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report