UploadThing is 5x Faster
- Theo Browne
CEO @ Ping Labs
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:
- User's Browser requests presigned URL from Your Server
- Your Server requests an S3 presigned URL from UploadThing API
- Your Server sends S3 presigned URL to User's Browser
- User's Browser uploads to S3
- UploadThing API called by event listener when upload is complete
- UploadThing API calls Your Server to notify of upload completion
- Your Server runs
onUploadComplete
hook - 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):
- User's Browser requests presigned URL from Your Server (this is now generated by your server)
- User's Browser uploads directly to UploadThing Ingest Server
- UploadThing Ingest Server uploads straight to our storage and notifies Your Server on completion (no more event listeners)
- Your Server runs
onUploadComplete
and sends response to UploadThing Ingest Server - 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.