Use initializer to initialize functions, e.g. setting up database connection, downloading models.
- Initialization is separated from request handling, which makes it easier for users to write programs with clearer logic, better structures, and better performance.
- Function code is smoothly updated and performance loss caused by business layer cold start is avoided. When a function instance starts, the system performs initialization before handling requests.
- If more function instances are required because of heavy business load, the system estimates the overhead of business layer cold start. Then, it precisely calculates the timing for resource scaling and the amount of resources needed. This process minimizes the delay in handling requests.
- Even if you keep your functions running without updating them, Function Compute may still release or replace a container in use. Even though a system layer cold start is not necessary, a business layer cold start is triggered. In this case, you can use the initializer to minimize the impact of the business layer cold start.
See this article for more details.
Multi-concurrency per instance
- Reduces the total duration and saves costs
Functions that require input/output operations can process multiple requests in one instance to minimize the total duration on multiple instances.
- Provides shared state for requests
Multiple requests in one instance can share the connection pool of the database to minimize the connections between requests and the database.
- Reduces the frequency of cold starts
Fewer instances need to be created because multiple requests can be processed in one instance, which reduces the frequency of cold starts.
- Reduces the number of IP addresses used in a virtual private cloud (VPC)
For a fixed number of requests to be processed, the number of occupied instances is reduced when each instance can handle multiple requests. Therefore, the number of IP addresses used in the VPC can be reduced.
See Concurrent requests in a single instance for more details.
- Use NAS if function runs a command that talks to file system, e.g. ffmpeg.
- Use NAS if you need to persist data across multiple functions. e.g. in a map-reduce job, mapper functions write data to separate files, and reducers can easily process them. For more information, see Build an audio and video processing system with elasticity and high availability based on Serverless architecture.
- Use NAS if function depends on some libraries that you do not want to package in the code.
See Configure NAS for more details.
Function instance limit
To prevent unexpected calls from generating unnecessary charges, you can configure the maximum number of pay-as-you-go instances for a function. This feature can prevent a large number of instances being occupied by a single function due to excessive calls, protecting backend resources and avoiding unexpected charges. For example, the account 123456789 has three functions: function-a, function-b, and function-c. You can specify a maximum of 10 pay-as-you-go instances for function-a. Then a maximum of 10 instances are used to process requests when you call function-a. See Configure the maximum number of pay-as-you-go instances.
- Keep the code size small if possible. For example, removing unused dependencies and data files from code package; taking advantage of the built-in modules.
- Select proper memory and runtime settings for optimal cold start performance.
- On-demand function instances can also be pre-warmed by time triggered invocations.
- Enable multiple concurrent requests per instance for certain workload (e.g. IO bounded) so one instance can serve multiple requests, e.g. when there is a sudden traffic increase, this setting allows the existing instances to serve the requests while requesting more instances to be allocated in the background.
- Do the initialization work in Initializer handler. For example, the initialization tasks may load large models for deep learning, setup database connection pools, or load dependent libraries. To minimize the effect caused by business layer cold start on the delay in handling requests, Function Compute introduces the initializer interface. The initializer locates the initialization logic in the user functions and optimizes scheduling.
- Configure provisioned instances if workload is latency sensitive. This feature allows users to provision certain number of function instances which are ready to serve requests all the time and hence eliminate the cold-start time completely. Traffic that cannot be served by provisioned instances are served by on-demand instances.
See article for more details.
- Avoid using VPC if possible. If you have to, try to put functions that use VPC in one service and functions that do not use VPC in another service.
- In VPC configuration, it's recommended to specify two or more vSwitches in the vSwitchIds field. This allows your functions to be executed in other subnets when an error occurs in the zone or IP addresses are insufficient. If multiple vSwitch IDs are specified in the vSwitchIds field, Function Compute selects one when it creates an Elastic Network Interface (ENI), see how to configure VPC access.
- If you have problem connecting database, another service in VPC, using this tool may help.
Do not use root account access key because root account can do anything and there is no way to configure what it can access. Use RAM user access keys instead. For more information, see Use RAM to manage user permissions and resources.
You can use the tagging feature to add teams to different groups and grant different permissions to different groups. For more information, see Use tags to perform group-based service authorization.
Restrict the function invocation to certain VPCs
After a function is created, it can be invoked through the public and private endpoints by default. For security purposes, if you want to allow functions to be invoked over a specified Virtual Private Cloud (VPC) only, but not the public and private networks, you can bind a specified VPC to the service, see Allow a specified VPC to invoke functions for more details.
Access other services
- Do not hard-code access key/secret in the function because it is easy to leak the keys by accident. Try to set service role if possible and use the temporary access tokens from the function execution environment.
- When defining service role, try your best to use the least-privilege authorization policy.
Password, secrete keys
If you can not use service role, e.g. accessing a database with username and password, encrypt them with KMS and configure function environment with the encrypted key, and decrypt them with the context access key during function initialization like this information.
Async invocation configuration
Function can be invoked synchronously or asynchronously, e.g. OSS invokes functions asynchronously and API gateway invokes functions synchronously. Since the sync invocation returns result, the client knows whether the invocation succeeds or not. But for async invocation, the status and result of function execution are not returned. To ensure reliable async invocation or build event driven applications, a destination can be configured for a function. If the result of the asynchronous invocation meets the condition (onFailure/onSuccess), Function Compute sends the context and data of the asynchronous invocation to the specified service. This allows cloud services to interact with each other. You can configure different destinations for different functions, aliases, and versions. The following destination services for asynchronous invocation are supported: MNS queue, MNS topic, Function Compute, EventBridge. See Manage asynchronous invocation configurations for more details.
Use VSCode plugin and Funcraft for local development. They allow you to run functions locally and do step-by-step debugging. For more information, see Run and Debug Functions locally through the API.
The Fun Local tool can fully simulate and run the functions in Function Compute locally and provides the single-step debugging feature, which makes up for Function Compute shortcomings when compared with traditional application development experience, and provide users with a new way to solve Function Compute problems. See Run and Debug Functions locally for more details.
Install 3rd party dependencies
Installing third-party dependencies is a big pain point. However, Fun install solidifies the best practices into tools based on previous experiences and achievements, which is convenient for users to install dependencies, see Develop Function Compute by Installing Third-Party Dependencies for more details.