[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [Task](https://evolu.dev/docs/api-reference/common/Task) › createSemaphoreByKey

## Call Signature

```ts
function createSemaphoreByKey<K>(
  initialPermits: Int1To100OrPositiveInt,
  options?: CreateSemaphoreByKeyOptions<K, unknown>,
): SemaphoreByKey<K>;
```

Defined in: [packages/common/src/Task.ts:6004](https://github.com/evoluhq/evolu/blob/dd96d79f1dbe9a49fa12ce8e0aa7d3d0177795ca/packages/common/src/Task.ts#L6004)

Creates a [SemaphoreByKey](https://evolu.dev/docs/api-reference/common/Task/interfaces/SemaphoreByKey).

### Example

```ts
import {
  assertOk,
  assertTrue,
  createRun,
  createSemaphoreByKey,
  ok,
  type Task,
} from "@evolu/common";

// Each host gets an independent two-download limit.
const downloadsByHost = createSemaphoreByKey<string>(2);
const download = (host: string, file: string): Task<string> =>
  downloadsByHost.withPermit(host, () => ok(`${host}/${file}`));

await using run = createRun();
assertOk(
  await run(download("a.example", "index.json")),
  "a.example/index.json",
);
assertTrue(downloadsByHost.isIdle("a.example"));
```

## Call Signature

```ts
function createSemaphoreByKey<K, L>(
  initialPermits: Int1To100OrPositiveInt,
  options: CreateSemaphoreByKeyOptions<K, L>,
): SemaphoreByKey<K>;
```

Defined in: [packages/common/src/Task.ts:6010](https://github.com/evoluhq/evolu/blob/dd96d79f1dbe9a49fa12ce8e0aa7d3d0177795ca/packages/common/src/Task.ts#L6010)

Creates a [SemaphoreByKey](https://evolu.dev/docs/api-reference/common/Task/interfaces/SemaphoreByKey) with custom logical key lookup.