Simplest example of http streaming chunks in Motoko

Just posting this here as documentation if it’s helpful. There should be better documentation on how to get http chunk streaming to work, since there’s a 2MB (1.9MB to be safe including headers) chunk limit on http requests and canister calls.

This example creates an output of firstchunk__middlechunk__middlechunk__middlechunk__lastchunk
https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/?tag=3614308521
if you go to:
http://raw.ic0.app/?canisterId=

Example code is also here:

Happy coding!

6 Likes

What’s your experience with its performance?

From my testing locally with my own Motoko http_request and http_request_streaming_callback… it’s slow. My frontend tries to fetch ~20 1-2 MB photos all at once from a single canister, and it takes more than a couple seconds to fetch them all.

If that’s the case, I don’t think canisters are gonna be performant enough to act as CDNs for photos / videos, and I might need to turn to IPFS.

It’s not fast, although I haven’t measured performance. I agree that IPFS is for sure faster.

2 Likes

Well damn I wonder why IPFS is faster (if it truly is)…

Not sure if the speed bottleneck is due to Motoko, or due to the http_request functions, or due to single-threaded canisters… maybe I’m doing something wrong.

Good question. I will ping team to see if anyone knows.

2 Likes

Wanna compare?

The following is a jpg 2.3mb image I uploaded and serve from the “asset” canister I implemented by myself: https://s2cv6-gaaaa-aaaai-aa5tq-cai.raw.ic0.app/images/2-3mb.jpg?token=c2ffb294-0413-45fa-b36e-492a705fd36e

Without cache, fastest download I got was once 1.5s and around 2.5s but, slowest is 6s. Often get something around 4s.

2 Likes

Are you sure those method declared as queries are actually being called as queries? For example, ‘dfx canister call’ vs ‘dfx canister call --query’. With dfx it’s possible to call a query method with much slower full consensus requirements and that’s even the default IIRC.

1 Like

I think in this case the image is being fetched directly through HTTP, where the boundary node translates the GET request to a query call.

It does seem rather slow. Clicking on the link took more than 4 seconds initially and at least 2 seconds on further clicks.

For comparison, I uploaded the exact same image to Google Firebase Storage (link: https://firebasestorage.googleapis.com/v0/b/deckdeckgo-studio-prod.appspot.com/o/TLsaIXLLIwdmA2PSV1DcEHGMva23%2Fassets%2Fimages%2F2-3mb.jpeg?alt=media&token=0b071105-7bc7-4b83-add9-8f5991049c9c).

In such conventional CDN it takes around 800ms - 1s to download the file.

I get 2.5s to 6s for my implementation with the IC and http_request + streaming.

So, I actually see it as positive kind of, sure it’s slower but it’s quite different tech. Being said, maybe it is possible to improve the speed of the delivery?

6 Likes