# Invoke Functions Locally

Functions can be invoked locally for development and testing purposes. Local Invocations don’t impact [Functions Limits](/docs/platform/functions/guide/limits.md).

## Run Local Invocation

You can run and invoke your function locally using the Salesforce CLI. Before invoking locally, make sure you've created a scratch org with Salesforce Functions enabled, as described in [Develop Functions Using Scratch Orgs](/docs/platform/functions/guide/scratch-orgs.md). Also make sure your functions permission set is configured properly as described in [Function Permissions](/docs/platform/functions/guide/permissions.md).

:::important
You can only have one function running locally at a time.
:::

### Start the Function Locally Using Salesforce CLI

Navigate to the function directory and build and run your function:

```sh
sf run function start
```

### Start the Local Function Using Container

Alternatively build and run your function locally in a container, like Docker. Make sure your container software is running, then run:

```sh
sf run function start container
```

The function is ready to receive requests when you see `Starting {FunctionName}`. Leave the terminal window running and use a new terminal window for the next step.

## Invoke the Locally Running Function Using CLI

To test a running function, send it a JSON payload. Pass the payload inline or create a `payload.json` file in your function directory:

```json
{
  "name": "MyAccount",
  "accountNumber": "123456789",
  "industry": "Technology",
  "type": "Prospect",
  "website": "www.salesforce.com"
}
```

Navigate to your project root directory and invoke the function:

```sh
sf run function -l http://localhost:8080 -p '@functions/myfunction/payload.json'
```

:::tip
On Windows, remove the single quotes:

```sh
sf run function -l http://localhost:8080 -p @functions/myfunction/payload.json
```
:::

This command invokes the function running on localhost port 8080 (the default for locally running functions), with the payload JSON file. You see output similar to:

```sh
Using defaultusername MyScratchOrgAlias login credential to initialize context
POST http://localhost:8080... 200
{
  "done": true,
  "totalSize": 1,
  "records": [
    {
      "type": "Account",
      "fields": {
        "id": "00163000012fAD0AAM",
        "isdeleted": false,
        "masterrecordid": null,
        "name": "MyAccount-1623718504016",

        ...fields omitted...

        "yearstarted": null,
        "sicdesc": null,
        "dandbcompanyid": null,
        "operatinghoursid": null
      }
    }
  ]
}
```

The execution logs stream in the terminal running the function. The output looks something like this:

```sh
{"level":30,"time":1623718504015,"pid":1,"hostname":"39f3353de3f7",
"invocationId":"a9c869ab-2130-42e0-9615-b342c8b97bd1","msg":"Invoking
 Myfunction with payload {\"name\":\"MyAccount\",
 \"accountNumber\":\"123456789\",\"industry\":\"Technology\",
 \"type\":\"Prospect\",\"website\":\"www.salesforce.com\"}"}
```

To invoke the function with an inline payload:

```sh
sf run function -l http://localhost:8080 -p '{"id": 12345}'
```

On Windows, escape any double-quote marks (“) in the payload with a backslash (”\“). For example:

```sh
sf run function -l http://localhost:8080 -p '{ \"id\": 12345 }'
```

Have your locally running function connect to the scratch org by providing the scratch org alias with the `-o` argument.

:::tip
You often set your scratch org alias when you create your scratch org, as described in [Develop Functions Using Scratch Orgs](/docs/platform/functions/guide/scratch-orgs.md). Visit [Create a Scratch Org](/docs/platform/functions/guide/create-dx-project.md) for help on creating and configuring your scratch org.
:::

```sh
sf run function -l http://localhost:8080 -p '{ "id": 12345 }' -o TestScratchOrg
```

## Stop Function Locally

The function continues to run and waits for requests until you stop the function. Stop the running function by pressing CTRL-C in the terminal where your function is running.
