Zipkin: a self-hosted distributed tracing server for latency troubleshooting
Zipkin is a distributed tracing system
At a glance
- What is it?
- Zipkin collects and queries timing data from instrumented services, stores it in memory, Cassandra or Elasticsearch, and shows per-service and dependency views. Here is how the server installs, what it can and cannot do, and where it fits next to Jaeger.
- Who is it for?
- Adopt Zipkin if you need a self-hosted trace store that accepts reports over HTTP or Kafka, and you are prepared to run Cassandra or Elasticsearch for anything beyond a laptop demo. Skip it if in-memory storage is your only plan, since the README calls that mode neither persistent nor viable for realistic work loads, and skip it if you need messaging transports while running the slim build.
- 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 55 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 September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The latency question Zipkin was built to answer
A request crossing five services produces five sets of logs, each with its own clock. When the request is slow, the logs rarely tell you which hop ate the time. Zipkin's stated purpose is to gather the timing data needed to troubleshoot latency problems in service architectures, and to do both collection and lookup of that data. The unit is a trace: a set of spans sharing a trace ID, each span carrying a service name, an operation name, a timestamp, a duration and tags.
The audience is teams running service-oriented or microservice architectures who already have, or are willing to add, a tracer or instrumentation library to each application. The README is explicit that applications need to be instrumented to report trace data to Zipkin, which usually means configuring such a library. Zipkin itself is not an agent that discovers your services; it is the server that receives, stores and serves what the instrumentation sends.
The payoff is in the query surface. If you have a trace ID in a log file, you can jump directly to it. Otherwise you query by service, operation name, tags or duration. Zipkin summarizes some of what it finds, including the percentage of time spent in a service and whether operations failed. A dependency diagram shows how many traced requests passed through each application, which the README frames as useful for spotting aggregate behavior such as error paths or calls to deprecated services.
How spans move from an instrumented app to the Zipkin UI
The data flow has three stages. First, the instrumentation in your application builds spans and encodes them, typically as Zipkin v2 JSON. The repository ships a core library at zipkin/src/main/java/zipkin2 that both instrumentation and the server depend on, and it includes built-in codecs for the v1 and v2 JSON formats. The README notes that a direct dependency on gson is avoided by minifying and repackaging the classes used, producing a 155k jar that will not conflict with libraries you already have.
Second, the spans travel to the server. The most popular transports, per the README, are HTTP or Kafka, with other options including Apache ActiveMQ, gRPC, RabbitMQ and Apache Pulsar. Third, a storage component persists and queries the spans. Zipkin defines a StorageComponent interface used by the server and by anyone writing collectors or span reporters.
The storage choice shapes what you can operate. In-memory storage is packaged in the core library and the README describes it as neither persistent nor viable for realistic work loads, existing so you can start a server on a laptop without a database. Cassandra uses a second-generation schema that stores spans using UDTs so they appear like Zipkin v2 JSON in cqlsh, and it requires a separate job to aggregate dependency links. Elasticsearch stores spans as Zipkin v2 JSON, which the README says keeps integration with other tools straightforward.
The server itself is a Java application. The README states it requires minimum JRE 17+, while the core library's minimum language level is 8 and storage components require Java 17+. That split matters if you are embedding the core library in agent instrumentation, where an older runtime may still be in play.
Install Zipkin and open the UI on port 9411
The quickest path, per the README, is to fetch the latest released server as a self-contained executable jar. The quickstart script downloads it and then you run it:
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jarWith the server running, the README says you can view traces in the Zipkin UI at http://localhost:9411/zipkin. On a fresh install with no instrumented applications, that UI will be empty; that is expected, because nothing has reported spans yet.
The Docker route is one command. The README notes the image is mirrored as ghcr.io/openzipkin/zipkin:
docker run -d -p 9411:9411 openzipkin/zipkinThere is a slim variant for smaller images and faster startup. It supports in-memory and Elasticsearch storage but does not support messaging transports such as Kafka or RabbitMQ. Running it via Docker looks like this:
docker run -d -p 9411:9411 openzipkin/zipkin-slimHomebrew is also listed as an option on macOS and Linux:
brew install zipkin
zipkinAfter the server is up, the remaining work is on the application side. The README points to Zipkin instrumentation and to the project's examples for configuring applications that are not sending traces yet. For configuration beyond the defaults, it directs readers to zipkin-server/README.md, and for docker-compose usage to the docker/examples directory.
Where Zipkin stops being the right tool
In-memory storage is the sharpest limitation, and the README states it plainly: it is neither persistent, nor viable for realistic work loads. Restart the process and the traces are gone. A single-node in-memory server is a development convenience, not a deployment.
Persistent backends move the problem rather than removing it. Cassandra storage requires a job to aggregate dependency links, so the dependency diagram depends on infrastructure you have to schedule and monitor separately. Elasticsearch storage, meanwhile, means operating an Elasticsearch or OpenSearch cluster; the README says the component is tested against Elasticsearch 7-8.x and OpenSearch 2.x. Neither backend is a single binary you drop on a host.
The slim build has its own boundary. It supports in-memory and Elasticsearch storage but not messaging transports like Kafka or RabbitMQ. If your reporters publish to Kafka, slim is the wrong artifact regardless of how much you like its startup time.
There is also a version constraint that bites embedded users. The server requires JRE 17+, and storage components require Java 17+, while the core library targets Java 8. Version 2.x was the last to support Java 6, and the README notes that zipkin-reporter-brave does not use the core library, so Brave still supports Java 6. If you are writing agent instrumentation for an old runtime, the core library is the piece to check, not the server.
Finally, Zipkin stores and queries traces; it does not decide what to instrument. The README says applications need to be instrumented to report trace data, which usually means configuring a tracer or instrumentation library. A team unwilling to touch every service will get an empty UI.
Zipkin vs Jaeger: the difference is in the storage and transport model
The most common comparison for Zipkin is Jaeger, and the architectural difference is worth stating precisely. Zipkin's design centers on a single server process that exposes HTTP endpoints for reporting and querying, with pluggable storage behind a StorageComponent interface. The README lists in-memory, Cassandra and Elasticsearch as the supported backends, and HTTP or Kafka as the most popular ways to report data, with Apache ActiveMQ, gRPC, RabbitMQ and Apache Pulsar also available.
Zipkin's core library is deliberately small and dependency-light. It ships built-in v1 and v2 JSON codecs, repackages the JSON classes it needs to avoid a gson conflict, and produces a 155k jar. That matters when you are embedding span encoding inside an agent or a shared library, where a transitive dependency clash is expensive to debug.
Zipkin also separates the dependency-link computation from the server. The Cassandra store requires a separate aggregation job, which the README points to as zipkin-dependencies. That is a different operational shape from a store that computes dependency data inline: you gain control over when aggregation runs and you take on a scheduled workload.
If you are choosing between the two, the questions that actually decide it are which storage systems your team already operates, which transport your instrumentation already speaks, and whether you want dependency links computed by the server or by a separate job. Those are answerable from the README's storage and transport lists; a general claim that one is faster or more modern is not.
Maintenance, releases and the Apache-2.0 licence
The repository is not archived, and the last push was on 2026-08-06. Recent releases listed are 3.6.1 on 2026-04-08, 3.6.0 on 2026-03-23 and 3.5.1 on 2025-04-27. The gap between 3.5.1 and 3.6.0 is roughly eleven months, so the release cadence is not monthly; plan upgrades around minor versions rather than expecting a steady stream of patches.
The upgrade cost is dominated by your storage backend, not by the server jar. The quickstart script fetches the latest released server, and the Docker images are tagged by version, so swapping the server is cheap. What is not cheap is the schema and compatibility surface underneath: Cassandra storage uses a second-generation schema with UDTs, and Elasticsearch storage is tested against Elasticsearch 7-8.x and OpenSearch 2.x. A major version jump in either backend is the upgrade you should test first.
The licence is Apache-2.0, which is a permissive licence that generally allows commercial use and modification with attribution and notice requirements. That is a description of the licence identifier, not legal advice; if you are redistributing the server or the core library inside a product, have counsel review the NOTICE and attribution obligations. The repository also carries a SECURITY.md, which is the file to read for how the project wants vulnerabilities reported.
Editorial conclusion
Adopt Zipkin if you need a self-hosted trace store that accepts reports over HTTP or Kafka, and you are prepared to run Cassandra or Elasticsearch for anything beyond a laptop demo. Skip it if in-memory storage is your only plan, since the README calls that mode neither persistent nor viable for realistic work loads, and skip it if you need messaging transports while running the slim build. Before committing, verify that your tracer or instrumentation library can report to Zipkin, confirm the JRE version on your hosts against the server's minimum, and check which storage backend your team can actually operate.
Frequently asked questions
What is Zipkin used for?
Zipkin is a distributed tracing system that gathers the timing data needed to troubleshoot latency problems in service architectures. It handles both collection and lookup of that data, letting you query by trace ID, service, operation name, tags or duration, and view a dependency diagram of traced requests.
Is Zipkin still used?
The repository is not archived and the last push was on 2026-08-06, with 3.6.1 released on 2026-04-08. The README still documents active installation paths including the quickstart script, Docker images and Homebrew.
What are the key differences between Zipkin and Jaeger?
Zipkin centers on a server with pluggable storage behind a StorageComponent interface, supporting in-memory, Cassandra and Elasticsearch, and reporting over HTTP or Kafka plus transports such as Apache ActiveMQ, gRPC, RabbitMQ and Apache Pulsar. Its Cassandra store also requires a separate job to aggregate dependency links, which the README points to as zipkin-dependencies.
How do you install the Zipkin server?
The README's quickest path is to fetch the latest released server as a self-contained executable jar using the quickstart script, then run it with java -jar zipkin.jar. Docker is also supported with docker run -d -p 9411:9411 openzipkin/zipkin, and Homebrew via brew install zipkin.
What is the Zipkin server jar?
It is the self-contained executable jar published as io.zipkin:zipkin-server on Maven Central, which the README recommends as the quickest way to get started. It requires a minimum JRE of 17 or later.
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/openzipkin-zipkin)