| <p align="center"> |
| <a href="https://trendshift.io/repositories/14204" target="_blank"><img src="https://trendshift.io/api/badge/repositories/14204" alt="apache%2Figgy | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a> |
| </p> |
| <div align="center"> |
| <picture> |
| <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/apache/iggy/refs/heads/master/assets/logo/SVG/iggy-apache-color-darkbg.svg"> |
| <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/apache/iggy/refs/heads/master/assets/logo/SVG/iggy-apache-color-lightbg.svg"> |
| <img alt="Apache Iggy" src="https://raw.githubusercontent.com/apache/iggy/refs/heads/master/assets/logo/SVG/iggy-apache-color-lightbg.svg" width="400"> |
| </picture> |
| </div> |
| |
| <div align="center"> |
| |
| [Website](https://iggy.apache.org) | [Getting started](https://iggy.apache.org/docs/introduction/quickstart/) | [Documentation](https://iggy.apache.org/docs/) | [Blog](https://iggy.apache.org/blogs/) | [Discord](https://discord.gg/apache-iggy) | [Crates](https://crates.io/crates/iggy) | [Mailing list](https://iggy.apache.org/community/mailing-lists/) |
| |
| </div> |
| <p align="center"> |
| <a title="Releases" target="_blank" href="https://github.com/apache/iggy/releases"><img alt="Latest Release" src="https://img.shields.io/github/v/release/apache/iggy?style=flat-square&color=9CF"></a> |
| <a title="Rust" target="_blank" href="https://crates.io/crates/iggy"><img alt="Crate" src="https://img.shields.io/crates/v/iggy?label=rust&logo=rust&style=flat-square"></a> |
| <a title="JavaScript" target="_blank" href="https://www.npmjs.com/package/apache-iggy"><img alt="NPM" src="https://img.shields.io/npm/v/apache-iggy?label=npm&logo=npm&style=flat-square"></a> |
| <a title="Python" target="_blank" href="https://pypi.org/project/apache-iggy/"><img alt="PyPI" src="https://img.shields.io/pypi/v/apache-iggy?label=pypi&logo=pypi&style=flat-square"></a> |
| <a title="Java" target="_blank" href="https://central.sonatype.com/artifact/org.apache.iggy/iggy"><img alt="Maven Central" src="https://img.shields.io/maven-central/v/org.apache.iggy/iggy?label=maven&logo=apachemaven&style=flat-square"></a> |
| <a title=".NET" target="_blank" href="https://www.nuget.org/packages/Apache.Iggy/"><img alt="NuGet" src="https://img.shields.io/nuget/v/Apache.Iggy?label=nuget&logo=nuget&style=flat-square"></a> |
| <a title="Apache 2.0" target="_blank" href="https://github.com/apache/iggy/blob/master/LICENSE"><img alt="License: Apache 2.0" src="https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square"></a> |
| <br> |
| <a title="Crates Downloads" target="_blank" href="https://crates.io/crates/iggy"><img alt="Crate Downloads" src="https://img.shields.io/crates/d/iggy.svg?style=flat-square"></a> |
| <a title="Code Coverage" target="_blank" href="https://codecov.io/github/apache/iggy"><img alt="Code Coverage" src="https://codecov.io/github/apache/iggy/graph/badge.svg?token=D9TIWPBWE2"></a> |
| <a title="Dependencies" target="_blank" href="https://deps.rs/repo/github/apache/iggy"><img alt="Dependency Status" src="https://deps.rs/repo/github/apache/iggy/status.svg"></a> |
| <a title="GitHub Pull Requests" target="_blank" href="https://github.com/apache/iggy/pulls"><img alt="Closed Pull Requests" src="https://img.shields.io/github/issues-pr-closed/apache/iggy.svg?style=flat-square&color=FF9966"></a> |
| <br> |
| <a title="GitHub Commits" target="_blank" href="https://github.com/apache/iggy/commits/master"><img alt="Monthly Commit Activity" src="https://img.shields.io/github/commit-activity/m/apache/iggy.svg?style=flat-square"></a> |
| <a title="Last Commit" target="_blank" href="https://github.com/apache/iggy/commits/master"><img alt="Last Commit" src="https://img.shields.io/github/last-commit/apache/iggy.svg?style=flat-square&color=FF9900"></a> |
| </p> |
| <p align="center"> |
| <a title="X" target="_blank" href="https://twitter.com/ApacheIggy"><img alt="Follow Apache Iggy on X" src="https://img.shields.io/twitter/follow/ApacheIggy?style=social"></a> |
| <a title="LinkedIn" target="_blank" href="https://www.linkedin.com/company/apache-iggy/"><img alt="Follow Apache Iggy on LinkedIn" src="https://img.shields.io/badge/LinkedIn-Apache%20Iggy-0A66C2?style=social&logo=linkedin"></a> |
| </p> |
| <p align="center"> |
| <a title="Discord" target="_blank" href="https://discord.gg/apache-iggy"><img alt="Chat with Apache Iggy community on Discord" src="https://img.shields.io/discord/1144142576266530928?label=Discord&logo=Discord&style=social"></a> |
| </p> |
| |
| **Contents:** [What is Apache Iggy?](#what-is-apache-iggy) · |
| [Features](#features) · |
| [Architecture](#architecture) · |
| [Clustering](#clustering) · |
| [Version](#version) · |
| [Supported languages SDK](#supported-languages-sdk) · |
| [CLI](#cli) · |
| [Web UI](#web-ui) · |
| [Connectors](#connectors) · |
| [Kafka gateway](#kafka-gateway) · |
| [Model Context Protocol](#model-context-protocol) · |
| [Docker](#docker) · |
| [Kubernetes](#kubernetes) · |
| [Configuration](#configuration) · |
| [Run the server](#run-the-server) · |
| [Try the CLI](#try-the-cli) · |
| [Examples](#examples) · |
| [SDK](#sdk) · |
| [Benchmarks](#benchmarks) · |
| [Contributing](#contributing) |
| |
| --- |
| |
| ## What is Apache Iggy? |
| |
| **Iggy** is a persistent message streaming platform written in Rust, supporting QUIC, WebSocket, TCP (custom binary specification) and HTTP (regular REST API) transport protocols, **capable of processing millions of messages per second at ultra-low latency**. |
| |
| Iggy provides **exceptionally high throughput and performance** while utilizing minimal computing resources. |
| |
| This is **not yet another extension** running on top of existing infrastructure, such as Kafka or SQL database. |
| |
| Iggy is a persistent message streaming log **built from the ground up** using low-level I/O with **thread-per-core shared nothing architecture**, `io_uring` and `compio` for maximum speed and efficiency. |
| |
| The name is an abbreviation for the Italian Greyhound - small yet extremely fast dogs, the best in their class. See the lovely [Fabio & Cookie](https://www.instagram.com/fabio.and.cookie/) ❤️ |
| |
| --- |
| |
| ## Features |
| |
| - **Highly performant**, persistent append-only log for message streaming |
| - **Very high throughput** for both writes and reads |
| - **Low latency and predictable resource usage** thanks to the Rust compiled language (no GC) and `io_uring`. |
| - **User authentication and authorization** with granular permissions and Personal Access Tokens (PAT) |
| - Support for multiple streams, topics and partitions |
| - Support for **multiple transport protocols** (QUIC, WebSocket, TCP, HTTP) |
| - Fully operational RESTful API which can be optionally enabled |
| - Available client SDK in multiple languages |
| - **Thread per core shared nothing design** together with `io_uring` guarantee the best possible performance on modern `Linux` systems. |
| - **Works directly with binary data**, avoiding enforced schema and serialization/deserialization overhead |
| - Custom **zero-copy (de)serialization**, which greatly improves the performance and reduces memory usage. |
| - Configurable server features (e.g. caching and transport protocols), plus per-topic segment size, durability and flush thresholds |
| - Server-side storage of **consumer offsets** |
| - Multiple ways of polling the messages: |
| - By offset (using the indexes) |
| - By timestamp (using the time indexes) |
| - First/Last N messages |
| - Next N messages for the specific consumer |
| - Optional **poll auto-commit**; processing guarantees depend on application processing and offset-commit ordering |
| - **Consumer groups** providing the message ordering and horizontal scaling across the connected clients |
| - **Message expiry** with auto deletion based on the configurable **retention policy** |
| - Additional features such as **server side message deduplication** |
| - **Multi-tenant** support via abstraction of **streams** which group **topics** |
| - **TLS** support for all transport protocols (TCP, WebSocket, QUIC, HTTPS) |
| - **[Connectors](https://github.com/apache/iggy/tree/master/core/connectors)** - sinks, sources and data transformations based on the **custom Rust plugins** |
| - **[Model Context Protocol](https://github.com/apache/iggy/tree/master/core/ai/mcp)** - provide context to LLM with **MCP server** |
| - Optional server-side as well as client-side **data encryption** using AES-256-GCM |
| - Optional metadata support in the form of **message headers** |
| - Server-side message compression is not supported yet. Topic compression values |
| are reserved for future disk/network compression support; use message headers |
| for manual compression today (see `examples/rust/src/message-headers/message-compression`). |
| - Optional **data backups and archiving** to disk or **S3** compatible cloud storage (e.g. AWS S3) |
| - Prometheus metrics for the server and connectors runtime, plus **OpenTelemetry** logs & traces in the connectors runtime. Server OTLP export is unavailable pending runtime integration. |
| - Built-in **CLI** to manage the streaming server installable via `cargo install iggy-cli` |
| - Built-in **benchmarking app** to test the performance |
| - **Single binary deployment** without an external broker or database; dynamically linked builds still require operating-system libraries |
| - Running as a single node or as a **cluster**, with data replication based on **[Viewstamped Replication (VSR)](https://github.com/apache/iggy/blob/master/assets/vsr.pdf)** |
| |
|  |
| |
|  |
| |
| --- |
| |
| ## Architecture |
| |
| This is the high-level architecture of the Iggy message streaming server, where extremely high performance and ultra low and stable tail latencies are the primary goals. The server is designed to handle high throughput and very low latency (sub-millisecond tail latencies), making it suitable for real-time applications. For more details, please refer to the [documentation](https://iggy.apache.org/docs/introduction/architecture). |
| |
|  |
| |
| --- |
| |
| ## Clustering |
| |
| Clustering is built into the standard `iggy-server` binary, with no separate build or feature flag. The same server runs as a single node or as a cluster, and `cluster.enabled` in the configuration chooses which. Clustering is disabled by default. |
| |
| Replicas stay consistent using [Viewstamped Replication (VSR)](https://github.com/apache/iggy/blob/master/assets/vsr.pdf), which commits on a quorum and elects a new primary when the current one fails. See the [clustering documentation](https://iggy.apache.org/docs/clustering/vsr) for configuration and deployment. |
| |
| --- |
| |
| ## Version |
| |
| The official releases follow semver (for example `server-0.9.0`), and the Docker images also carry the `latest` tag (`apache/iggy:latest`). |
| |
| The server, SDKs and CLI are versioned independently. For example, server 0.9.0 ships with Rust SDK 0.11.0 and CLI 0.14.0. The [server compatibility table](https://iggy.apache.org/docs/sdk/introduction#server-compatibility) lists the SDK version for each server release. |
| |
| We also publish edge releases (versions with an `-edge.N` suffix, and `apache/iggy:edge`) for the SDKs and the Docker images. They track the latest changes, but are not guaranteed to be stable and are not recommended for production use. |
| |
| --- |
| |
| ## Supported languages SDK |
| |
| - [Rust](https://crates.io/crates/iggy) |
| - [C#](https://www.nuget.org/packages/Apache.Iggy/) |
| - [Java](https://mvnrepository.com/artifact/org.apache.iggy/iggy) |
| - [Python](https://pypi.org/project/apache-iggy/) |
| - [Node.js (TypeScript)](https://www.npmjs.com/package/apache-iggy) |
| - [Go](https://pkg.go.dev/github.com/apache/iggy/foreign/go) |
| |
| [C++](https://github.com/apache/iggy/tree/master/foreign/cpp) and [PHP](https://github.com/apache/iggy/tree/master/foreign/php) are work in progress. |
| |
| --- |
| |
| ## CLI |
| |
| The interactive CLI is implemented under `core/cli`, to provide the best developer experience. This is a great addition to the Web UI, especially for all the developers who prefer using the console tools. |
| |
| Iggy CLI can be installed with `cargo install iggy-cli` and then simply accessed by typing `iggy` in your terminal. |
| |
|  |
| |
| ## Web UI |
| |
| There's a dedicated Web UI for the server, which allows managing the streams, topics, partitions, browsing the messages and so on. This is an ongoing effort to build a comprehensive dashboard for administrative purposes of the Iggy server. Check the Web UI in the `/web` directory. The [docker image for Web UI](https://hub.docker.com/r/apache/iggy-web-ui) is available, and can be fetched via `docker pull apache/iggy-web-ui`. |
| |
|  |
| |
| --- |
| |
| ## Connectors |
| |
| The highly performant and modular **[runtime](https://github.com/apache/iggy/tree/master/core/connectors)** for statically typed, yet dynamically loaded connectors. Ingest the data from the external sources and push it further to the Iggy streams, or fetch the data from the Iggy streams and push it further to the external sources. **Create your own Rust plugins** by simply implementing either the `Source` or `Sink` trait and **build custom pipelines for the data processing**. |
| |
| ```toml |
| ## Configure a sink or source connector, depending on your needs in its own config file. |
| type = "sink" |
| key = "quickwit" |
| enabled = true |
| version = 0 |
| name = "Quickwit sink" |
| path = "target/release/libiggy_connector_quickwit_sink" |
| plugin_config_format = "yaml" |
| |
| [[streams]] |
| stream = "qw" |
| topics = ["records"] |
| schema = "json" |
| batch_length = 1000 |
| poll_interval = "5ms" |
| consumer_group = "qw_sink_connector" |
| |
| [transforms.add_fields] |
| enabled = true |
| |
| [[transforms.add_fields.fields]] |
| key = "service_name" |
| value.static = "qw_connector" |
| |
| [[transforms.add_fields.fields]] |
| key = "timestamp" |
| value.computed = "timestamp_millis" |
| |
| [transforms.delete_fields] |
| enabled = true |
| fields = ["email", "created_at"] |
| ``` |
| |
| --- |
| |
| ## Kafka gateway |
| |
| The [Kafka gateway](https://github.com/apache/iggy/tree/master/gateways/kafka) is a Kafka wire protocol listener in front of Iggy, intended to let existing Kafka clients use Iggy. It is in development and not yet part of a release. See its [README](gateways/kafka/README.md) for the current status and how to run it. |
| |
| --- |
| |
| ## Model Context Protocol |
| |
| The [Model Context Protocol](https://modelcontextprotocol.io) (MCP) is an open protocol that standardizes how applications provide context to LLMs. The **[Iggy MCP Server](https://github.com/apache/iggy/tree/master/core/ai/mcp)** is an implementation of the MCP protocol for the message streaming infrastructure. It can be used to provide context to LLMs in real-time, allowing for more accurate and relevant responses. |
| |
|  |
| |
| --- |
| |
| ## Docker |
| |
| The official images are on [Docker Hub](https://hub.docker.com/r/apache/iggy). Images tagged `latest` are built from stable releases, and `edge` images are built from the latest `master` branch. Images for the other tools, such as the connectors runtime and the MCP server, are also on [Docker Hub](https://hub.docker.com/u/apache?page=1&search=iggy). |
| |
| The published image listens on `127.0.0.1` inside the container, so the host can't reach it by default. This command makes it reachable and sets the root credentials: |
| |
| ```bash |
| docker run -d --name iggy \ |
| --cap-add=SYS_NICE --security-opt seccomp=unconfined --ulimit memlock=-1:-1 \ |
| -e IGGY_ROOT_USERNAME=iggy -e IGGY_ROOT_PASSWORD=iggy \ |
| -e IGGY_TCP_ADDRESS=0.0.0.0:8090 -e IGGY_HTTP_ADDRESS=0.0.0.0:3000 \ |
| -e IGGY_NODE_ADVERTISED_ADDRESS=localhost \ |
| -p 8090:8090 -p 3000:3000 \ |
| -v iggy:/app/local_data \ |
| apache/iggy |
| ``` |
| |
| The CLI is on the image's `PATH`: |
| |
| ```bash |
| docker exec -it iggy iggy -u iggy -p iggy stream list |
| ``` |
| |
| The `SYS_NICE` capability, the seccomp setting and the unlimited locked memory are required. The [Docker & Helm](https://iggy.apache.org/docs/server/docker) page explains why, and has a `docker-compose.yml` example and the Helm chart. |
| |
| On operating systems other than Linux, Docker runs in a VM, so the container might run slower. |
| |
| To build the image from source instead, run `docker compose up` from the root of the repository. That image listens on all interfaces and keeps its data in `/local_data`. The container is named `iggy-server`, and the CLI is at `/iggy`. Set `IGGY_ROOT_USERNAME` and `IGGY_ROOT_PASSWORD` in `docker-compose.yml`. Otherwise the server generates a root password and prints it once in the container log. |
| |
| --- |
| |
| ## Kubernetes |
| |
| A Helm chart for the server and the Web UI is in [helm/charts/iggy](helm/charts/iggy): |
| |
| ```bash |
| helm install iggy ./helm/charts/iggy --set server.image.tag=0.9.0 |
| ``` |
| |
| See the chart [README](helm/charts/iggy/README.md) and the [Docker & Helm](https://iggy.apache.org/docs/server/docker) page for its settings. |
| |
| --- |
| |
| ## Configuration |
| |
| The default configuration can be found in `config.toml` file in `core/server` directory. |
| |
| The configuration file is loaded from the current working directory, but you can specify the path to the configuration file by setting `IGGY_CONFIG_PATH` environment variable, for example `export IGGY_CONFIG_PATH=core/server/config.toml` (or other command depending on OS). |
| |
| When config file is not found, the default values from embedded `config.toml` file are used. |
| |
| Topic creation accepts two independent policies: `durability` for message acknowledgments and `consumer_offset_durability` for explicit offset stores and deletes. Both default to `replicated`. This means VSR quorum commit without waiting for stable storage. `persisted` also requires recoverable stable-storage copies on the replication quorum. Both policies normally store data on disk. Poll auto-commit remains asynchronous and is not covered by the poll response's completion. |
| |
| The data directory is configured with `path` or `IGGY_PATH`. The layout beneath it is `streams/<stream>/topics/<topic>/partitions/<partition>`, with fixed directory names. |
| |
| The HTTP `Iggy-Durability` header reports `replicated` or `persisted` for awaited writes, and `none` for early dispatch acceptance. |
| |
| Segment flush thresholds control scheduling, independently of acknowledgment durability. |
| |
| Rust HTTP callers can use `HttpClient::send_messages_with_durability` to read the advertised guarantee alongside confirmations. |
| |
| The CLI exposes `--durability persisted` and `--consumer-offset-durability persisted` on `topic create`. Select either independently. The policy names describe completion guarantees and do not prescribe an I/O syscall. |
| |
| For the detailed documentation of the configuration file, please refer to the [configuration](https://iggy.apache.org/docs/server/configuration) section. |
| |
| --- |
| |
| ## Run the server |
| |
| Build the project (the longer compilation time is due to [LTO](https://doc.rust-lang.org/rustc/linker-plugin-lto.html) enabled in release [profile](https://github.com/apache/iggy/blob/master/Cargo.toml#L2): |
| |
| `cargo build` |
| |
| Run the tests: |
| |
| `cargo test` |
| |
| Set root user credentials (OPTIONAL): |
| |
| Iggy requires credentials to authenticate requests to the server. |
| You can set the root user **before** starting the server. |
| |
| (macOS/Linux) |
| |
| ```bash |
| export IGGY_ROOT_USERNAME=iggy |
| export IGGY_ROOT_PASSWORD=iggy |
| ``` |
| |
| (Windows(Powershell)) |
| |
| ```bash |
| $env:IGGY_ROOT_USERNAME = "iggy" |
| $env:IGGY_ROOT_PASSWORD = "iggy" |
| ``` |
| |
| If no root credentials are set and no users exist yet, `iggy-server` generates a random root user password and prints it once in the server log. |
| |
| Start the server: |
| |
| `cargo run --bin iggy-server` |
| |
| All the data used by the server will be persisted under the `local_data` directory by default, unless specified differently in the configuration (see `path` in `config.toml`). |
| |
| One can use default root credentials with optional `--with-default-root-credentials`. |
| This flag is equivalent to setting `IGGY_ROOT_USERNAME=iggy` and `IGGY_ROOT_PASSWORD=iggy`, plus |
| it should only be used for development and testing. |
| |
| `cargo run --bin iggy-server -- --with-default-root-credentials` |
| |
| Root credentials are only set on the first server startup when the data directory doesn't exist yet. Once the server has been started and persisted data exists, the existing root credentials will be reused, and the `--with-default-root-credentials` flag or environment variables are ignored. They are still validated, though: a half-set pair or an out-of-range value aborts the boot instead of being silently dropped. To reset credentials, delete the data directory. |
| |
| For configuration options and detailed help: |
| |
| `cargo run --bin iggy-server -- --help` |
| |
| You can also use environment variables to override any configuration setting: |
| |
| - Override TCP address |
| `IGGY_TCP_ADDRESS=127.0.0.1:8090 cargo run --bin iggy-server` |
| |
| - Set custom data path |
| `IGGY_PATH=/data/iggy cargo run --bin iggy-server` |
| |
| - Enable HTTP transport |
| `IGGY_HTTP_ENABLED=true cargo run --bin iggy-server` |
| |
| - Set custom root user credentials |
| `IGGY_ROOT_USERNAME=iggy IGGY_ROOT_PASSWORD=iggy cargo run --bin iggy-server` |
| |
| To quickly generate the sample data: |
| |
| `cargo run --bin data-seeder-tool` |
| |
| --- |
| |
| ## Try the CLI |
| |
| The commands below use the `iggy` CLI from the `core/cli` crate, run against the server started above. |
| |
| Create a stream with name `dev` (numerical ID will be assigned by server automatically) using default credentials and `tcp` transport (available transports: `quic`, `websocket`, `tcp`, `http`, default `tcp`): |
| |
| `cargo run --bin iggy -- --transport tcp --username <iggy_username> --password <iggy_password> stream create dev` |
| |
| List available streams: |
| |
| `cargo run --bin iggy -- --username <iggy_username> --password <iggy_password> stream list` |
| |
| Get `dev` stream details: |
| |
| `cargo run --bin iggy -- -u <iggy_username> -p <iggy_password> stream get dev` |
| |
| Create a topic named `sample` (numerical ID will be assigned by server automatically) for stream `dev`, with 2 partitions (IDs 0 and 1), no topic compression (`none`), and disabled message expiry (skipped optional parameter). Other compression values are reserved for future server-side support: |
| |
| `cargo run --bin iggy -- -u <iggy_username> -p <iggy_password> topic create dev sample 2 none` |
| |
| List available topics for stream `dev`: |
| |
| `cargo run --bin iggy -- -u <iggy_username> -p <iggy_password> topic list dev` |
| |
| Get topic details for topic `sample` in stream `dev`: |
| |
| `cargo run --bin iggy -- -u <iggy_username> -p <iggy_password> topic get dev sample` |
| |
| Send the first message 'hello world' to the stream `dev` to topic `sample` and partition 0: |
| |
| `cargo run --bin iggy -- -u <iggy_username> -p <iggy_password> message send --partition-id 0 dev sample "hello world"` |
| |
| Send a second message 'lorem ipsum' to the same stream, topic and partition: |
| |
| `cargo run --bin iggy -- -u <iggy_username> -p <iggy_password> message send --partition-id 0 dev sample "lorem ipsum"` |
| |
| Poll messages by a regular consumer with ID 1 from the stream `dev` for topic `sample` and partition with ID 0, starting with offset 0, messages count 2, with auto commit (storing consumer offset on server): |
| |
| `cargo run --bin iggy -- -u <iggy_username> -p <iggy_password> message poll --consumer 1 --offset 0 --message-count 2 --auto-commit dev sample 0` |
| |
| Finally, restart the server to see it is able to load the persisted data. |
| |
| The HTTP API endpoints can be found in [server.http](https://github.com/apache/iggy/blob/master/core/server/server.http) file, which can be used with [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) extension for VS Code. |
| |
| To see the detailed logs from the CLI/server, run it with the `RUST_LOG=trace` environment variable. |
| |
| --- |
| |
| ## Examples |
| |
| You can find comprehensive sample applications under the `examples/rust` directory. These examples showcase various usage patterns of the Iggy client SDK, from basic operations to advanced multi-tenant scenarios. |
| |
| For detailed information about available examples and how to run them, please see the [Examples README](examples/rust/README.md). |
| |
| There are also examples for [C#](examples/csharp/README.md), [Go](examples/go/README.md), [Java](examples/java/README.md), [Node.js](examples/node/README.md), [PHP](examples/php/README.md) and [Python](examples/python/README.md). |
| |
| --- |
| |
| ## SDK |
| |
| Iggy comes with the Rust SDK, which is available on [crates.io](https://crates.io/crates/iggy). |
| |
| The SDK provides both, low-level client for the specific transport, which includes the message sending and polling along with all the administrative actions such as managing the streams, topics, users etc., as well as the high-level client, which abstracts the low-level details and provides the easy-to-use API for both, message producers and consumers. |
| |
| You can find the more examples, including the multi-tenant one under the `examples` directory. |
| |
| ```rust |
| // Create the Iggy client |
| let client = IggyClient::from_connection_string("iggy://user:secret@localhost:8090")?; |
| |
| // Create a producer for the given stream and one of its topics |
| let mut producer = client |
| .producer("dev01", "events")? |
| .direct( // Use either direct (instant) or background message sending |
| DirectConfig::builder() |
| .batch_length(1000) |
| .linger_time(IggyDuration::from_str("1ms")?) |
| .build(), |
| ) |
| .partitioning(Partitioning::balanced()) |
| .build(); |
| |
| producer.init().await?; |
| |
| // Send some messages to the topic |
| let messages = vec![IggyMessage::from_str("Hello Apache Iggy")?]; |
| producer.send(messages).await?; |
| |
| // Create a consumer for the given stream and one of its topics |
| let mut consumer = client |
| .consumer_group("my_app", "dev01", "events")? |
| .auto_commit(AutoCommit::IntervalOrWhen( |
| NonZeroIggyDuration::from_str("1s")?, |
| AutoCommitWhen::ConsumingAllMessages, |
| )) |
| .create_consumer_group_if_not_exists() |
| .auto_join_consumer_group() |
| .polling_strategy(PollingStrategy::next()) |
| .poll_interval(IggyDuration::from_str("1ms")?) |
| .batch_length(1000) |
| .build(); |
| |
| consumer.init().await?; |
| |
| // Start consuming the messages |
| while let Some(message) = consumer.next().await { |
| // Handle the message |
| } |
| ``` |
| |
| --- |
| |
| ## Benchmarks |
| |
| **Benchmarks should be the first-class citizens**. We believe that performance is crucial for any system, and we strive to provide the best possible performance for our users. Please check, why we believe that the **[transparent |
| benchmarking](https://iggy.apache.org/blogs/2025/02/17/transparent-benchmarks)** is so important. |
| |
| We've also built the **[benchmarking platform](https://benchmarks.iggy.apache.org)** where anyone can upload the benchmarks and compare the results with others. Source code for the platform is available in the `core/bench/dashboard` directory. |
| |
|  |
| |
| For the benchmarking purposes, we've developed the dedicated **iggy-bench** tool, which is a part of the **iggy** project. It is a command-line tool that allows you to run the variety of fully customizable benchmarks. |
| |
|  |
| |
| To benchmark the project, first build the project in release mode: |
| |
| ```bash |
| cargo build --release |
| ``` |
| |
| Start `iggy-server` separately, then run the benchmarking app with the desired options: |
| |
| 1. Sending (writing) benchmark |
| |
| ```bash |
| cargo run --bin iggy-bench -r -- pinned-producer tcp |
| ``` |
| |
| 2. Polling (reading) benchmark |
| |
| ```bash |
| cargo run --bin iggy-bench -r -- pinned-consumer tcp |
| ``` |
| |
| 3. Parallel sending and polling benchmark |
| |
| ```bash |
| cargo run --bin iggy-bench -r -- pinned-producer-and-consumer tcp |
| ``` |
| |
| 4. Balanced sending to multiple partitions benchmark |
| |
| ```bash |
| cargo run --bin iggy-bench -r -- balanced-producer tcp |
| ``` |
| |
| 5. Consumer group polling benchmark: |
| |
| ```bash |
| cargo run --bin iggy-bench -r -- balanced-consumer-group tcp |
| ``` |
| |
| 6. Parallel balanced sending and polling from consumer group benchmark: |
| |
| ```bash |
| cargo run --bin iggy-bench -r -- balanced-producer-and-consumer-group tcp |
| ``` |
| |
| 7. End to end producing and consuming benchmark (single task produces and consumes messages in sequence): |
| |
| ```bash |
| cargo run --bin iggy-bench -r -- end-to-end-producing-consumer tcp |
| ``` |
| |
| 8. End to end producing and consuming through a consumer group: |
| |
| ```bash |
| cargo run --bin iggy-bench -r -- end-to-end-producing-consumer-group tcp |
| ``` |
| |
| The benchmark connects to a running server and creates the streams, topics, and partitions needed by the selected workload. Use `iggy-bench --help` and `iggy-bench examples` for all benchmark variants, transports, and topic-option examples. Both message and consumer-offset durability independently default to `replicated`. |
| |
| For example, to run the benchmark for the already started server, provide the additional argument `--server-address 127.0.0.1:8090`. |
| |
| **Iggy is already capable of processing millions of messages per second at the microseconds range for p99+ latency** Depending on the hardware, transport protocol (`quic`, `websocket`, `tcp` or `http`) and payload size (`messages-per-batch * message-size`) you might expect **over 5000 MB/s (e.g. 5M of 1 KB msg/sec) throughput for writes and reads**. |
| |
| Please refer to the mentioned [benchmarking platform](https://benchmarks.iggy.apache.org) where you can browse the results achieved on the different hardware configurations, using the different Iggy server versions. |
| |
| ### Host preparation |
| |
| Check `io_uring` access, process limits, memory headroom, CPU/NUMA placement, and sustained disk/network capacity before comparing runs. Measure host-tuning changes with the same workload and durability policies. |
| |
| Use the [benchmark host checklist](core/bench/README.md#host-preparation) for practical setup and repeatable measurements. The [Linux tuning guide](https://iggy.apache.org/docs/server/linux-tuning) explains swappiness, huge pages, writeback, CPU placement, and networking, with commands and upstream references. |
| |
| --- |
| |
| ## Contributing |
| |
| Please see [Contributing](CONTRIBUTING.md) |