What Cloud Run CPU and Memory limits do App Engine Standard instance classes map to? - google-app-engine

I am migrating from App Engine to Cloud Run. App Engine Standard instance classes are defined here. I would like to know to what CPU and Memory configuration they map to in Cloud Run.

tl,dr: An F4 App Engine instance is roughly equivalent to 1 CPU and 1Gi Memory in Cloud Run.
Memory: This table shows exactly how much memory each instance class gets:
CPU: Cloud Run doesn't give details about the CPU frequency (it might change over time), it only guarantees a CPU quantity. F1 and F2 App Engine instances map to 0.25 and 0.5 CPU in Cloud Run, selecting a CPU < 1 in Cloud Run comes with limitations on other settings (e.g. concurrency). So the recommendation is to pick 1 CPU for these instance classes too.
App Engine instance class
Cloud Run CPU equivalent
Cloud Run Memory equivalent
F1
0.25
256 MiB
F2
0.5
512 MiB
F4
1
1 GiB
F4 _1G
1
2 GiB

Related

Higher than expected number of GAE instances

I run a nodejs backend on Google App Engine for my website app (which is hosted statically elsewhere). My QPS is very low:
However my number of instances regularly goes above 1, to 2 and sometimes as high as 3 or 4. This blows past the free quota and I start have to pay.
My cost were below $0.1 per month but now are regularly above $8 which is a worrying trend. My user base or their patterns haven't really changed significantly to explain this (and as mentioned the QPS are low IMHO).
I noticed that the memory usage is relatively high and I'm wondering if I should investigate potential memory leaks in my app.
More background on the app: it mostly handles auth and fetches and stores data into MongoDB Atlas.
I would go with a 2 step process
First 'temporarily' set your maximum_instances to 1 in your app.yaml file. This means your server will only spin up 1 instance. This comes with a risk that if you have a spike in traffic, it might be slow for some people.
app.yaml
automatic_scaling:
max_instances: 1
Then investigate if you have memory leaks in your code and see how you can optimize your code. If you discover your issues and fix it, you can remove the max_instance or raise the value.
From the screenshots you’ve shared, I can see that your number of instances increases as your memory usage does, and decreases in the same way. Therefore, I would recommend increasing the amount of memory that is assigned to every instance to use less instances for serving your application. As this guide recommends to begin testing your application:
start with a lower machine (1 core CPU and 1 GB RAM) and increase the minimum instances that the App Engine should spawn instead
Also, the guide says that:
Since App Engine bills you on the number of Cores and RAM used per hour, you can save up to 40% of your costs by using the former setup with lower machines
From that, it is better to have more memory allocated to an instance to avoid excessive costs.
In the App Engine pricing page, it says that:
Billing for the memory resource includes the memory your app uses plus the memory that the runtime itself needs to run your app. This means your memory usage and costs can be higher than the maximum memory you request for your app.
In your app.yaml configuration file, you can set the parameter memory_gb that is set to 0.6 GB by default.
The requested memory for your application, which does not include the ~0.4 GB of memory that is required for the overhead of some processes. Each CPU core requires a total memory between 0.9 and 6.5 GB.
To calculate the requested memory:
´memory_gb = cpu * [0.9 - 6.5] - 0.4´
Additionally, you should check your code for memory leaks to avoid your application consuming more memory than expected.
Finally, you can use the pricing calculator to estimate the costs for your application based on the tweaks you do on your application.

Google Cloud App Engine Instance Class / CPU Speed

I'm trying to set up a single backend worker on Google Cloud App Engine. I have a YAML file that defines (among other things):
env: flex
resources:
memory_gb: 2
cpu: 1
instance_class: B8
...
I can control the memory size, the number of processors, but I need a faster CPU. I set instance_class: B8, but it doesn't help (probably works just for the Standard environment, not Flex).
Is there a way to control which instance (i.e. CPU speed) to run it on?
You cannot specify the CPU speed. You can specify the number of cores and the RAM.
App Engine Flexible Resource Settings
The Instance Type B8 is used with App Engine Standard and not Flexible.
Review the App Engine Flexible pricing for additional information.

What does the CPU Limit mean for App Engine instances?

I created a site on App Engine and chose the smallest F1 instance class which according to the docs has a CPU Limit of 600 MHz.
I limited the app to 1 instance only as a test and let it run several days then checked the CPU utilization on the dashboard. Here's part of the chart:
As you can see the utilization which is given in Megacycles/sec which I assume equals to one MHz is between like 700 and 1500.
The app uses one F1 instance only, runs without problems, there are no quota errors, but then what does the 600 Mhz CPU limit mean if the utilization is usually above it?
Megacycles/sec is not MHz in this graph. As explained in Interface QuotaService:
Measures the duration that the current request has spent so far
processing the request within the App Engine sandbox. Note that time
spent in API calls will not be added to this value. The unit the
duration is measured is Megacycles. If all instructions were to be
executed sequentially on a standard 1.2 GHz 64-bit x86 CPU, 1200
megacycles would equate to one second physical time elapsed.
In App Engine Flex, you get an entire CPU core from the machine you are renting out, but in App Engine Standard, it shows the Megacycles since it uses a sandbox.
Note that there is a feature request in the issue tracker on adding CPU% metric under gae_app for App Engine standard and I have relayed your concern about it to the Cloud App Engine product team. However, there is no guarantee of the implementation and ETA at this time. I recommend to star the ticket so that you would receive updates about it.

Initial requests to datastore and cloud tasks have higher latency, is that normal?

My app engine service is written in Go. I have code that connects to Cloud Datastore before even the server listens on the port. There is a single Projection query that takes about 500ms reading just 4 entities. Does the first interaction with datastore have higher latency potentially as a connection needs to be established? Any way this datastore connection latency be reduced? Also, is there any difference in doing this db call before listening to the port vs doing it within the warmup request (this is an autoscaled instance).
Similar to high initial latency for Cloud Datastore, I see a similar pattern for Cloud Tasks. Initial task creation could be as high as 500ms but even subsequent ones are any where from 200 to 400ms. This is in us-central. I was actually considering moving a db update to a background task but in general I am seeing the latency of task creation to be more or less same as doing a transaction to read and update the data giving no net benefit.
Finally, instance startup time is typically 2.5 to 3 seconds with the main getting called after about 2 seconds. My app startup time is the above mentioned project query cost of 500ms and nothing else. So, no matter how much I optimize my app startup, should I assume an additional latency of about 2 seconds?
Note that the load on the system is very light so these issues can't be because of high volume.
Update: deployment files as requested by Miguel (this is for a test environment investigating performance characteristics. Prod deployment will be more generous for instances)
default app:
service: default
runtime: go112
instance_class: F1
automatic_scaling:
min_instances: 0
max_instances: 1
min_idle_instances: 1
max_idle_instances: 1
min_pending_latency: 200ms
max_pending_latency: 500ms
max_concurrent_requests: 10
target_cpu_utilization: 0.9
target_throughput_utilization: 0.9
inbound_services:
- warmup
backend app:
service: backend-services
runtime: go112
instance_class: B1
basic_scaling:
idle_timeout: 1m
max_instances: 1
200-500ms to initialize a client seems reasonable because there is a remote connection being established. Also, a 1-2 seconds cold start for App Engine also seems normal.
As you mentioned, you can experiment with a warmup request to reduce cold starts and initialize clients.
I would also recommend looking into the mode you are running your Datastore in (native vs datastore). There is increase latency when using datastore mode, for more info see Cloud Datastore Best Practices.

Google App Engine Instance is abruptly shutting down on Standard Environment

We are using Google App Engine to ingest large amount of data to Google Cloud FireStore with below configuration:
Basic scaling
instance_class: B4
basic_scaling:
instances: 1
The overall data ingestion 0f 20GB takes around 1.5 hours. But we have noticed that some time after an hour, instance is abruptly shutting down with below error:
Container terminated on signal 9.
As per this documentation, basic scaling can serve he request up to 24 hours.
We can not see any more details in the logs as well. Also checked the memory usage, B4 has 1024 MB and the app is only utilising up to 700 MB.
If anyone has faced this kind of error, your input would be valuable!
Although the instance has 1024MB, the Operating System also needs some of that space - I guess that's why it shuts down. It's out of memory.

Resources