UploadThing is 5x Faster

V7 Is Here!

This release has been an absurd amount of work. So proud of the team and what we've built. Huge thanks to Julius and Mark for making this happen.

It is so, so hard to not go straight into the nerdy details, but the whole point of UploadThing is that you don't need to know ANY of those details. With that in mind, here's what's relevant for most of y'all:

  • UploadThing is now way faster
  • Uploads can be paused and resumed seamlessly (huge for users on bad internet connections)
  • We added support for Remix
  • We've started to shut down the legacy infra from the initial UT launch

Ready to upgrade? Julius wrote an awesome guide to get you going.

Before we go into the nerdy details, I want to brag a bit about the speed.

Benchmarks

These benchmarks tested the simplest possible "full-stack" UploadThing implementation. You can see the implementation on GitHub

Multiple images test

4713ms (v6) -> 1250ms (v7) 377% faster

Single image test

3733ms (v6) -> 733ms (v7) 509% faster

The Road To V7

Our initial goal with UploadThing was simple: Make user-facing file uploads as safe and easy as possible. Might be a bold statement, but I think we achieved that.

The next step was obvious: Make UploadThing the best way to upload files as well. Which means moving away from S3 direct uploads.

Wait, how can you possibly be better than S3?

Hear me out.

Every upload has 4 touch points: User's Browser, Your Server, UploadThing API, and S3.

The steps looked like this:

  1. User's Browser requests presigned URL from Your Server
  2. Your Server requests an S3 presigned URL from UploadThing API
  3. Your Server sends S3 presigned URL to User's Browser
  4. User's Browser uploads to S3
  5. UploadThing API called by event listener when upload is complete
  6. UploadThing API calls Your Server to notify of upload completion
  7. Your Server runs onUploadComplete hook
  8. User's Browser (which has been polling this whole time) finally gets a success response.

This worked incredibly well, and has scaled great. But the sheer number of hops has been...not great.

This isn't even touching on the unique issues with uploading directly to S3:

  • No resumability
  • No validation on ingestion (i.e. checking file sizes, types, safety)
  • No control over what happens after upload

It was time to make some big changes. It was time to move off of serverless.

UploadThing Has Servers now

Yep. I've finally caved. UploadThing now has servers. And oh man, the results are incredible.

First, let's look at how much simpler the flow is (note the addition of UploadThing Ingest Server):

  1. User's Browser requests presigned URL from Your Server (this is now generated by your server)
  2. User's Browser uploads directly to UploadThing Ingest Server
  3. UploadThing Ingest Server uploads straight to our storage and notifies Your Server on completion (no more event listeners)
  4. Your Server runs onUploadComplete and sends response to UploadThing Ingest Server
  5. UploadThing Ingest Server sends onUploadComplete response directly to User's Browser as part of the presigned post request

We cut the number of hops in HALF. We removed the need for polling entirely. We no longer block uploads starting on our API's verifying the upload. And with all these changes, we cut the amount of JS in our client side bundle by over 30%.

...and we're just getting started

This infra overhaul enables us to do a LOT more cool stuff with UploadThing. Things like content analysis and detection, transcoding, "bring-your-own-bucket" and much, much more. We're so hyped for what's next.