How-to

Use AWS S3 for swarm storage

Applies to: .NET SDK Last updated: 2026-06-11

Pattern

Implement IQuorumStorage backed by the AWS SDK. The critical contract is that TryCreateNewAsync must use S3 conditional PutObject with the If-None-Match: * header to guarantee atomic create:

public sealed class S3QuorumStorage : IQuorumStorage
{
    private readonly IAmazonS3 _s3;
    private readonly string _bucket;
    private readonly string _prefix;

    public async Task<bool> TryCreateNewAsync(string path, byte[] data)
    {
        try
        {
            await _s3.PutObjectAsync(new PutObjectRequest
            {
                BucketName = _bucket,
                Key        = $"{_prefix}/{path}",
                InputStream = new MemoryStream(data),
                Headers    = { ["If-None-Match"] = "*" },
            });
            return true;
        }
        catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.PreconditionFailed)
        {
            return false; // already existed
        }
    }

    // Implement ReadAsync, WriteAsync, etc. using IAmazonS3
}

Register the storage backend

await client.EnableSwarmModeAsync(
    swarmKey:          "shared-swarm-secret",
    quorumStorageRoot: "agents/billing",
    storage:           new S3QuorumStorage(_s3, "my-bucket"));

See also