Ambry distributed object store: API, deployment, and storage limits
Distributed object store
At a glance
- What is it?
- LinkedIn's Ambry is a Java-based distributed object store for immutable media, backups, search indexes, and reports. Its documented HTTP workflow is clear, but deployment requires cluster layout files and several services.
- Who is it for?
- Adopt Ambry when a service needs immutable blobs, metadata, TTL expiration, and deletion across a distributed store, and the team can operate its Java services and layout files. Do not choose it for mutable objects or as a drop-in key-value database without confirming that its immutability model fits the application.
- 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 4 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Ambry's blob model and target workloads
Ambry solves the problem of storing and serving immutable objects at a scale that ranges from small files, described as 50K to 100K, to billions of large objects. The README positions the system for media objects used by web companies, while also naming database backups, search indexes, and business reports as possible workloads. That distinction matters. Ambry is an object store, not a mutable document database or a general-purpose block service. Its documented API centers on uploading a blob, reading blob information, downloading the bytes, and deleting the object.
The immutability rule is the main design constraint. The README says that blobs cannot be updated. An application that needs to replace an object must upload a new blob and manage its identity and lifecycle separately. Deletion is supported, but it makes the blob irretrievable, and a later BlobInfo request returns `410 Gone`. This is a meaningful boundary for applications that expect revision history or in-place updates. The repository layout includes modules such as `ambry-account`, `ambry-frontend`, `ambry-clustermap`, `ambry-replication`, and `ambry-store`, which is consistent with a system that separates request handling, cluster mapping, replication, and storage concerns.
Ambry also exposes object properties through request headers. The documented upload includes service ID, owner ID, content type, description metadata, and a TTL option. This makes it possible to attach application-level metadata to an object, although Ambry does not interpret arbitrary user metadata. The README describes support for public and private blobs, plus metadata-only retrieval and `HEAD`. Those features fit systems where application services need HTTP object semantics rather than direct filesystem access.
Ambry request routing through cluster layout files
Ambry uses files to describe the cluster and route requests between the frontend and storage servers. The getting-started instructions call for `server.properties`, `HardwareLayout.json`, and `PartitionLayout.json`. The README describes a simple cluster map with one server and one partition whose mount point is `/tmp`. This is the smallest documented starting arrangement, not evidence of a production cluster configuration.
The frontend process is started with `AmbryFrontendMain`. It receives the server properties and the hardware and partition layout files, then exposes the HTTP endpoint used by `curl`. The server process runs from `ambry.jar` with corresponding configuration arguments. The architecture therefore separates the public HTTP-facing component from the server-side storage process. The repository's `ambry-router`, `ambry-clustermap`, and `ambry-replication` module names further indicate that request placement and replication are separate concerns.
The README does not document the internal file formats beyond their names, nor does it specify how to grow a cluster, change partition ownership, or recover from a failed layout file. Those omissions limit how far an operator can plan from the README alone. Based on the repository layout, a real deployment will need to understand the relationship between `ambry-clustermap`, the frontend, and server configuration rather than treating the commands as a complete production installation guide.
Building and starting Ambry on the documented JDK range
The README requires JDK version 1.11 through 1.14. It does not document installation on a newer JDK, so the supported build target should be treated as a real constraint. The documented build uses the repository's Gradle wrapper and produces an all-JAR artifact under `target`. The README then creates a `logs` directory before launching the server.
The following commands reproduce the documented build and preparation sequence. After the final command, the working directory should be `target`, with `logs` available for the server and frontend log files.
$ git clone https://github.com/linkedin/ambry.git
$ cd ambry
$ ./gradlew allJar
$ cd target
$ mkdir logsThe next commands start a server and a frontend using the supplied configuration files. They also redirect console output into separate logs. The README tells the operator to retain the process IDs for shutdown.
$ nohup java -Dlog4j2.configurationFile=file:../config/log4j2.xml -jar ambry.jar --serverPropsFilePath ../config/server.properties --hardwareLayoutFilePath ../config/HardwareLayout.json --partitionLayoutFilePath ../config/PartitionLayout.json > logs/server.log &
$ nohup java -Dlog4j2.configurationFile=file:../config/log4j2.xml -cp "*" com.github.ambry.frontend.AmbryFrontendMain --serverPropsFilePath ../config/frontend.properties --hardwareLayoutFilePath ../config/HardwareLayout.json --partitionLayoutFilePath ../config/PartitionLayout.json > logs/frontend.log &The frontend readiness check is explicit. The documented endpoint is port `1174`, and the expected response body is `GOOD`.
$ curl http://localhost:1174/healthCheck
GOODThe README does not provide a production service definition, firewall configuration, dependency installation procedure, or deployment topology. It also does not state how to configure authentication, storage durability, or backup restoration.
Uploading and retrieving an immutable blob
The first documented use uploads `demo.gif` to the frontend. The binary body is sent with `POST`, while Ambry-specific headers provide object properties. The `Location` response header contains the blob ID. That identifier becomes the URL path for retrieval and deletion.
The upload command below must be run with `demo.gif` present in the `target` directory. The backticks around `whoami` are part of the documented shell command and populate the owner ID from the current user.
$ curl -i -H "x-ambry-service-id:CUrlUpload" -H "x-ambry-owner-id:`whoami`" -H "x-ambry-content-type:image/gif" -H "x-ambry-um-description:Demonstration Image" http://localhost:1174/ --data-binary @demo.gifThe documented response is `HTTP/1.1 201 Created`, with the blob ID returned in `Location`. The properties can then be inspected through the `BlobInfo` resource. The response includes size, service ID, creation time, private status, content type, owner ID, and the abbreviated user metadata description.
$ curl -i http://localhost:1174/AmbryID/BlobInfoThe actual bytes are retrieved from the blob ID itself. The README uses `diff` to compare the uploaded and downloaded files.
$ curl http://localhost:1174/AmbryID > demo-downloaded.gif
$ diff demo.gif demo-downloaded.gifA successful `diff` command with no output indicates that the retrieved bytes match the uploaded file. The README also notes `multipart/form-data` uploads, metadata-only `GET`, and `HEAD`, but does not provide separate examples for those operations.
Deletion, TTL expiration, and the wrong-tool cases
Ambry supports deletion as a lifecycle operation, not as a way to mutate the contents of a blob. The documented `DELETE` request returns `202 Accepted`, after which the blob properties and data are no longer available. The README demonstrates this state change with a `BlobInfo` request that returns `410 Gone`.
$ curl -i -X DELETE http://localhost:1174/AmbryID
$ curl -i http://localhost:1174/AmbryID/BlobInfoThe first request is expected to return `HTTP/1.1 202 Accepted`. The second is expected to return `HTTP/1.1 410 Gone`. Because deletion is immediate from the API perspective, applications need to decide whether users may still encounter a previously issued blob ID.
TTL provides another lifecycle path. During `POST`, a client can provide `x-ambry-ttl` with a value in seconds. After expiration, Ambry stops serving the blob, and the README says expired blobs behave like deleted blobs on `GET`. Private blobs can be marked with `x-ambry-private: true`, and API behavior can be configured according to public or private status.
These features make Ambry unsuitable when the workload requires in-place edits, atomic transactions across blobs, or a conventional mutable key-value interface. The README also does not document restore after deletion, object versioning, or rollback. Those omissions are especially relevant for database backups and reports, where an application may need retention guarantees beyond ordinary blob deletion. The repository's modules indicate support areas such as quota, account handling, replication, and REST, but the README does not explain their configuration or recovery semantics.
Operational boundaries, licensing, and upgrade cost
The repository is not archived, and the last push was on 2026-10-14. The listed releases are much older: `v0.3.115` on 2020-02-22, `v0.3.109` on 2020-02-15, and `v0.3.108` on 2020-02-14. The project is under the `Apache-2.0` license. That identifies the repository's declared licensing terms, but it is not a substitute for reviewing the license file and any notices applicable to a particular distribution.
The upgrade path is not documented in the README. There is no stated compatibility policy for upgrading a running cluster, no migration command, and no explanation of whether layout files or stored object formats change between versions. The documented JDK range also gives operators a bounded build environment. An upgrade evaluation therefore needs to account for rebuilding, restarting the frontend and server, and confirming that the cluster map and partition layout remain compatible. The README provides shutdown commands, but it does not describe a safe maintenance sequence.
The test section warns that tests can take upwards of 40 minutes and begins by referring to `azurite`, although the README ends before explaining the dependency. This signals a substantial validation path, but the available text does not explain the full external test dependency or how to configure it. Operators should treat the documented test warning as a cost before using the repository in a release pipeline. The repository also contains `ambry-benchmarks` and `ambry-test-utils`, but no benchmark procedure or performance results are documented.
Ambry compared with direct object storage interfaces
A real alternative is a managed object storage service accessed through its object API. The practical difference is operational ownership: Ambry is a repository that must be built and run as Java services, with the operator supplying a frontend, server, cluster map, hardware layout, partition layout, and log configuration. A managed service moves those deployment and maintenance responsibilities to the provider, while Ambry gives the application an HTTP blob interface without requiring the provider's SDK.
That difference is not a claim that one system is faster or more reliable. The README describes Ambry as horizontally scalable, highly available, low latency, and high throughput, but it provides no measurements or deployment results. It also does not document provider credentials, region handling, service-level objectives, or managed backup behavior. Ambry is more relevant when the team wants to operate the store itself and accepts responsibility for the cluster layout and Java runtime. A managed object store is the more direct choice when reducing infrastructure administration matters more than controlling the service implementation.
For a small local evaluation, Ambry's documented one-server, one-partition setup is concrete. For a production decision, the missing documentation becomes decisive. The team would need to inspect `config/`, understand the layout file schemas, and determine how replication and account configuration behave before treating the README's examples as an operating model.
Editorial conclusion
Adopt Ambry when a service needs immutable blobs, metadata, TTL expiration, and deletion across a distributed store, and the team can operate its Java services and layout files. Do not choose it for mutable objects or as a drop-in key-value database without confirming that its immutability model fits the application. Verify JDK compatibility, the cluster configuration, frontend availability, and the intended lifecycle for deletes and expired blobs first. The documented setup is a concrete starting point, but the README does not cover production sizing, rollback, or operational upgrades.
Frequently asked questions
What is Ambry used for?
Ambry is a distributed object store for immutable objects, especially small media objects and large objects. The README also lists database backups, search indexes, and business reports as possible uses.
How do I build and start Ambry?
The README documents cloning the repository, running `./gradlew allJar`, creating `target/logs`, and starting the server and frontend with the supplied configuration files. The frontend is checked through `http://localhost:1174/healthCheck`.
Can Ambry blobs be updated or deleted?
Ambry blobs cannot be updated because the store is immutable. They can be deleted, and the README says that a deleted blob's properties and data become unavailable and that a BlobInfo request returns `410 Gone`.
What JDK versions does Ambry require?
The README states that Ambry requires JDK version 1.11 through 1.14. It does not document compatibility with newer JDK releases.
Does Ambry support expiration and private blobs?
The README documents the `x-ambry-ttl` header for a TTL in seconds and `x-ambry-private: true` for private blobs. Expired blobs are described as behaving like deleted blobs on `GET`.
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/linkedin-ambry)Was this useful?