kparisa commented on code in PR #112: URL: https://github.com/apache/iggy-website/pull/112#discussion_r4058293694
########## content/blog/release-0.9.0.mdx: ########## @@ -0,0 +1,528 @@ +--- +title: Apache Iggy 0.9.0 Release +description: Apache Iggy 0.9.0 brings VSR clustering, per-topic durability, SDK and connector updates, and a first look at performance work for the next release. +author: piotr, hubert +tags: ["release", "0.9.0", "announcement", "clustering", "vsr", "benchmarks"] +date: 2026-09-21 +--- +## Release 0.9.0 + +Five months after [0.8.0](https://iggy.apache.org/blogs/2026/04/22/release-0.8.0/), we're proud to release **[Apache Iggy 0.9.0](https://github.com/apache/iggy/releases/tag/server-0.9.0)**. It is our first release as an **Apache Top-Level Project**, following the [graduation from the Incubator](https://iggy.apache.org/blogs/2026/08/24/apache-iggy-top-level-project-tlp-graduation/) on August 19, 2026, and the first one without the `-incubating` suffix. It is also the release we have been working towards for the past year. + +**Iggy now runs as a cluster.** 0.9.0 ships **Viewstamped Replication Revisited (VSR)** consensus in the standard `iggy-server` binary. Start three nodes, lose one, and the cluster keeps serving reads and writes. There is no separate build, feature flag, or clustered edition. The same server runs single-node or replicated, and `cluster.enabled` in the configuration decides which one you get. + +This is the biggest release in the project's history: **over 600 merged pull requests from 60 contributors, 34 of them contributing to Iggy for the first time.** Alongside the server, we're releasing the Rust SDK 0.11.0, the CLI 0.14.0, the connectors runtime 0.5.0, the MCP server 0.5.0, the Web UI 0.4.0, the bench dashboard 0.8.0, and the Python 0.9.0, Node.js 0.10.0, Java 0.9.0, C# 0.9.0 and Go 0.9.0 SDKs, all from the same repository. Beyond clustering, 0.9.0 brings **per-topic durability policies**, an extensible **topic options** catalog, a new **PHP SDK**, **eight new connectors** and an **HTTP webhook source**, the foundation of a **Kafka protocol gateway** for existing Kafka clients, a redesigned **benchmarks dashboard**, cluster-aware **Helm charts**, and hundreds of fixes and performance improvements across the server, SDKs and connectors. + +Before the changelog, two topics deserve their own space: **clustering** and **performance**. + +--- + +## Clustering with VSR consensus + +For three releases the roadmap section of these posts has ended the same way: complete the clustering implementation with VSR consensus. 0.7.0 laid the consensus foundations. 0.8.0 added the shard crate, the plane abstractions, the persistent WAL journal, and the experimental `iggy-server-ng` binary. In 0.9.0 that work became the server. **[server-ng was promoted to the Apache Iggy server](https://github.com/apache/iggy/pull/3856)**, the `vsr` feature flag is gone, the legacy server and its wire format were deleted, and every SDK and CI lane runs against the replicated server. Single-node deployment remains the default, and clustering is opt-in through the `[cluster]` section of the configuration. + +### What a cluster gives you + +Apache Iggy replicates with **[Viewstamped Replication Revisited](https://github.com/apache/iggy/blob/master/assets/vsr.pdf)**. VSR keeps an ordered state machine consistent across replicas and elects a new primary when the current one fails: + +- **Normal operation**: the primary assigns an operation number, sends `Prepare`, and commits after a quorum answers `PrepareOk`. +- **View change**: when replicas stop hearing from the primary, they exchange `StartViewChange` and `DoViewChange`, and the new primary sends `StartView`. Failover needs no operator. +- **Recovery**: a restarted or lagging replica probes the current view and repairs the missing WAL ranges from its peers before it serves current state. + +**Three replicas tolerate one unavailable replica, five tolerate two.** Three nodes is the recommended minimum for a highly available deployment. A two-node cluster is useful for development, but it cannot make progress after either node fails. + +Replication is split by namespace rather than run as one global log: + +| Plane | Consensus group | Replicated state | +| --- | --- | --- | +| Metadata | One group on shard 0 | Streams, topics, users, permissions, consumer groups, access tokens | +| Partition | **One group per partition** | Messages and consumer offsets | + +Each group runs its own consensus and elects its own primary. Metadata writes route through the metadata primary, and partition writes route through the primary of that partition. Reads are served from the local replicated state on any node, followers included. + +### How it was built + +The consensus work spans well over a hundred pull requests. The milestones, in roughly the order they landed: + +- **[Consensus per partition](https://github.com/apache/iggy/pull/3071)** and the **[consensus group mechanism](https://github.com/apache/iggy/pull/3138)** made every partition its own replicated state machine +- **[Session registration with combined login and register](https://github.com/apache/iggy/pull/3108)**, later **[reworked so sessions resume across restarts](https://github.com/apache/iggy/pull/3753)**, backed by the client table for at-most-once request handling +- **[Async fire-and-forget message bus](https://github.com/apache/iggy/pull/3134)** for consensus traffic, plus **[QUIC, TCP-TLS, WebSocket and WSS transports](https://github.com/apache/iggy/pull/3192)** for clients +- **[Replica bootstrap](https://github.com/apache/iggy/pull/3163)** and **[multi-shard cross-shard communication](https://github.com/apache/iggy/pull/3269)**, so all shards of a node take part in consensus +- **[Partition reconciliation loop](https://github.com/apache/iggy/pull/3436)**, **[partition background tasks](https://github.com/apache/iggy/pull/3564)**, and **[replica rejoin via view probe and message repair](https://github.com/apache/iggy/pull/3667)** +- **[Metadata VSR state persisted in a durable superblock](https://github.com/apache/iggy/pull/3767)**, **[state transfer for the metadata snapshot and client table](https://github.com/apache/iggy/pull/3765)**, and **[state transfer for partitions](https://github.com/apache/iggy/pull/3808)**, which let a wiped replica refill itself from its peers +- **[Committed sends confirmed with partition and offset](https://github.com/apache/iggy/pull/3781)**, so producers learn exactly where their batch landed +- **[Deduplication of partition writes with per-group client table slices](https://github.com/apache/iggy/pull/3959)**, so a produce retried after a timeout does not write twice +- **[Follower HTTP requests forwarded to the primary](https://github.com/apache/iggy/pull/3744)**, so any node can answer any control-plane request +- **[Inbox split into consensus and client-reply lanes](https://github.com/apache/iggy/pull/3915)**, so a burst of client traffic cannot starve replication +- **[Metadata reads served at or above the client's own writes](https://github.com/apache/iggy/pull/4024)** + +Then came the correctness fixes found by the simulator, the crash tests and real cluster runs: **[view change no longer discards committed ops](https://github.com/apache/iggy/pull/3824)**, **[a replica is kept off a hole in its committed prefix](https://github.com/apache/iggy/pull/4073)**, **[repaired prepares can't rewind the WAL parent](https://github.com/apache/iggy/pull/3978)**, **[the dedup fence survives capacity eviction](https://github.com/apache/iggy/pull/3934)**, **[writes recover after a fast primary rejoin](https://github.com/apache/iggy/pull/3987)**, **[a late partition materialiser can't wedge its group](https://github.com/apache/iggy/pull/4007)**, **[partition and metadata repair are driven from the tick](https://github.com/apache/iggy/pull/4006)**, **[an unservable header counts as a nack](https://github.com/apache/iggy/pull/4109)**, **[frames no plane claims are refused](https://github.com/apache/iggy/pull/4103)**, **[torn segment tails are truncated instead of resu rrected](https://github.com/apache/iggy/pull/3946)**, and, as the last change before the tag, **[spurious heartbeat elections are prevented](https://github.com/apache/iggy/pull/4194)**. Review Comment: It's more readable with the links if this is a bullet format list like the one above -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
