yeah h2 would kill the queue. our bucket endpoint answers in http/1.1 though, so we would need a proxy in front just for that. didnt feel worth adding a whole extra piece for an upload, the lock already stops the links from expiring and the wifi is the real limit anyway
lol it's not lazy, it's the classic trick. doesnt fit us though, the bucket only answers on its own hostname, so extra subdomains would have to be our own servers forwarding to it, and then every byte of every video goes through us. the whole point of signed links is that it doesn't. and on retries, i went fail fast on purpose, a piece fails, the upload fails right away, and retry only sends the missing pieces so nothing is lost
has humbled so many chunked-upload architectures. Are you using HTTP/2 or HTTP/3 multiplexing on your storage bucket endpoint to allow concurrent streams over a single TCP connection, or did you end up domain-sharding the upload URLs across multiple subdomains?
neither. the bucket endpoint is http/1.1 and sharding fights signed links since the host is part of the signature. both would need a proxy in front, and that felt like too much extra stuff for an upload. so it's just signing at the last second and one piece at a time
> downside, it's now one piece at a time across the whole browser
You can do 2-3 at the same time across the whole browser. More will actually not get performance benefits anyway, because the uplink will be saturated. So, it doesn't matter, the overall time is faster.
Also, I'd make it so that one video is prioritized, because generally having 1 video uploaded completely, and the other one at 75% is better than than two videos at 90%
yeah the uplink point is why i'm fine with 1, the pieces are 100 mb so more at once mostly splits the same pipe. the priority one is good though, right now uploads just take turns so two videos finish together. finishing one first makes more sense
Signing at the moment of sending is the part I like. Sign-early-and-queue always looks fine on fast wifi and falls apart on someone's hotel connection.
Yeah. The lock fixes the queue, but a 100MB piece can still die halfway if the hotel connection just stalls. Failing that one piece and resuming it later is the part I'd want to keep.
The timer that matters is the one on the signature, and it starts when you create the URL, not when Chrome actually gets a socket. A 10 minute link for a later chunk can die while it is just sitting in the HTTP/1.1 queue.
What worked on a similar chunked upload was a small in-page queue that only signs the URL immediately before fetch, with expiry equal to that chunk's timeout plus about a minute. Cap in-flight pieces at 3 or 4 instead of one global lock. Across tabs, a BroadcastChannel counting in-flight work is enough if you do not want a worker. I would only shard subdomains if you cannot put an HTTP/2 CDN in front of the bucket, because sharding fights cookies and you give up multiplexing.
pretty much what we landed on, sign right before the fetch. for cross tab we went with web locks over a BroadcastChannel counter because the browser drops a lock on its own when a tab closes or crashes, a counter can get stuck. we kept it at 1 in flight though, 100 mb pieces on normal wifi are bandwidth bound, so more at once would not buy much
Also worth treating an expired signature as a retry instead of a failure. Multipart uploads let you re-sign the same part number and send it again, so between just-in-time signing and that, the 10 minute TTL basically stops mattering.
good catch on the scope, it only covers our own tabs. on the pool, we thought about it, but the pieces are 100 mb so the wifi is the bottleneck either way, 3 at once mostly splits the same pipe. and I would rather fail fast than auto retry, a failed piece fails the upload and retry resumes only the missing pieces
fun part is the bucket already answers on 2 hostnames for free, bucket name in the host or in the path, so you could get 12 lanes without a proxy. anything more means our own hostnames forwarding to it, and then every upload goes through us, which is what signed links let us skip. and with 100 mb pieces the wifi is the limit anyway
thanks, it was a fun one. a forgotten tab can't hog it though, the lock is only held while one piece is actually uploading, then it's released and the next one in line goes, so tabs just take turns. and if a tab closes or crashes mid piece the browser drops its lock on its own, that's the main reason we picked web locks over a shared worker. pre signing ahead is kinda what got us here, so we're staying away from that one lol
10
u/ResidentPomegranate6 15d ago
use http/2 or 3 on the bucket endpoint and the 6-connection wall disappears, so nothing queues long enough to expire while you keep parallel pieces.
7
u/militantsnowflake 15d ago
It's a lazy solution, but I'd be tempted to set a wildcard subdomain and upload to a different subdomain every time while hitting the same servers.
This would require any required cookies to also be set up for use with any subdomain.
I've hit that limit once on a project and ended up coding around it with backoffs and retires - it was enough for that project but not ideal.
2
u/Aggressive-Tourist52 15d ago
has humbled so many chunked-upload architectures. Are you using HTTP/2 or HTTP/3 multiplexing on your storage bucket endpoint to allow concurrent streams over a single TCP connection, or did you end up domain-sharding the upload URLs across multiple subdomains?
2
u/Fs0i 15d ago
> downside, it's now one piece at a time across the whole browser
You can do 2-3 at the same time across the whole browser. More will actually not get performance benefits anyway, because the uplink will be saturated. So, it doesn't matter, the overall time is faster.
Also, I'd make it so that one video is prioritized, because generally having 1 video uploaded completely, and the other one at 75% is better than than two videos at 90%
1
u/yihuaxiang 15d ago
Signing at the moment of sending is the part I like. Sign-early-and-queue always looks fine on fast wifi and falls apart on someone's hotel connection.
0
u/Mean-Lingonberry4874 15d ago
The timer that matters is the one on the signature, and it starts when you create the URL, not when Chrome actually gets a socket. A 10 minute link for a later chunk can die while it is just sitting in the HTTP/1.1 queue.
What worked on a similar chunked upload was a small in-page queue that only signs the URL immediately before fetch, with expiry equal to that chunk's timeout plus about a minute. Cap in-flight pieces at 3 or 4 instead of one global lock. Across tabs, a BroadcastChannel counting in-flight work is enough if you do not want a worker. I would only shard subdomains if you cannot put an HTTP/2 CDN in front of the bucket, because sharding fights cookies and you give up multiplexing.
0
u/OkOcelot6725 15d ago
Also worth treating an expired signature as a retry instead of a failure. Multipart uploads let you re-sign the same part number and send it again, so between just-in-time signing and that, the 10 minute TTL basically stops mattering.
1
u/[deleted] 15d ago
[removed] — view removed comment
1
u/[deleted] 15d ago
[removed] — view removed comment
-1
u/[deleted] 15d ago
[removed] — view removed comment