An action in Gadget is a unit of work that your application can perform, like saving a record or processing a webhook. Actions define the behavior of the application.
How does an action work?
Actions execute as serverless JavaScript functions mounted inside the Gadget framework, triggered by one of Gadget's built-in triggers. Actions can be run by user interactions, API calls, incoming webhooks, all without having to write the standard boilerplate code to process requests, authorization, or responses. Actions remain fully customizable, allowing developers to implement custom logic like input validation, record updates, third-party API interactions, and more.
Types of actions
There are 2 types of actions in Gadget:
Model-scoped actions: API endpoints that run in the context of specific records within a model
Globally-scoped actions: Run outside the context of any particular record
Each model-scoped action and globally-scoped action in Gadget follows the same pattern. A trigger starts an action, then permissions are checked, and then the action's handler functions are executed to do the actual work.
This is the specific sequence that Gadget runs:
Action Execution Flow
Triggering the Action: An action begins when triggered. Triggers are typically GraphQL API mutations but can also include webhooks from third-party services or scheduled cron jobs. Think of triggers as the when of running an action.
Permission Verification: Gadget ensures that the caller has the necessary permissions to execute the action. This is determined by the current user's role or the API key being used. Think of permissions as the who of an action. For more details, see the access control guide.
Loading the Record: For model-scoped actions, the relevant record is automatically fetched from the database, eliminating the need for manual data retrieval.
Executing the run Function: The run function is executed within a database transaction. It handles data-related operations such as modifying records, making API calls, and logging information. Think of run as the what of an action.
Handling Post-Execution Logic (onSuccess): If the run function completes successfully and the transaction commits, the onSuccess function is executed. This function is used for post-processing tasks that should only run after the main action succeeds, such as sending notifications or triggering webhooks. It is particularly useful for ensuring that follow-up actions, like responding to external services (e.g., Shopify webhooks), only occur once all necessary data is saved.
Globally-scoped Actions share all the same properties as model-scoped actions, but they don’t operate in the context of a specific record and don’t automatically load any data. However, they can still interact with data using the api object. This allows them to query records, create or update data, and fetch related information from different models as needed. For example, a globally-scoped action could be used to generate reports, process bulk data, or retrieve a list of users without being tied to a single record.
Action code
Actions are each expressed in their own JavaScript file, which runs on Gadget's serverless Node.js hosting. Within the run and onSuccess functions in these files, actions can modify the database, make outbound API calls, change the user's session, or perform any other desired operations using the helpers from gadget-server or packages from npm.
Triggers in Gadget are mechanisms that capture events from external sources, such as incoming webhooks or API calls, and initiate the execution of actions. They serve as the starting point for the action's workflow by parsing the event data and passing it along for further processing. Triggers can be pre-configured defaults, like the GraphQL API trigger or Shopify Webhook triggers, or they can be custom-defined based on specific requirements.
For more information on types of triggers see the Triggers guide.
Background actions
Background actions in Gadget allow certain tasks to be executed asynchronously, ensuring that the main application logic can continue without waiting for these tasks to complete. These actions are suitable for time-consuming tasks that don't need to block user interactions or API calls, such as processing webhook events, sending bulk notifications, or generating reports.
Background actions are executed on serverless workers, each allocated 2GB of memory and sufficient CPU power to manage typical background tasks, such as webhook processing or report generation. This infrastructure enables long-running tasks to be processed asynchronously, ensuring that the main application flow remains uninterrupted. The orchestration of these background jobs is managed by Temporal, which efficiently queues and executes tasks in the background. Temporal also handles retries, scheduling, and error management, ensuring that tasks are completed successfully and resources are freed up for other operations.
Background Action Limits
Concurrency: The maximum concurrency for background actions is 100. This means up to 100 background actions can run at the same time. For apps requiring higher concurrency, Gadget support can help with adjustments based on specific use cases.
Payload Size: Each background action has a payload size limit of 100MB when serialized using msgpack. If your task involves larger data, consider storing the data in Gadget's file storage and passing file references to your background actions.
Enqueue Rate: In production environments, the maximum rate for enqueuing background actions is 200 actions per second, with a burst capacity of 600 actions per second. In development environments, the enqueue rate is limited to 80 actions per second, with a burst capacity of 240 actions per second. Exceeding these limits will result in a GGT_TOO_MANY_REQUESTS error. For higher enqueue rates, contacting Gadget support is recommended.