Learn Functions Patterns and Best Practices
Use Salesforce Functions development patterns to improve workflow while building effective and durable functions projects.
Run time for Salesforce Functions varies for each function invocation based on its dependencies, complexity, and payload. Even the same function can take a different amount of time for each invocation. This variability means that functions may not complete in the same order they were invoked.
For both synchronous and asynchronous invocation, there's a limit of 1 GB for process memory for each function container.
Salesforce Functions automatically increases or decreases the number of function containers available to handle invocations based on CPU load. Each function container can handle multiple concurrent invocations. As a result, the total available memory in a function container is shared across all concurrent invocations.
The platform shuts down the container and starts a new one when the total memory footprint exceeds the limit of 1 GB. Concurrently running invocations and other overhead contribute to process memory limit in the function container. When the limit is reached, currently executing invocations in that container fail and an Out of Memory message is logged in the functions log stream.
Using global variables or writing files to the filesystem opens subsequent functions to errors and wasted resources. For instance, containers cycle out regularly with each deployment, removing any files written to the filesystem. For the safest and most efficient approach, Heroku Data in Salesforce Functions is considered the best practice when sharing data across invocations.
Salesforce Functions run in a stateless model, which means nothing automatically persists from invocation to invocation. A function can't make any assumptions about system caches or filesystem content. Similarly, a function can't rely on information generated in a previous run. Manage and pass state information or other data between invocations in a separate data store you control, like your org. When a function uses initial state of variables at run time, set that state in the function code that gets run during invocation. Don't use either a global variable or external package. Instead, use a custom object or Apex platform cache.
If you do need to persist information across multiple invocations, store it in a file or somewhere outside of memory. Instead of a cache in memory, use Heroku Data to create a Heroku Redis store. Enable stateful functions invocation with Heroku Data in Salesforce Functions to safely and effectively process and data across invocations.
Prevent Out of Memory Errors
Stay within memory limits while developing functions with some safe practices:
- Keep functions simple and focused on a specific task that can complete quickly.
- Conserve memory by deploying functions with only the essential libraries.
- Profile response times for when connecting to external services from functions, like Heroku, Mulesoft, and Slack.
- Test functions to gauge average execution time and memory use per invocation.
- Test functions in a development environment with payloads that you expect in the production environment to make sure response times are acceptable.