SeaweedFS: one weed binary, port 8333, and replica math in values.yaml
SeaweedFS is a distributed storage system for object storage (S3), file systems, and Iceberg tables, designed to handle billions of files with O(1) disk access and effortless horizontal scaling.
At a glance
- What is it?
- SeaweedFS is an Apache-2.0 storage system written in Go that serves an S3 object store, a POSIX file system, WebDAV and Iceberg tables from one weed binary over the same data. Scaling it out means counting volume servers yourself, and two shortcuts in the quick start cost you more than the sentence that offers them suggests.
- Who is it for?
- SeaweedFS fits teams that want S3, a POSIX tree and Iceberg tables answered by one Go binary, or that want their own disks and a tiered cloud backend under the same API. It does not fit a team shopping for a drop-in S3 conformance guarantee, because the documentation names a complete S3 API without listing which operations are covered.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
weed mini puts the master, volume server, filer and S3 gateway in one process
Download the latest binary from the releases page, unzip the single weed or weed.exe file, or let the install script place it in /usr/local/bin:
curl -fsSL https://raw.githubusercontent.com/seaweedfs/seaweedfs/master/install.sh | bashOne command then starts a full storage system:
AWS_ACCESS_KEY_ID=admin \
AWS_SECRET_ACCESS_KEY=secret \
S3_BUCKET=my-bucket \
./weed mini -dir=./dataThe S3 endpoint lands on http://localhost:8333, my-bucket already exists, and the pair admin and secret are valid credentials. Behind that single process sit the master, a volume server, the filer, WebDAV, the Iceberg REST catalog and the Admin UI, all pointed at ./data. Capacity then grows by starting a volume server on another machine, and the filer is the piece that turns the same blobs into a POSIX tree. This is the cheapest way to find out whether the S3 surface fits your client before anyone designs a cluster around it.
Your first object goes up through the AWS CLI against port 8333
The upload is an ordinary AWS CLI call with the endpoint overridden:
AWS_ACCESS_KEY_ID=admin AWS_SECRET_ACCESS_KEY=secret \
aws --endpoint-url http://localhost:8333 s3 cp README.md s3://my-bucket/Setting S3_TABLE_BUCKET=warehouse at startup also creates an Iceberg table bucket, and warehouse:LANCE creates a Lance one instead. weed mini is auto-tuned for a single node, and the quick start calls that fine for single-node production, such as an S3 gateway that issues presigned URLs. It does not give you the second node worth of coordination inside that same process. On macOS the unzipped binary arrives quarantined and will not start until you strip the attribute:
xattr -d com.apple.quarantine ./weedThe container route behaves the same way, persisting weed-data at /data:
docker run -p 8333:8333 -v weed-data:/data \
-e AWS_ACCESS_KEY_ID=admin \
-e AWS_SECRET_ACCESS_KEY=secret \
-e S3_BUCKET=my-bucket \
chrislusf/seaweedfsOnly 8333 is published, so the master, the filer and the Admin UI inside that image stay unreachable from outside until you map them yourself.
Dropping the AWS keys leaves port 8333 with no authentication at all
The quick start offers a shortcut for development: remove the AWS keys and weed mini runs without authentication. That is one variable away from a working install, which is exactly why it is worth reading what it leaves behind. A server on 8333 that accepts anonymous PUT, GET and ListBuckets is a bucket with no access control in front of it, and the Docker command above publishes that port for any host that can route to the machine. No document in the repository states which interface the S3 server binds to or offers a firewall example, so the operator has to verify that themselves the day the port stops being a local test. Because weed mini is described as auto-tuned for one node, it is also easy to leave running on a box that was never meant to face a network.
Helm derives your volume replica count from the replication digits
One setting in the production-shaped values.yaml decides the shape of the cluster. replicationPlacement set to "001" means one extra copy on another server, and the comment beside it says "002" for two. Under it, volume.replicas is 3, annotated "at least 1 + the sum of the replication digits". Do that arithmetic and the trap shows: the sample is sized for one placement string, so moving to "002" needs four volume servers rather than three. Nothing in the values file connects the two numbers, and nothing at apply time complains when they disagree, so the failure is silent under-replication rather than a rejected manifest. Master runs 3 replicas against a 1Gi persistentVolumeClaim and filer runs 2, both on the cluster default storage class unless you set storageClass. The chart names a SeaweedFS Operator and a CSI driver as the other Kubernetes paths, so there are three ways in and no stated guidance on which replaced which.
make install and full_install pass different build tags
Building from source is two commands, and the second one hides a decision:
git clone https://github.com/seaweedfs/seaweedfs.git
cd seaweedfs/weed && make installThe binary lands in $GOPATH/bin, and go.mod asks for go 1.26.6, so the toolchain is not a free choice. Two install targets sit in the Makefile. The plain install target runs admin-generate and then cd weed; go install with no tags. full_install passes elastic gocdk sqlite ydb tarantool tikv rclone, and the test target passes the same list. The module requires cloud.google.com/go/storage, aws-sdk-go, Shopify/sarama, bwmarrin/snowflake, go-sql-driver/mysql and jackc/pgx/v5 as direct dependencies, and no document in the repository says which of those reach a default weed binary. A team depending on one specific backend ends up checking the binary instead of the documentation. The Admin UI has its own Makefile under weed/admin with build, dev and run targets, which is why install depends on admin-generate at all.
Three tags in twenty days, and no documented upgrade step between them
4.46 landed on 2026-09-08, 4.47 on 2026-09-14 and 4.48 on 2026-09-28, and the last push to master was on 2026-09-27, the day before that last tag. The repository is not archived. Nobody pins a version and waits for the line to settle, and the quick start covers no upgrade procedure, no rollback procedure, and no list of what changed between 4.46 and 4.48. Two files at the root, S3_LIFECYCLE_REDESIGN.md and VOLUME_SERVER_RUST_PLAN.md, show that the S3 lifecycle and the volume server have designs in flight, but a design note is not a migration note. Operators who need to know whether a bucket expiry rule behaves the same way across that jump have to read the release notes on GitHub or the wiki themselves. No LTS line or stability designation appears anywhere either, so there is no version to point a long-lived deployment at and hold.
S3, POSIX, WebDAV and Iceberg share one data path, which is not the same as beating MinIO
The README runs its own comparisons against HDFS, GlusterFS, Ceph, MooseFS, MinIO and RustFS, and its table of contents carries a section titled The most complete S3 API. No conformance table, no operation list, no S3 specification version appears anywhere in the repository text, so that claim cannot be checked from what ships. The difference in approach the documentation does make concrete is scope: one weed binary serves the S3 API, a POSIX file system through the filer, WebDAV, the Iceberg REST catalog and the Admin UI over the same data, with cloud object storage usable behind it as a cache or a tier. Set that beside an object store that exposes S3 and nothing else, and the decision stops being about throughput. It is about whether you want one binary answering four access patterns or a narrow protocol surface with a smaller thing to reason about. Active-active replication and the cloud cache each get their own section, so the tiering relationship is a designed part of the system rather than an afterthought.
unmaintained/ sits in the root, and Prometheus needs a second wget
The tree keeps a directory named unmaintained/ beside the code it ships, alongside design notes for a Lance catalog, a CloudStack provider and bucket config serialization, plus snap/, terraform/ and postgres-examples/. A directory with that name is a promise nobody keeps for you: feature areas parked in there are not being worked on, and nothing in the documentation says which ones moved or when. Observability is hand-assembled as well. The compose instructions fetch a Prometheus configuration in a separate step:
wget -P prometheus https://raw.githubusercontent.com/seaweedfs/seaweedfs/master/docker/prometheus/prometheus.ymlNo metrics endpoint is started by the single-command path. The port 9324 you eventually need turns up in the Makefile server target next to -filer.maxMB=64 and -volume.max=0, not in the documented install. A team expecting one command to produce a scrapeable service ends up reading a Makefile to find the port.
Editorial conclusion
SeaweedFS fits teams that want S3, a POSIX tree and Iceberg tables answered by one Go binary, or that want their own disks and a tiered cloud backend under the same API. It does not fit a team shopping for a drop-in S3 conformance guarantee, because the documentation names a complete S3 API without listing which operations are covered. Before you commit, check two things: whether port 8333 still has its AWS keys set on every host, and whether your volume replica count matches the replicationPlacement string you actually chose, since the chart computes one from the other and enforces nothing.
Frequently asked questions
What is SeaweedFS?
SeaweedFS is a distributed storage system written in Go under Apache-2.0 that serves an S3 object store, a POSIX file system and a lakehouse with S3 Tables from a single weed binary over the same data. Its two stated objectives are to store billions of files and to serve them fast, with each blob one disk read away.
how to install seaweedfs
Unzip the single weed binary from the releases page, or run curl -fsSL https://raw.githubusercontent.com/seaweedfs/seaweedfs/master/install.sh | bash to place it in /usr/local/bin. On macOS a quarantined binary needs xattr -d com.apple.quarantine ./weed first, and there is also a container image, chrislusf/seaweedfs, published on Docker Hub.
what is seaweedfs filer
The filer is the metadata layer of a SeaweedFS deployment and one of the processes a weed binary runs next to the master, the volume server, WebDAV, the Iceberg REST catalog and the Admin UI. REST_API.md documents the HTTP REST API for the filer, master and volume servers, and the Helm chart sets filer.replicas to 2 with a recipe for filer metadata on PostgreSQL.
is seaweedfs s3 compatible
The S3 endpoint listens on port 8333 and clients point at it with an endpoint URL, as the AWS CLI example shows. A section of the README is titled The most complete S3 API, but no conformance table, operation list or S3 specification version appears in the repository text, so exact coverage is not documented there.
is seaweedfs production ready
The quick start says weed mini is auto-tuned for one node and fine for single-node production such as an S3 gateway issuing presigned URLs, and the Helm chart offers a production-shaped three-master cluster with replication. Versions 4.46, 4.47 and 4.48 were released on 2026-09-08, 2026-09-14 and 2026-09-28, and no upgrade or rollback procedure between them is documented.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/seaweedfs-seaweedfs)