Self-hosted service
uber/kraken avatar
uber/kraken

Kraken hands out peer lists instead of moving image layers

P2P Docker registry capable of distributing TBs of data in seconds

6,776 stars507 forksGoApache-2.0

At a glance

What is it?
Uber's P2P Docker registry keeps blob bytes between host agents and off any central server. Five components, a pluggable storage layer, and a build-index that makes no consistency promise about tags.
Who is it for?
Adopt Kraken when pull throughput across thousands of hosts is measured as the bottleneck, and when S3, GCS, ECR or HDFS already back your blobs. Skip it for a single region fleet of a few dozen nodes.
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 last received commits 1 day ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • uber/kraken6,776 ★ · +26
Star history
Repository2026-09-232026-11-13
uber/kraken6.8k6.8k

26 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

A tracker hands out peer lists instead of moving bytes

Kraken is a peer to peer Docker registry for image management, replication and distribution across a hybrid cloud, and the reason it exists is throughput rather than features. The project states that it has run in production at Uber since early 2018, that its busiest cluster moves more than one million blobs a day including 100k of them at 1G or larger, and that at peak production load it distributed 20K blobs in the 100MB to 1G range in under 30 seconds.

The design keeps the payload off any central server. A small number of dedicated hosts, called origins, seed content, and every other host runs an agent that speaks the Docker registry interface, announces what it already holds to a central tracker, and connects to the peers the tracker names. The tracker orchestrates all participants into a pseudo random regular graph, which gives the network high connectivity and a small diameter, and then returns ordered lists of peers to contact for a given blob. The tracker itself never carries data. The project puts a floor of 80% of maximum upload or download speed as reachable for every participant when only one seeder is present and thousands of peers join in the same second, and 60% as what the current implementation actually delivers.

Origins hash ring the blobs while agents answer the registry API

Kraken splits into five components with separate jobs. The proxy implements the Docker registry interface on the write side. It uploads each image layer to whichever origin owns it on a self healing hash ring, then sends tags to a separate service. Origins hold blobs as files on local disk backed by whatever pluggable storage you configure, with S3, GCS, ECR and HDFS all named as options and another registry able to stand in as the backing store.

The tracker holds the routing state: which peers have which content, both in progress and completed, and it turns that state into the ordered connection lists agents consume. Build-index maps human readable tags to blob digests, stores tags on pluggable storage and powers image replication between clusters.

The agent is the component you actually meet in daily use, since it is deployed on every host and answers registry requests there. In the Kubernetes example every node exposes that interface on localhost:30081, which is why a node can pull an image without knowing any origin exists.

Build-index makes tags a last writer wins mapping

The project's own description of build-index carries its warning in the same breath as its role: no consistency guarantees, so the client should use unique tags. There is no defined ordering between a push of a tag and a read of the same tag, which means a pipeline that republishes one mutable name such as latest inherits behaviour nobody can reason about after a partial failure.

Cross cluster replication rides on the same component. The queues are simple duplicated queues with retry, and rule based async replication between clusters is advertised as lossless. Those two properties are worth separating before you build on them. Replication is the half that carries a guarantee. Tag lookup is the half that does not.

Building the images and standing up the Helm demo

Every Kraken component ships as a Docker container, and the build is driven from the Makefile. The module targets Go 1.24.0, which is also the default build image:

bash
$ make images

Configuration is not carried in the README. It points to docs/CONFIGURATION.md for how to configure and use Kraken, so that is the document to read before your first push rather than after it.

For Kubernetes there is an example Helm chart in the helm directory. It requires Helm 3.x, installs with an example HTTP fileserver backend, and takes one command:

bash
$ helm install kraken-demo ./helm

Once it is deployed, every node exposes a Docker registry API on localhost:30081, and the pod spec that pulls images through a Kraken agent is examples/k8s/demo.json.

To see all five components on a laptop, the devcluster target starts a herd container holding origin, tracker, build-index and proxy, plus two agent containers with development configuration:

bash
$ make devcluster

Docker-for-Mac is required for that path on macOS. Builds cross compile through a Linux container by design, because cgo for sqlite3 does not port cleanly to macOS, while tools that avoid cgo build natively.

The 20G ceiling and the shape of the published benchmark

Kraken claims arbitrarily large blobs and layers, then qualifies it in the same list: the maximum size is normally limited to 20G for the best performance. Those two statements sit together, and the second is the one to plan around, because a layer that size will not fit a chunking or retry strategy you designed for smaller units.

The published benchmark is narrow, and it is worth reading precisely rather than as a headline. A 3G Docker image of 2 layers was downloaded by 2600 hosts concurrently, which the project counts as 5200 blob downloads, with a 300MB/s limit on all agents and 5 trackers against 5 origins. p50 came in at 10 seconds, which is the rate limit being reached, p99 at 18 seconds and p99.9 at 22 seconds. Nothing in that figure covers the write path, a tracker restart, or an origin losing disk, so the tail it reports is a read tail under clean conditions.

The other number worth holding onto is host count. The project states support for at least 15k hosts per cluster, with every host pulling above 50% of its maximum download speed limit and cluster size and image size having no significant effect on that speed. Claims of that shape are the hardest kind to reproduce elsewhere, so treat them as the project's own.

The BitTorrent protocol Kraken wrote instead of adopting

Kraken began with a BitTorrent driver and replaced it. The current driver is built on the BitTorrent protocol but written in house, the stated reasons being tighter integration with storage solutions and more control over performance optimizations. The comparison draws a line between problem spaces: Kraken targets a stable environment and tries to cut global max download time and communication overhead, while BitTorrent was designed for an unpredictable and adversarial one, so it keeps more copies of scarce data and defends against malicious or misbehaving peers.

Dragonfly gets sharper treatment. Its cluster has one or a few supernodes coordinating every 4MB chunk, which the project argues caps throughput at the processing power of those few hosts and degrades linearly as either blob size or cluster size grows. Kraken's tracker, on that account, only shapes the connection graph and leaves negotiation of the actual transfer to the peers themselves.

Both comparisons are written by Kraken's own authors, so read them as claims.

If registry pull is not the bottleneck, none of this helps

The dependency story is unusually small. Beyond the pluggable storage you choose, the only optional dependency is DNS, and no component is described as a single point of failure. Security is limited to uploader authentication and data integrity protection through TLS, which is worth naming if you arrived expecting content signing or finer authorization layers, since neither is listed among the features. The devcluster path wants Docker-for-Mac on a laptop, and the Helm chart ships with an HTTP fileserver backend, so production means replacing storage yourself.

Maintenance is active. The last push landed on 2026-11-02, and three releases shipped between 2026-10-19 and 2026-11-02 (v0.1.33 to v0.1.35), all still numbered 0.1.x on a repository whose default branch is master. The licence is Apache-2.0. The module declares Go 1.24.0 while still pinning aws-sdk-go v1.21.4 and docker/distribution v2.7.1, so the Docker API surface Kraken builds against is a dated one.

Editorial conclusion

Adopt Kraken when pull throughput across thousands of hosts is measured as the bottleneck, and when S3, GCS, ECR or HDFS already back your blobs. Skip it for a single region fleet of a few dozen nodes. Read docs/CONFIGURATION.md first, because the Helm chart ships an example HTTP fileserver backend and the README points to that document for configuration.

Frequently asked questions

How do I get all five Kraken components running on one machine?

Run `make devcluster`, which starts a herd container holding origin, tracker, build-index and proxy, plus two agent containers with development configuration. Docker-for-Mac is required for that path to work on a laptop. Component images are built with `make images`.

What does a Kubernetes node get after installing the Kraken Helm chart?

Every node exposes a Docker registry API on localhost:30081. The chart requires Helm 3.x and installs with an example HTTP fileserver backend, and examples/k8s/demo.json holds a pod spec that pulls through a Kraken agent.

Does Kraken guarantee that a tag I just pushed is readable at once?

No. Build-index maps human readable tags to blob digests and carries no consistency guarantees, so the client should use unique tags. Cross cluster replication runs on duplicated queues with retry and is the part that offers a guarantee.

How large can a layer get before Kraken stops being a good fit?

The project claims arbitrarily large blobs and layers, but normally limits the maximum size to 20G for the best performance. It states support for at least 15k hosts per cluster, with every host above 50% of its maximum download speed limit.

Which storage backends can sit behind Kraken origins?

Origins store blobs as files on disk backed by pluggable storage, and the README names S3, GCS, ECR and HDFS as options, with another registry able to act as the backing store. The storage interface is described as simple, with new options easy to add.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. Releases
  5. uber/kraken on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/uber-kraken.svg)](https://hysenlabs.com/projects/uber-kraken)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/uber-kraken.svg)](https://hysenlabs.com/projects/uber-kraken)

Was this useful?