Learn Functions Patterns and Best Practices

Use Salesforce Functions development patterns to improve workflow while building effective and durable functions projects.

Note Function Invocation Run Time

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.

<!-- > ## Choose the Best Invocation Method for Your Function ### Use Synchronous or Asynchronous Invocation Choose either a synchronous or asynchronous invocation and construct the function to avoid timeouts as much as possible. A _synchronously_ invoked function can run for 2 minutes before the invocation times out, and _asynchronous_ invocations can run for up to 15 minutes. The limit for both is enforced in Core and by Apex. The function importantly continues to run to completion, and when the Apex callout terminates the response from the invocation won't be received. Apex invoking a function that times out must recover from this kind of error. :::important The function code continues to run and can communicate back with the org. The timed out function can insert records, thus generating CDC events, or even send Platform Events itself. This behavior will change in the future when the timeout is enforced by providing a means to terminate long running invocations. ::: -->

Stay Within Process Memory Limits

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.

<!-- UPCOMING FEATURE? #### Process Invocations with Interactive or Batch Invocations For interactive invocation proessing, real-time use cases when a user is waiting for a response can be synchronous or asynchronous. Response time and function execution duration depends on what the function does. When using batch invocations to process functions, a function can be invoked faster than your org can handle requests coming from your Function to query or update record data in your objects. Be sure to consider the rate at which functions are invoked to ensure their response or callback don't exceed daily API limits for Functions. Consider bulkifying functions and payloads when batch processing to avoid calling to your org and using resources uneccesarily. When using your Function to do batch processing of your org data, bulkify the work within the Function itself. For example, instead of invoking a Function to process a single record (and then invoking that Function multiple times, possibly in a loop, from Apex), consider passing a set of record IDs that the Function can work on. You can send up to a 6-MB payload (12 MB for async invocation) per invocation. This way, you can use that payload limit to send a batch of IDs, or even a SOQL query string that the Function can use to get the set of records to operate on. :::tip Consider [Flow Bulkification on Transactions](https://help.salesforce.com/s/articleView?id=platform.flow_concepts_bulkification.htm&type=5) to utilize payload size and needlessly avoid hitting limits. ::: Alternatively, implement database operations in the calling or responding Apex logic after the function invocation is complete. For example, Batch Apex job execution is limited by the compute work it performs, and such jobs execute faster if they're mostly tasked with invoking asynchronously Functions. As such if you're invoking Functions from this context keep in mind the data access those Functions perform and their usage of the Functions Daily API limit. -->

Track Function State Across Invocations

important: 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.

Prevent Out of Memory Errors

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.