> For the complete documentation index, see [llms.txt](https://brightercommand.gitbook.io/paramore-brighter-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://brightercommand.gitbook.io/paramore-brighter-documentation/outbox-and-inbox/distributedlock/firestoredistributedlock.md).

# Firestore Distributed Lock

The Firestore locking provider implements Brighter's [distributed lock](/paramore-brighter-documentation/outbox-and-inbox/distributedlock.md) using Google Cloud Firestore, so a single [Outbox Sweeper](/paramore-brighter-documentation/outbox-and-inbox/brighteroutboxsupport.md#implicit-clear) and Archiver run when you scale out. It is a good choice when your workloads already run on Google Cloud.

## Package

* **Paramore.Brighter.Locking.Firestore**

The provider stores its locks in a Firestore collection that you name through the Firestore configuration — see [Provisioning](#provisioning).

## Configuration

The Firestore provider is configured through a `FirestoreConfiguration`, whose constructor takes your project id and database. Set its `Locking` property to a `FirestoreCollection` that names the lock collection and, optionally, a time-to-live:

```csharp
var configuration = new FirestoreConfiguration(
    projectId: "my-gcp-project",
    database: "(default)")
{
    Locking = new FirestoreCollection
    {
        Name = "brighter-locks",
        Ttl = TimeSpan.FromMinutes(1)
    }
};

var lockingProvider = new FirestoreDistributedLock(configuration);
```

`FirestoreDistributedLock` also has a constructor that accepts an `IAmAFirestoreConnectionProvider` alongside the configuration if you want to share a connection provider.

| Setting (on `Locking`) | Type        | Description                                   |
| ---------------------- | ----------- | --------------------------------------------- |
| `Name`                 | `string`    | The collection that holds the lock documents. |
| `Ttl`                  | `TimeSpan?` | Optional expiry for lock documents.           |

## Example

```csharp
var configuration = new FirestoreConfiguration("my-gcp-project", "(default)")
{
    Locking = new FirestoreCollection { Name = "brighter-locks", Ttl = TimeSpan.FromMinutes(1) }
};

services
    .AddBrighter()
    .AddProducers(opt =>
    {
        opt.Outbox = /* your external Outbox */;
        // ... connection/transaction providers for your Outbox ...

        opt.DistributedLock = new FirestoreDistributedLock(configuration);
    })
    .UseOutboxSweeper(opt => { opt.BatchSize = 10; });
```

## Provisioning

The provider creates lock documents in the collection named by `Locking.Name`. It acquires a lock with an atomic create that succeeds only when the document does not already exist, so only one instance holds a given lock at a time. Setting `Ttl` lets stale locks expire, which protects you if an instance crashes before releasing its lock. Ensure the application's service account can read and write documents in the lock collection.

## Notes

* Resource names are normalised for Firestore (for example `/` and `.` are replaced), so lock document ids are always valid. You do not need to do anything for this.
* Set `Ttl` longer than a typical Sweeper or Archiver batch so a lock is not expired mid-run. See [Lease Expiry vs Manual Release](/paramore-brighter-documentation/outbox-and-inbox/distributedlock.md#lease-expiry-vs-manual-release).

## Further Reading

* [Distributed Lock](/paramore-brighter-documentation/outbox-and-inbox/distributedlock.md) — concepts and the full provider list
* [Outbox Support](/paramore-brighter-documentation/outbox-and-inbox/brighteroutboxsupport.md) — the Sweeper and Archiver


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://brightercommand.gitbook.io/paramore-brighter-documentation/outbox-and-inbox/distributedlock/firestoredistributedlock.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
