# Managing concurrency
Source: https://www.inngest.com/docs/functions/concurrency

Limit the number of concurrently running steps for your function with the [`concurrency`](/docs/reference/functions/create#configuration) configuration options. Setting an optional `key` parameter limits the concurrency for each unique value of the expression.

[Read our concurrency guide for more information on concurrency, including how it works and any limits](/docs/guides/concurrency).

<CodeGroup>
```ts {{ title: "Simple" }}
export default inngest.createFunction(
  {
    id: "sync-contacts",
    concurrency: {
      limit: 10,
    },
  }
  // ...
);
```
```ts {{ title: "Multiple keys" }}
inngest.createFunction(
  {
    id: "unique-function-id",
    concurrency: [
      {
         // Use an account-level concurrency limit for this function, using the
         // "openai" key as a virtual queue.  Any other function which
         // runs using the same "openai"` key counts towards this limit.
         scope: "account",
         key: `"openai"`,
         // If there are 10 steps executing with the "openai" key, this function's
         // runs will wait for capacity before executing.
         limit: 10,
      },
      {
         // Create another virtual concurrency queue for this function only.  This
         // limits all accounts to a single executing step for this function, based off
         // of the `event.data.account_id` field.
         // "fn" is the default scope, so we could omit this field.
         scope: "fn",
         key: "event.data.account_id",
         limit: 1,
      },
    ],
  }
  { event: "ai/summary.requested" },
  async ({ event, step }) => {
  }
);
```
</CodeGroup>

Setting `concurrency` limits are very useful for:

* Handling API rate limits - Limit concurrency to stay within the rate limit quotas that are allowed by a given third party API.
* Limiting database operations or connections
* Preventing one of your user's accounts from consuming too many resources (see `key`)

Alternatively, if you want to limit the number of times that your function runs in a given period, [the `rateLimit` option](/docs/reference/functions/rate-limit) may be better for your use case.

## Configuration

<Properties>
  <Property name="concurrency" type="number | object | [object, object]">
    Options to configure concurrency. Specifying a `number` is a shorthand to set the `limit` property.

    <Properties nested={true}>
      <Property name="limit" type="number" required>
        The maximum number of concurrently running steps.
        A value of `0` or `undefined` is the equivalent of not setting a limit.
        The maximum value is dictated by your account's plan.
      </Property>
      <Property name="scope" type="'account' | 'env' | 'fn'">
        The scope for the concurrency limit, which impacts whether concurrency is managed on an individual function, across an environment, or across your entire account.

        * `fn` (default):  only the runs of this function affects the concurrency limit
        * `env`:  all runs within the same environment that share the same evaluated key value will affect the concurrency limit.  This requires setting a `key` which evaluates to a virtual queue name.
        * `account`:  every run that shares the same evaluated key value will affect the concurrency limit, across every environment.  This requires setting a `key` which evaluates to a virtual queue name.
      </Property>
      <Property name="key" type="string">
        An expression which evaluates to a string given the triggering event.  The string returned from the expression is used as the concurrency queue name.  A key is required when setting an `env` or `account` level scope.

        Expressions are defined using the Common Expression Language (CEL) with the original event accessible using dot-notation. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info. Examples:

        * Limit concurrency to `n` (via `limit`) per customer id: `'event.data.customer_id'`
        * Limit concurrency to `n` per user, per import id: `'event.data.user_id + "-" + event.data.import_id'`
        * Limit globally using a specific string: `'"global-quoted-key"'` (wrapped in quotes, as the expression is evaluated as a language)
      </Property>
    </Properties>
  </Property>
</Properties>

<Callout>
The current concurrency option controls the number of concurrent _steps_ that can be running at any one time.

Because a single function run can contain multiple steps, it's possible that more functions than the concurrency limit are triggered, but only the set number of steps will ever be running.
</Callout>