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 your functions sometimes complete in a different order than they were invoked.
Both synchronous and asynchronous invocations have a function container limit of 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 and memory usage. When the limit is reached, currently executing invocations in that container fail and an Out of Memory message is logged in the function log stream.
Include only the necessary libraries and packages to reach the function container limit less often. For example, only import the methods necessary for your function instead of importing an entire library.
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 have 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 function invocation with Heroku Data in Salesforce Functions to safely and effectively process and data across invocations.
Stay within memory limits while developing your 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 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.