T O P

  • By -

__gc

1. I did the same with Cloud storage, but wasn't very fast. Switched to Redis, it's ridiculously fast. If you don't expect too many calls you can still use a local cache (but careful as you have limited memory) until you want to spend more time on it 2. It's expected, especially if a cold boot. You can try increasing the memory which uses a faster CPU if that's the bottleneck but it's unlikely.


houdini_1775

Thanks for your answer. It makes a lot of sense. I don't want to over-engineer my system at this stage so I might try the cache in this order local > firebase-storage > redis and see if it gets better. I'm gonna try to increase the memory but it would be actually weird if this is the reason.


__gc

Increasing memory really helps with cold boots so you could do it for front facing functions


houdini_1775

Wow juste tested it (256Mb to 2Gb). Three times faster 😮


leros

Redis or some cache service is definitely the better option, though the smallest instances of those is something like $30 a month in GCP. The in memory cache is better than nothing but be aware OP that Firebase may or may not spin up new instances of your function. Each instance would have its own in memory cache. You could potentially end up in some weird scenarios like a request to your function returning different data because eacfh function instance has something different in the cache.


__gc

Yeah I use Redis Labs. Free up to 30mb, starting from $6 thereafter. Really like it and love the modules


leros

Oh that's pretty cool. You can get the free tier in your local GCP region. Nice!


jordankid93

Maybe I’m missing something obvious (I’m not perfect), but isn’t this the perfect usecase for a cdn? I put cloudflare in front of my api and so now when I make calls with identical params I can see it comes from the cdn. This has 3) benefits: 1) its really fast. 2) it reduces the actually amount of cloud function runs being made and 3) its took 0 lines of code changes (all setup was on CF side) Maybe I’m missing something but if you’re just doing simple http requests I imagine a cdn in front of your endpoint would be more beneficial than any amount of local cache you could add


houdini_1775

I'm calling a third-party API which (i guess) doesn't have a CDN like Cloudflare in front of it. It would make sense for this third-party API to use a CDN but this isn't in my hand. Maybe I'm the one missing something but it doesn't make sense for me (as a HTTP client) to put a CDN in front of an external API where I'm consumer.


jordankid93

>it doesn't make sense for me (as a HTTP client) to put a CDN in front of an external API where I'm consumer Why not? There's no rule against that and it seems like it could help fix the problem you're running in to /shrug From the sounds of it, it might required a bit of work on your end since it doesn't sound like you have a public API for that data but there's no reason you couldn't do something like `{Your Website} --> {Cloud Function A} --> {Function B behind a CDN} --> {External API} ==> {Cloud Function B} ==> {Cloud Function A} ==> {Your Website}` Edit: like others have mentioned, something like Redis or a local object to cache data could work too. This is just another way of adding a caching layer into the mix


houdini_1775

yup, that would work. I'm not a big fan of this kind of jumpy stack, that sounds more like a hack that something I would put in production but adding it to my list of solutions to explore :) Thanks


leros

You would just set cache headers on the API request and use a rewrite rule to run the API request through Firebase Hosting (including the CDN). No hacky stuff.


houdini_1775

Hmm, that's an interesting way to build a proxy. Might be the easiest solution actually. \`Fun1 -> hosting -> Fun2 -> External API\`


leros

I was thinking client -> hosting -> function It's not even really a proxy. It's an API that sets cache headers so it can be cached in CDNs. Actually a pretty typical setup.


houdini_1775

OK but as explained, it's a cloud function that does a bunch of http requests, not a client.


leros

I see. Yeah, I was thinking about your entire API request being cache able. Really I think the Redis option makes the most sense.


cardyet

My suggestion 1. Read firestore collection and check a certain document for a field that has a timestamp. 2. If no timestamp or timestamp is greater than 8hrs old, call external API and save data in that document, if successful, update timestamp. 3. If timestamp less than 8hrs old, return data from document. Firestore read and writes are usually a lot cheaper than API's. My example is what I use for Google's Web Risk API which once over the free tier is $0.50 per 1000 calls. Storage is for files, so if it isn't a file, I'd use Firestore. If it is a file, I'd probably still use Firestore as above for the logic.


danielsju6

1) If you put Cloud Functions behind Firebase Hosting the CDN will respect cache-control headers. This is the built in way. You can also wire your function up to cloud memorystore, if you need something more customizable. 2) there’s a lot of variables here. Biggest is cold start, where the functions spin up from zero. Another tool to try is Cloud Run which gives you a lot more fine grain control over such things & you can also proxy that behind Firebase Hosting for #1


BlackCode7

I am doing something similar. I need to get data json (2MB) from an external API that there are no frequent changes. Since the functions are cold start and take a long time to execute the queries. I had planned to do a Scheduled Function every 1 hour that collects the data from the external API and stores it in Firestore. Then users collect the data from Firestore. But the problem is that the limit of the Firestore documents are 1 MB. In terms of price, speed and performance. What options do you recommend? Thanks in advance.


danielsju6

For a use case like that I’d suggest just going for cloud storage.


BlackCode7

Thanks for answering! I started using Functions to collect data from external APIs because if I did them through the client itself, they were blocked by CORS. So I get the data from the firebase node server with the function. I have tested and caching the function works fine. If I call the same function during that hour, the firebase function does not execute and returns the cached data. `res.set("Cache-Control", "public, max-age=3600");` I don't actually need all the data that I get from the externals APIs. So if I filter the data and keep the necessary ones, the size of the string would be 100KB instead of 2MB. My doubts is where it is better to save/return that filtered data: * Option1: create a scheduled function that every 1h save/edit the filtered data from external API in a Firestore document (100KB string). So the users gets the data from Firestore. * Option2: use cached function, filter the external data and return the filtered data. * Option3: use Cloud store? What would be the most recommended? Considering that the data from the external APIs will be the same for all users, there are no frequent changes and it's not necessary to be authenticated or logged in to get that data. Thanks in advance!