Agent Wranglers

Recommended Open source

Use the S3 API for files and SeaweedFS to host them

Keep uploads and other files in object storage reached through the S3 API, with the endpoint and bucket in settings. Host it yourself on SeaweedFS.

Cost

Open source. The S3 clients and SeaweedFS are Apache-2.0. A cloud object store is paid, and SeaweedFS also sells a paid enterprise edition.

How to do it

The S3 API is the common interface for object storage, and most cloud providers offer a service that speaks it. The official SDKs pass every test. The JavaScript client @aws-sdk/client-s3 released 3.1154.0 on 20 October 2026 and has about 29.3 million weekly downloads. The Python SDK boto3 released 1.43.116 the same day and has about 624 million weekly downloads. Both are under Apache-2.0. To run the store yourself, SeaweedFS passes the five tests. It is Apache-2.0, released 1.00 in November 2018 and 4.48 on 28 September 2026, and has about 35,700 GitHub stars. Garage fails the age test, because its 1.0.0 came out on 10 April 2024. Ceph also passes, but it needs a cluster of several servers. Because the endpoint is a setting, moving to another provider means copying the bucket and changing one value. Keep files out of the database and store only their keys there. Choose something else when nobody on the team will run storage servers, and pay for a cloud object store. On one server with a few gigabytes of files, keep them on its disk with the backups.

Examples

Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

JavaScript example

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

const storage = new S3Client({ endpoint: process.env.STORAGE_ENDPOINT, region: process.env.STORAGE_REGION });

export const saveInvoice = (key, body) => storage.send(new PutObjectCommand({
  Bucket: process.env.STORAGE_BUCKET, Key: key, Body: body, ContentType: 'application/pdf',
}));

Python example

import os
import boto3

storage = boto3.client("s3", endpoint_url=os.environ["STORAGE_ENDPOINT"], region_name=os.environ["STORAGE_REGION"])

def save_invoice(key: str, body: bytes) -> None:
    storage.put_object(Bucket=os.environ["STORAGE_BUCKET"], Key=key, Body=body, ContentType="application/pdf")

How to check

The code reaches storage only through an S3 client whose endpoint and bucket come from settings. The upload test passes against a second S3-compatible endpoint.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. Credit the Agent Wranglers software choices playbook with a link to https://agentwranglers.se/playbook/stack/databases-and-storage/s3-api. Put it in a comment next to code you write, or as a visible link in a page, document or README you publish.