This is an automated email from the ASF dual-hosted git repository.
maciej pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git
The following commit(s) were added to refs/heads/master by this push:
new b19daa9fd feat(server-ng): create iggy-server-ng binary crate (#3053)
b19daa9fd is described below
commit b19daa9fddba4672e8bf3236edf2328fb642bdf4
Author: Krishna Vishal <[email protected]>
AuthorDate: Thu Apr 2 14:38:34 2026 +0530
feat(server-ng): create iggy-server-ng binary crate (#3053)
---
.github/workflows/_common.yml | 1 +
Cargo.lock | 180 +++++++++----
Cargo.toml | 2 +
DEPENDENCIES.md | 45 ++--
core/server-ng/.dockerignore | 30 +++
core/server-ng/Cargo.toml | 183 +++++++++++++
core/server-ng/Dockerfile | 164 ++++++++++++
core/server-ng/build.rs | 87 +++++++
core/server-ng/config.toml | 590 ++++++++++++++++++++++++++++++++++++++++++
core/server-ng/server-ng.http | 376 +++++++++++++++++++++++++++
core/server-ng/src/lib.rs | 18 ++
core/server-ng/src/main.rs | 23 ++
justfile | 3 +
13 files changed, 1628 insertions(+), 74 deletions(-)
diff --git a/.github/workflows/_common.yml b/.github/workflows/_common.yml
index 6dfdb9226..3c864790d 100644
--- a/.github/workflows/_common.yml
+++ b/.github/workflows/_common.yml
@@ -122,6 +122,7 @@ jobs:
sdk
security
server
+ server-ng
shard
test
web
diff --git a/Cargo.lock b/Cargo.lock
index b5c76c369..4be27b7fb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3918,9 +3918,12 @@ dependencies = [
[[package]]
name = "fragile"
-version = "2.0.1"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619"
+checksum = "8878864ba14bb86e818a412bfd6f18f9eabd4ec0f008a28e8f7eb61db532fcf9"
+dependencies = [
+ "futures-core",
+]
[[package]]
name = "fs-err"
@@ -5085,12 +5088,13 @@ dependencies = [
[[package]]
name = "icu_collections"
-version = "2.1.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
+checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
dependencies = [
"displaydoc",
"potential_utf",
+ "utf8_iter",
"yoke",
"zerofrom",
"zerovec",
@@ -5098,9 +5102,9 @@ dependencies = [
[[package]]
name = "icu_locale_core"
-version = "2.1.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
+checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
dependencies = [
"displaydoc",
"litemap",
@@ -5111,9 +5115,9 @@ dependencies = [
[[package]]
name = "icu_normalizer"
-version = "2.1.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
+checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
dependencies = [
"icu_collections",
"icu_normalizer_data",
@@ -5125,15 +5129,15 @@ dependencies = [
[[package]]
name = "icu_normalizer_data"
-version = "2.1.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
+checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
[[package]]
name = "icu_properties"
-version = "2.1.2"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec"
+checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
dependencies = [
"icu_collections",
"icu_locale_core",
@@ -5145,15 +5149,15 @@ dependencies = [
[[package]]
name = "icu_properties_data"
-version = "2.1.2"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"
+checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
[[package]]
name = "icu_provider"
-version = "2.1.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
+checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
dependencies = [
"displaydoc",
"icu_locale_core",
@@ -5288,7 +5292,7 @@ dependencies = [
"tracing-subscriber",
"uuid",
"walkdir",
- "zip 8.4.0",
+ "zip 8.5.0",
]
[[package]]
@@ -5315,7 +5319,7 @@ dependencies = [
"tempfile",
"thiserror 2.0.18",
"tokio",
- "toml 1.1.1+spec-1.1.0",
+ "toml 1.1.2+spec-1.1.0",
"tracing",
"tracing-appender",
"tracing-subscriber",
@@ -5366,7 +5370,7 @@ dependencies = [
"tempfile",
"thiserror 2.0.18",
"tokio",
- "toml 1.1.1+spec-1.1.0",
+ "toml 1.1.2+spec-1.1.0",
"tower-http",
"tracing",
"tracing-opentelemetry",
@@ -5521,7 +5525,7 @@ dependencies = [
"simd-json",
"strum_macros 0.28.0",
"tokio",
- "toml 1.1.1+spec-1.1.0",
+ "toml 1.1.2+spec-1.1.0",
"tracing",
]
@@ -5955,12 +5959,12 @@ dependencies = [
"test-case",
"testcontainers-modules",
"tokio",
- "toml 1.1.1+spec-1.1.0",
+ "toml 1.1.2+spec-1.1.0",
"tracing",
"tracing-subscriber",
"twox-hash",
"uuid",
- "zip 8.4.0",
+ "zip 8.5.0",
]
[[package]]
@@ -6539,9 +6543,9 @@ checksum =
"32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
[[package]]
name = "litemap"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
+checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
[[package]]
name = "litrs"
@@ -8122,9 +8126,9 @@ dependencies = [
[[package]]
name = "potential_utf"
-version = "0.1.4"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
+checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
dependencies = [
"zerovec",
]
@@ -8209,7 +8213,7 @@ version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
dependencies = [
- "toml_edit 0.25.9+spec-1.1.0",
+ "toml_edit 0.25.10+spec-1.1.0",
]
[[package]]
@@ -9912,7 +9916,79 @@ dependencies = [
"sysinfo 0.38.4",
"tempfile",
"thiserror 2.0.18",
- "toml 1.1.1+spec-1.1.0",
+ "toml 1.1.2+spec-1.1.0",
+ "tower-http",
+ "tracing",
+ "tracing-appender",
+ "tracing-opentelemetry",
+ "tracing-subscriber",
+ "ulid",
+ "uuid",
+ "vergen-git2",
+]
+
+[[package]]
+name = "server-ng"
+version = "0.7.3-edge.1"
+dependencies = [
+ "ahash 0.8.12",
+ "anyhow",
+ "argon2",
+ "async-channel",
+ "async_zip",
+ "axum",
+ "axum-server",
+ "bytes",
+ "chrono",
+ "clap",
+ "compio",
+ "configs",
+ "ctrlc",
+ "cyper",
+ "cyper-axum",
+ "dashmap",
+ "dotenvy",
+ "err_trail",
+ "error_set",
+ "figlet-rs",
+ "flume 0.12.0",
+ "fs2",
+ "futures",
+ "hash32 1.0.0",
+ "human-repr",
+ "hwlocality",
+ "iggy_binary_protocol",
+ "iggy_common",
+ "jsonwebtoken",
+ "left-right",
+ "metadata",
+ "mimalloc",
+ "mime_guess",
+ "nix",
+ "opentelemetry",
+ "opentelemetry-appender-tracing",
+ "opentelemetry-otlp",
+ "opentelemetry-semantic-conventions",
+ "opentelemetry_sdk",
+ "papaya",
+ "prometheus-client",
+ "rand 0.10.0",
+ "ringbuffer",
+ "rmp-serde",
+ "rolling-file",
+ "rust-embed",
+ "rustls",
+ "rustls-pemfile",
+ "secrecy",
+ "send_wrapper",
+ "serde",
+ "slab",
+ "socket2 0.6.3",
+ "strum 0.28.0",
+ "sysinfo 0.38.4",
+ "tempfile",
+ "thiserror 2.0.18",
+ "toml 1.1.2+spec-1.1.0",
"tower-http",
"tracing",
"tracing-appender",
@@ -11002,9 +11078,9 @@ dependencies = [
[[package]]
name = "tinystr"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
+checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
dependencies = [
"displaydoc",
"zerovec",
@@ -11135,9 +11211,9 @@ dependencies = [
[[package]]
name = "toml"
-version = "1.1.1+spec-1.1.0"
+version = "1.1.2+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "994b95d9e7bae62b34bab0e2a4510b801fa466066a6a8b2b57361fa1eba068ee"
+checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee"
dependencies = [
"indexmap 2.13.0",
"serde_core",
@@ -11193,9 +11269,9 @@ dependencies = [
[[package]]
name = "toml_edit"
-version = "0.25.9+spec-1.1.0"
+version = "0.25.10+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da053d28fe57e2c9d21b48261e14e7b4c8b670b54d2c684847b91feaf4c7dac5"
+checksum = "a82418ca169e235e6c399a84e395ab6debeb3bc90edc959bf0f48647c6a32d1b"
dependencies = [
"indexmap 2.13.0",
"toml_datetime 1.1.1+spec-1.1.0",
@@ -11205,9 +11281,9 @@ dependencies = [
[[package]]
name = "toml_parser"
-version = "1.1.1+spec-1.1.0"
+version = "1.1.2+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39ca317ebc49f06bd748bfba29533eac9485569dc9bf80b849024b025e814fb9"
+checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
dependencies = [
"winnow 1.0.1",
]
@@ -13052,9 +13128,9 @@ dependencies = [
[[package]]
name = "yoke"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
+checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca"
dependencies = [
"stable_deref_trait",
"yoke-derive",
@@ -13063,9 +13139,9 @@ dependencies = [
[[package]]
name = "yoke-derive"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
+checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
dependencies = [
"proc-macro2",
"quote",
@@ -13095,18 +13171,18 @@ dependencies = [
[[package]]
name = "zerofrom"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
+checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df"
dependencies = [
"zerofrom-derive",
]
[[package]]
name = "zerofrom-derive"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
+checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
dependencies = [
"proc-macro2",
"quote",
@@ -13136,9 +13212,9 @@ dependencies = [
[[package]]
name = "zerotrie"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
+checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
dependencies = [
"displaydoc",
"yoke",
@@ -13147,9 +13223,9 @@ dependencies = [
[[package]]
name = "zerovec"
-version = "0.11.5"
+version = "0.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
+checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
dependencies = [
"yoke",
"zerofrom",
@@ -13158,9 +13234,9 @@ dependencies = [
[[package]]
name = "zerovec-derive"
-version = "0.11.2"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
+checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
dependencies = [
"proc-macro2",
"quote",
@@ -13181,9 +13257,9 @@ dependencies = [
[[package]]
name = "zip"
-version = "8.4.0"
+version = "8.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7756d0206d058333667493c4014f545f4b9603c4330ccd6d9b3f86dcab59f7d9"
+checksum = "2726508a48f38dceb22b35ecbbd2430efe34ff05c62bd3285f965d7911b33464"
dependencies = [
"crc32fast",
"flate2",
diff --git a/Cargo.toml b/Cargo.toml
index 263c99d78..877491457 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -55,6 +55,7 @@ members = [
"core/partitions",
"core/sdk",
"core/server",
+ "core/server-ng",
"core/shard",
"core/simulator",
"core/tools",
@@ -253,6 +254,7 @@ serde_with = { version = "3.18.0", features = ["base64",
"macros"] }
serde_yaml_ng = "0.10.0"
serial_test = "3.4.0"
server = { path = "core/server" }
+server-ng = { path = "core/server-ng" }
simd-json = { version = "0.17.0", features = ["serde_impl"] }
slab = "0.4.12"
socket2 = "0.6.3"
diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md
index 0135e7ed2..436e4714d 100644
--- a/DEPENDENCIES.md
+++ b/DEPENDENCIES.md
@@ -347,7 +347,7 @@ fontdb: 0.23.0, "MIT",
foreign-types: 0.3.2, "Apache-2.0 OR MIT",
foreign-types-shared: 0.1.1, "Apache-2.0 OR MIT",
form_urlencoded: 1.2.2, "Apache-2.0 OR MIT",
-fragile: 2.0.1, "Apache-2.0",
+fragile: 2.1.0, "Apache-2.0",
fs-err: 3.3.0, "Apache-2.0 OR MIT",
fs2: 0.4.3, "Apache-2.0 OR MIT",
fs_extra: 1.3.0, "MIT",
@@ -441,13 +441,13 @@ iana-time-zone-haiku: 0.1.2, "Apache-2.0 OR MIT",
iceberg: 0.9.0, "Apache-2.0",
iceberg-catalog-rest: 0.9.0, "Apache-2.0",
iceberg-storage-opendal: 0.9.0, "Apache-2.0",
-icu_collections: 2.1.1, "Unicode-3.0",
-icu_locale_core: 2.1.1, "Unicode-3.0",
-icu_normalizer: 2.1.1, "Unicode-3.0",
-icu_normalizer_data: 2.1.1, "Unicode-3.0",
-icu_properties: 2.1.2, "Unicode-3.0",
-icu_properties_data: 2.1.2, "Unicode-3.0",
-icu_provider: 2.1.1, "Unicode-3.0",
+icu_collections: 2.2.0, "Unicode-3.0",
+icu_locale_core: 2.2.0, "Unicode-3.0",
+icu_normalizer: 2.2.0, "Unicode-3.0",
+icu_normalizer_data: 2.2.0, "Unicode-3.0",
+icu_properties: 2.2.0, "Unicode-3.0",
+icu_properties_data: 2.2.0, "Unicode-3.0",
+icu_provider: 2.2.0, "Unicode-3.0",
id-arena: 2.3.0, "Apache-2.0 OR MIT",
ident_case: 1.0.1, "Apache-2.0 OR MIT",
idna: 1.1.0, "Apache-2.0 OR MIT",
@@ -551,7 +551,7 @@ libz-sys: 1.1.25, "Apache-2.0 OR MIT",
linked-hash-map: 0.5.6, "Apache-2.0 OR MIT",
linux-raw-sys: 0.4.15, "Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT",
linux-raw-sys: 0.12.1, "Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT",
-litemap: 0.8.1, "Unicode-3.0",
+litemap: 0.8.2, "Unicode-3.0",
litrs: 1.0.0, "Apache-2.0 OR MIT",
local-channel: 0.1.5, "Apache-2.0 OR MIT",
local-waker: 0.1.4, "Apache-2.0 OR MIT",
@@ -700,7 +700,7 @@ polyval: 0.6.2, "Apache-2.0 OR MIT",
portable-atomic: 1.13.1, "Apache-2.0 OR MIT",
portable-atomic-util: 0.2.6, "Apache-2.0 OR MIT",
postcard: 1.1.3, "Apache-2.0 OR MIT",
-potential_utf: 0.1.4, "Unicode-3.0",
+potential_utf: 0.1.5, "Unicode-3.0",
powerfmt: 0.2.0, "Apache-2.0 OR MIT",
ppv-lite86: 0.2.21, "Apache-2.0 OR MIT",
predicates: 3.1.4, "Apache-2.0 OR MIT",
@@ -851,6 +851,7 @@ serde_yaml_ng: 0.10.0, "MIT",
serial_test: 3.4.0, "MIT",
serial_test_derive: 3.4.0, "MIT",
server: 0.7.4-edge.1, "Apache-2.0",
+server-ng: 0.7.3-edge.1, "Apache-2.0",
sha1: 0.10.6, "Apache-2.0 OR MIT",
sha2: 0.10.9, "Apache-2.0 OR MIT",
sha3: 0.10.8, "Apache-2.0 OR MIT",
@@ -943,7 +944,7 @@ time-macros: 0.2.27, "Apache-2.0 OR MIT",
tiny-keccak: 2.0.2, "CC0-1.0",
tiny-skia: 0.11.4, "BSD-3-Clause",
tiny-skia-path: 0.11.4, "BSD-3-Clause",
-tinystr: 0.8.2, "Unicode-3.0",
+tinystr: 0.8.3, "Unicode-3.0",
tinyvec: 1.11.0, "Apache-2.0 OR MIT OR Zlib",
tinyvec_macros: 0.1.1, "Apache-2.0 OR MIT OR Zlib",
tokio: 1.50.0, "MIT",
@@ -954,13 +955,13 @@ tokio-tungstenite: 0.29.0, "MIT",
tokio-util: 0.7.18, "MIT",
tokise: 0.2.1, "Apache-2.0 OR MIT",
toml: 0.8.23, "Apache-2.0 OR MIT",
-toml: 1.1.1+spec-1.1.0, "Apache-2.0 OR MIT",
+toml: 1.1.2+spec-1.1.0, "Apache-2.0 OR MIT",
toml_datetime: 0.6.11, "Apache-2.0 OR MIT",
toml_datetime: 1.1.1+spec-1.1.0, "Apache-2.0 OR MIT",
toml_edit: 0.19.15, "Apache-2.0 OR MIT",
toml_edit: 0.22.27, "Apache-2.0 OR MIT",
-toml_edit: 0.25.9+spec-1.1.0, "Apache-2.0 OR MIT",
-toml_parser: 1.1.1+spec-1.1.0, "Apache-2.0 OR MIT",
+toml_edit: 0.25.10+spec-1.1.0, "Apache-2.0 OR MIT",
+toml_parser: 1.1.2+spec-1.1.0, "Apache-2.0 OR MIT",
toml_write: 0.1.2, "Apache-2.0 OR MIT",
toml_writer: 1.1.1+spec-1.1.0, "Apache-2.0 OR MIT",
tonic: 0.14.5, "MIT",
@@ -1153,19 +1154,19 @@ yew: 0.23.0, "Apache-2.0 OR MIT",
yew-macro: 0.23.0, "Apache-2.0 OR MIT",
yew-router: 0.20.0, "Apache-2.0 OR MIT",
yew-router-macro: 0.20.0, "Apache-2.0 OR MIT",
-yoke: 0.8.1, "Unicode-3.0",
-yoke-derive: 0.8.1, "Unicode-3.0",
+yoke: 0.8.2, "Unicode-3.0",
+yoke-derive: 0.8.2, "Unicode-3.0",
zerocopy: 0.8.48, "Apache-2.0 OR BSD-2-Clause OR MIT",
zerocopy-derive: 0.8.48, "Apache-2.0 OR BSD-2-Clause OR MIT",
-zerofrom: 0.1.6, "Unicode-3.0",
-zerofrom-derive: 0.1.6, "Unicode-3.0",
+zerofrom: 0.1.7, "Unicode-3.0",
+zerofrom-derive: 0.1.7, "Unicode-3.0",
zeroize: 1.8.2, "Apache-2.0 OR MIT",
zeroize_derive: 1.4.3, "Apache-2.0 OR MIT",
-zerotrie: 0.2.3, "Unicode-3.0",
-zerovec: 0.11.5, "Unicode-3.0",
-zerovec-derive: 0.11.2, "Unicode-3.0",
+zerotrie: 0.2.4, "Unicode-3.0",
+zerovec: 0.11.6, "Unicode-3.0",
+zerovec-derive: 0.11.3, "Unicode-3.0",
zip: 0.6.6, "MIT",
-zip: 8.4.0, "MIT",
+zip: 8.5.0, "MIT",
zlib-rs: 0.6.3, "Zlib",
zmij: 1.0.21, "MIT",
zopfli: 0.8.3, "Apache-2.0",
diff --git a/core/server-ng/.dockerignore b/core/server-ng/.dockerignore
new file mode 100644
index 000000000..e2fdd5f0d
--- /dev/null
+++ b/core/server-ng/.dockerignore
@@ -0,0 +1,30 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+.config
+.github
+/assets
+/local_data
+/licenses
+/certs
+/helm
+/web
+Dockerfile
+docker-compose.yml
+.dockerignore
+.git
+.gitignore
diff --git a/core/server-ng/Cargo.toml b/core/server-ng/Cargo.toml
new file mode 100644
index 000000000..0f5f045fa
--- /dev/null
+++ b/core/server-ng/Cargo.toml
@@ -0,0 +1,183 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+name = "server-ng"
+version = "0.7.3-edge.1"
+edition = "2024"
+license = "Apache-2.0"
+
+[package.metadata.cargo-udeps.ignore]
+normal = ["tracing-appender"]
+
+[package.metadata.cargo-machete]
+ignored = [
+ "ahash",
+ "anyhow",
+ "argon2",
+ "async-channel",
+ "async_zip",
+ "axum",
+ "axum-server",
+ "bytes",
+ "chrono",
+ "clap",
+ "compio",
+ "configs",
+ "ctrlc",
+ "cyper",
+ "cyper-axum",
+ "dashmap",
+ "dotenvy",
+ "err_trail",
+ "error_set",
+ "figlet-rs",
+ "flume",
+ "fs2",
+ "futures",
+ "hash32",
+ "human-repr",
+ "hwlocality",
+ "iggy_binary_protocol",
+ "iggy_common",
+ "jsonwebtoken",
+ "left-right",
+ "metadata",
+ "mimalloc",
+ "mime_guess",
+ "nix",
+ "opentelemetry",
+ "opentelemetry-appender-tracing",
+ "opentelemetry-otlp",
+ "opentelemetry-semantic-conventions",
+ "opentelemetry_sdk",
+ "papaya",
+ "prometheus-client",
+ "rand",
+ "ringbuffer",
+ "rmp-serde",
+ "rolling-file",
+ "rust-embed",
+ "rustls",
+ "rustls-pemfile",
+ "secrecy",
+ "send_wrapper",
+ "serde",
+ "slab",
+ "socket2",
+ "strum",
+ "sysinfo",
+ "tempfile",
+ "thiserror",
+ "toml",
+ "tower-http",
+ "tracing-appender",
+ "tracing-opentelemetry",
+ "ulid",
+ "uuid",
+ "vergen-git2",
+]
+
+[[bin]]
+name = "iggy-server-ng"
+path = "src/main.rs"
+
+[features]
+default = ["mimalloc", "iggy-web"]
+disable-mimalloc = []
+mimalloc = ["dep:mimalloc"]
+iggy-web = ["dep:rust-embed", "dep:mime_guess"]
+
+[dependencies]
+ahash = { workspace = true }
+anyhow = { workspace = true }
+argon2 = { workspace = true }
+async-channel = { workspace = true }
+async_zip = { workspace = true }
+axum = { workspace = true }
+axum-server = { workspace = true }
+bytes = { workspace = true }
+chrono = { workspace = true }
+clap = { workspace = true }
+compio = { workspace = true }
+configs = { workspace = true }
+ctrlc = { workspace = true }
+cyper = { workspace = true }
+cyper-axum = { workspace = true }
+dashmap = { workspace = true }
+dotenvy = { workspace = true }
+err_trail = { workspace = true }
+error_set = { workspace = true }
+figlet-rs = { workspace = true }
+flume = { workspace = true }
+fs2 = { workspace = true }
+futures = { workspace = true }
+hash32 = { workspace = true }
+human-repr = { workspace = true }
+iggy_binary_protocol = { workspace = true }
+iggy_common = { workspace = true }
+jsonwebtoken = { workspace = true }
+left-right = { workspace = true }
+metadata = { workspace = true }
+mimalloc = { workspace = true, optional = true }
+mime_guess = { workspace = true, optional = true }
+nix = { workspace = true }
+opentelemetry = { workspace = true }
+opentelemetry-appender-tracing = { workspace = true }
+opentelemetry-otlp = { workspace = true }
+opentelemetry-semantic-conventions = { workspace = true }
+opentelemetry_sdk = { workspace = true }
+papaya = { workspace = true }
+prometheus-client = { workspace = true }
+rand = { workspace = true }
+ringbuffer = { workspace = true }
+rmp-serde = { workspace = true }
+rolling-file = { workspace = true }
+rust-embed = { workspace = true, optional = true }
+rustls = { workspace = true }
+rustls-pemfile = { workspace = true }
+secrecy = { workspace = true }
+send_wrapper = { workspace = true }
+serde = { workspace = true }
+slab = { workspace = true }
+socket2 = { workspace = true }
+strum = { workspace = true }
+sysinfo = { workspace = true }
+tempfile = { workspace = true }
+thiserror = { workspace = true }
+toml = { workspace = true }
+tower-http = { workspace = true }
+tracing = { workspace = true }
+tracing-appender = { workspace = true }
+tracing-opentelemetry = { workspace = true }
+tracing-subscriber = { workspace = true }
+ulid = { workspace = true }
+uuid = { workspace = true }
+
+[target.'cfg(not(target_env = "musl"))'.dependencies]
+hwlocality = { workspace = true }
+
+[target.'cfg(target_env = "musl")'.dependencies]
+hwlocality = { workspace = true, features = ["vendored"] }
+
+[build-dependencies]
+vergen-git2 = { workspace = true }
+
+[lints.clippy]
+enum_glob_use = "deny"
+pedantic = "deny"
+nursery = "warn"
diff --git a/core/server-ng/Dockerfile b/core/server-ng/Dockerfile
new file mode 100644
index 000000000..b7be72884
--- /dev/null
+++ b/core/server-ng/Dockerfile
@@ -0,0 +1,164 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+ARG RUST_VERSION=1.94
+ARG ALPINE_VERSION=3.22
+
+# ── from-source path ─────────────────────────────────────────────────────────
+FROM --platform=$BUILDPLATFORM
lukemathwalker/cargo-chef:latest-rust-${RUST_VERSION}-alpine AS chef
+WORKDIR /app
+RUN apk add --no-cache musl-dev pkgconfig
+
+FROM --platform=$BUILDPLATFORM chef AS planner
+COPY . .
+RUN cargo chef prepare --recipe-path recipe.json
+
+FROM --platform=$BUILDPLATFORM chef AS builder
+ARG PROFILE=release
+ARG TARGETPLATFORM
+ARG LIBC=musl
+ARG IGGY_CI_BUILD
+ENV IGGY_CI_BUILD=${IGGY_CI_BUILD}
+
+RUN apk add --no-cache zig make autoconf automake libtool pkgconfig hwloc-dev
xz-dev xz-static nodejs npm && \
+ cargo install cargo-zigbuild --locked && \
+ rustup target add \
+ x86_64-unknown-linux-musl \
+ aarch64-unknown-linux-musl \
+ x86_64-unknown-linux-gnu \
+ aarch64-unknown-linux-gnu
+
+# Allow pkg-config to work in cross-compilation mode (needed for
hwlocality-sys)
+ENV PKG_CONFIG_ALLOW_CROSS=1
+
+COPY --from=planner /app/recipe.json recipe.json
+
+RUN
--mount=type=cache,target=/usr/local/cargo/registry,id=cargo-registry-${TARGETPLATFORM}-${LIBC}
\
+
--mount=type=cache,target=/usr/local/cargo/git,id=cargo-git-${TARGETPLATFORM}-${LIBC}
\
+
--mount=type=cache,target=/app/target,id=cargo-target-${TARGETPLATFORM}-${LIBC}
\
+ case "$TARGETPLATFORM:$LIBC" in \
+ "linux/amd64:musl") RUST_TARGET="x86_64-unknown-linux-musl" ;; \
+ "linux/arm64:musl") RUST_TARGET="aarch64-unknown-linux-musl" ;; \
+ "linux/amd64:glibc") RUST_TARGET="x86_64-unknown-linux-gnu" ;; \
+ "linux/arm64:glibc") RUST_TARGET="aarch64-unknown-linux-gnu" ;; \
+ *) echo "Unsupported $TARGETPLATFORM/$LIBC" && exit 1 ;; \
+ esac && \
+ if [ "$PROFILE" = "debug" ]; then \
+ cargo chef cook --recipe-path recipe.json --target ${RUST_TARGET}
--zigbuild \
+ -p server-ng -p iggy-cli; \
+ else \
+ cargo chef cook --recipe-path recipe.json --target ${RUST_TARGET}
--zigbuild --release \
+ -p server-ng -p iggy-cli; \
+ fi
+
+COPY . .
+
+# Build Web UI static files for embedding
+RUN npm --prefix web ci && npm --prefix web run build:static
+
+RUN
--mount=type=cache,target=/usr/local/cargo/registry,id=cargo-registry-${TARGETPLATFORM}-${LIBC}
\
+
--mount=type=cache,target=/usr/local/cargo/git,id=cargo-git-${TARGETPLATFORM}-${LIBC}
\
+
--mount=type=cache,target=/app/target,id=cargo-target-${TARGETPLATFORM}-${LIBC}
\
+ case "$TARGETPLATFORM:$LIBC" in \
+ "linux/amd64:musl") RUST_TARGET="x86_64-unknown-linux-musl" ;; \
+ "linux/arm64:musl") RUST_TARGET="aarch64-unknown-linux-musl" ;; \
+ "linux/amd64:glibc") RUST_TARGET="x86_64-unknown-linux-gnu" ;; \
+ "linux/arm64:glibc") RUST_TARGET="aarch64-unknown-linux-gnu" ;; \
+ *) echo "Unsupported $TARGETPLATFORM/$LIBC" && exit 1 ;; \
+ esac && \
+ if [ "$PROFILE" = "debug" ]; then \
+ cargo zigbuild --locked --target ${RUST_TARGET} --bin iggy-server-ng --bin
iggy && \
+ cp /app/target/${RUST_TARGET}/debug/iggy-server-ng /app/iggy-server-ng && \
+ cp /app/target/${RUST_TARGET}/debug/iggy /app/iggy; \
+ else \
+ cargo zigbuild --locked --target ${RUST_TARGET} --bin iggy-server-ng --bin
iggy --release && \
+ cp /app/target/${RUST_TARGET}/release/iggy-server-ng /app/iggy-server-ng
&& \
+ cp /app/target/${RUST_TARGET}/release/iggy /app/iggy; \
+ fi
+
+# ── prebuilt path (FAST)
──────────────────────────────────────────────────────
+FROM debian:trixie-slim AS prebuilt
+WORKDIR /out
+ARG PREBUILT_IGGY_SERVER_NG
+ARG PREBUILT_IGGY_CLI
+COPY ${PREBUILT_IGGY_SERVER_NG} /out/iggy-server-ng
+COPY ${PREBUILT_IGGY_CLI} /out/iggy
+RUN chmod +x /out/iggy-server-ng /out/iggy
+
+# ── final images
──────────────────────────────────────────────────────────────
+FROM debian:trixie-slim AS runtime-prebuilt
+ARG TARGETPLATFORM
+ARG PREBUILT_IGGY_SERVER_NG
+ARG PREBUILT_IGGY_CLI
+WORKDIR /app
+RUN apt-get update && apt-get install -y \
+ libhwloc-dev \
+ libudev-dev \
+ pkg-config \
+ && rm -rf /var/lib/apt/lists/*
+COPY --from=prebuilt /out/iggy-server-ng /usr/local/bin/iggy-server-ng
+COPY --from=prebuilt /out/iggy /usr/local/bin/iggy
+RUN echo "═══════════════════════════════════════════════════════════════" && \
+ echo " IGGY SERVER-NG BUILD SUMMARY " && \
+ echo "═══════════════════════════════════════════════════════════════" && \
+ echo "Build Type: PREBUILT BINARIES" && \
+ echo "Platform: ${TARGETPLATFORM:-linux/amd64}" && \
+ echo "Source Path: ${PREBUILT_IGGY_SERVER_NG:-not specified}" && \
+ echo "Binary Info:" && \
+ (command -v file >/dev/null 2>&1 && file /usr/local/bin/iggy-server-ng |
sed 's/^/ /' || \
+ echo " $(ldd /usr/local/bin/iggy-server-ng 2>&1 | head -1)") && \
+ echo "Binary Size:" && \
+ ls -lh /usr/local/bin/iggy-server-ng /usr/local/bin/iggy | awk '{print "
" $9 ": " $5}' && \
+ echo "Build Date: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" && \
+ echo "Container Base: debian:trixie-slim" && \
+ echo "═══════════════════════════════════════════════════════════════"
+ENTRYPOINT ["iggy-server-ng"]
+
+FROM debian:trixie-slim AS runtime
+ARG TARGETPLATFORM
+ARG PROFILE=release
+ARG LIBC=musl
+WORKDIR /app
+RUN apt-get update && apt-get install -y \
+ libhwloc15 \
+ libudev1 \
+ pkg-config \
+ && rm -rf /var/lib/apt/lists/*
+COPY --from=builder /app/iggy-server-ng /usr/local/bin/iggy-server-ng
+COPY --from=builder /app/iggy /usr/local/bin/iggy
+RUN echo "═══════════════════════════════════════════════════════════════" && \
+ echo " IGGY SERVER-NG BUILD SUMMARY " && \
+ echo "═══════════════════════════════════════════════════════════════" && \
+ echo "Build Type: FROM SOURCE" && \
+ echo "Platform: ${TARGETPLATFORM:-linux/amd64}" && \
+ echo "Profile: ${PROFILE}" && \
+ echo "Libc: ${LIBC}" && \
+ case "${TARGETPLATFORM:-linux/amd64}:${LIBC}" in \
+ "linux/amd64:musl") echo "Target: x86_64-unknown-linux-musl" ;; \
+ "linux/arm64:musl") echo "Target: aarch64-unknown-linux-musl" ;; \
+ "linux/amd64:glibc") echo "Target: x86_64-unknown-linux-gnu" ;; \
+ "linux/arm64:glibc") echo "Target: aarch64-unknown-linux-gnu" ;; \
+ *) echo "Target: unknown" ;; \
+ esac && \
+ echo "Binary Info:" && \
+ (command -v file >/dev/null 2>&1 && file /usr/local/bin/iggy-server-ng |
sed 's/^/ /' || \
+ echo " $(ldd /usr/local/bin/iggy-server-ng 2>&1 | head -1)") && \
+ echo "Binary Size:" && \
+ ls -lh /usr/local/bin/iggy-server-ng /usr/local/bin/iggy | awk '{print "
" $9 ": " $5}' && \
+ echo "Build Date: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" && \
+ echo "═══════════════════════════════════════════════════════════════"
+ENTRYPOINT ["iggy-server-ng"]
diff --git a/core/server-ng/build.rs b/core/server-ng/build.rs
new file mode 100644
index 000000000..17761da6a
--- /dev/null
+++ b/core/server-ng/build.rs
@@ -0,0 +1,87 @@
+/* Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use std::path::PathBuf;
+use std::{env, error};
+use vergen_git2::{BuildBuilder, CargoBuilder, Emitter, Git2Builder,
RustcBuilder, SysinfoBuilder};
+
+const WEB_ASSETS_PATH: &str = "web/build/static";
+const WEB_INDEX_FILE: &str = "web/build/static/index.html";
+
+fn main() -> Result<(), Box<dyn error::Error>> {
+ verify_web_assets_if_enabled();
+ emit_vergen_instructions()?;
+ Ok(())
+}
+
+/// Returns the workspace root (iggy/), two levels up from core/server-ng.
+fn workspace_root() -> PathBuf {
+ PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
+ .parent()
+ .and_then(|p| p.parent())
+ .expect("server-ng crate must be at core/server-ng within workspace")
+ .to_path_buf()
+}
+
+fn emit_vergen_instructions() -> Result<(), Box<dyn error::Error>> {
+ if option_env!("IGGY_CI_BUILD") != Some("true") {
+ println!("cargo:info=Skipping vergen because IGGY_CI_BUILD is not set
to 'true'");
+ return Ok(());
+ }
+
+ Emitter::default()
+ .add_instructions(&BuildBuilder::all_build()?)?
+ .add_instructions(&CargoBuilder::all_cargo()?)?
+ .add_instructions(&Git2Builder::all_git()?)?
+ .add_instructions(&RustcBuilder::all_rustc()?)?
+ .add_instructions(&SysinfoBuilder::all_sysinfo()?)?
+ .emit()?;
+
+ let configs_path = workspace_root()
+ .join("core/configs")
+ .canonicalize()
+ .unwrap_or_else(|e| panic!("Failed to canonicalize configs path:
{e}"));
+
+ println!("cargo:rerun-if-changed={}", configs_path.display());
+ Ok(())
+}
+
+fn verify_web_assets_if_enabled() {
+ if env::var("CARGO_FEATURE_IGGY_WEB").is_err() {
+ return;
+ }
+
+ let assets_dir = workspace_root().join(WEB_ASSETS_PATH);
+ let index_file = workspace_root().join(WEB_INDEX_FILE);
+
+ println!("cargo:rerun-if-changed={}", assets_dir.display());
+
+ if !assets_dir.exists() || !index_file.exists() {
+ println!(
+ "cargo:info=Web UI assets not found at {}. \
+ To build them, run: npm --prefix web ci && npm --prefix web run
build:static",
+ assets_dir.display()
+ );
+ return;
+ }
+
+ println!(
+ "cargo:info=Web UI assets verified at {}",
+ assets_dir.display()
+ );
+}
diff --git a/core/server-ng/config.toml b/core/server-ng/config.toml
new file mode 100644
index 000000000..b3be68e58
--- /dev/null
+++ b/core/server-ng/config.toml
@@ -0,0 +1,590 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Configuration for consumer group cooperative partition rebalancing.
+[consumer_group]
+# Maximum time a partition can remain in pending revocation before being
force-transferred to the target member.
+rebalancing_timeout = "30s"
+# How often the periodic checker scans for timed-out pending revocations.
+rebalancing_check_interval = "5s"
+
+[data_maintenance.messages]
+# Enables or disables the expired message cleaner process.
+cleaner_enabled = false
+
+# Interval for running the message cleaner.
+interval = "1 m"
+
+# HTTP server configuration
+[http]
+# Determines if the HTTP server is active.
+# `true` enables the server, allowing it to handle HTTP requests.
+# `false` disables the server, preventing it from handling HTTP requests.
+enabled = true
+
+# Specifies the network address and port for the HTTP server.
+# The format is "HOST:PORT". For example, "127.0.0.1:3000" listens on
localhost only on port 3000.
+address = "127.0.0.1:3000"
+
+# Maximum size of the request body in bytes. For security reasons, the default
limit is 2 MB.
+max_request_size = "2 MB"
+
+# Enables the embedded Web UI dashboard at '/ui'.
+# When set to `true` and the server is compiled with the 'iggy-web' feature,
+# the Svelte dashboard will be served at the '/ui' endpoint, providing a
+# browser-based interface for managing streams, topics, and viewing messages.
+# If the server is compiled without 'iggy-web' feature and this is set to
`true`,
+# a warning will be logged at startup but the server will continue to run.
+# `true` enables the embedded Web UI (requires server built with 'iggy-web'
feature).
+# `false` disables the embedded Web UI (default).
+web_ui = false
+
+# Configuration for Cross-Origin Resource Sharing (CORS).
+[http.cors]
+# Controls whether CORS is enabled for the HTTP server.
+# `true` allows handling cross-origin requests with specified rules.
+# `false` blocks cross-origin requests, enhancing security.
+enabled = true
+
+# Specifies which HTTP methods are allowed when CORS is enabled.
+# For example, ["GET", "POST"] would allow only GET and POST requests.
+allowed_methods = ["GET", "POST", "PUT", "DELETE"]
+
+# Defines which origins are permitted to make cross-origin requests.
+# An asterisk "*" allows all origins. Specific domains can be listed to
restrict access.
+allowed_origins = ["*"]
+
+# Lists allowed headers that can be used in CORS requests.
+# For example, ["content-type"] permits only the content-type header.
+allowed_headers = ["content-type", "authorization"]
+
+# Headers that browsers are allowed to access in CORS responses.
+# An empty array means no additional headers are exposed to browsers.
+exposed_headers = [""]
+
+# Determines if credentials like cookies or HTTP auth can be included in CORS
requests.
+# `true` allows credentials to be included, useful for authenticated sessions.
+# `false` prevents credentials, enhancing privacy and security.
+allow_credentials = false
+
+# Allows or blocks requests from private networks in CORS.
+# `true` permits requests from private networks.
+# `false` disallows such requests, providing additional security.
+allow_private_network = false
+
+# JWT (JSON Web Token) configuration for HTTP.
+[http.jwt]
+# Specifies the algorithm used for signing JWTs.
+# For example, "HS256" indicates HMAC with SHA-256.
+algorithm = "HS256"
+
+# The issuer of the JWT, typically a URL or an identifier of the issuing
entity.
+issuer = "iggy.apache.org"
+
+# Intended audience for the JWT, usually the recipient or system intended to
process the token.
+audience = "iggy.apache.org"
+
+# Lists valid issuers for JWT validation to ensure tokens are from trusted
sources.
+valid_issuers = ["iggy.apache.org"]
+
+# Lists valid audiences for JWT validation to confirm tokens are for the
intended recipient.
+valid_audiences = ["iggy.apache.org"]
+
+# Expiry time for access tokens.
+access_token_expiry = "1 h"
+
+# Tolerance for timing discrepancies during token validation.
+clock_skew = "5 s"
+
+# Time before which the token should not be considered valid.
+not_before = "0 s"
+
+# Secret key for encoding JWTs.
+# If left empty, a secure random secret will be generated on each server start.
+encoding_secret = ""
+
+# Secret key for decoding JWTs.
+# If left empty, a secure random secret will be generated on each server start.
+decoding_secret = ""
+
+# Indicates if the secret key is base64 encoded.
+# `true` means the secret is base64 encoded.
+# `false` means the secret is in plain text.
+use_base64_secret = false
+
+# Metrics configuration for HTTP.
+[http.metrics]
+# Enable or disable the metrics endpoint.
+# `true` makes metrics available at the specified endpoint.
+# `false` disables metrics collection.
+enabled = true
+
+# Specifies the endpoint for accessing metrics, e.g., "/metrics".
+endpoint = "/metrics"
+
+# TLS (Transport Layer Security) configuration for HTTP.
+[http.tls]
+# Controls the use of TLS for encrypted HTTP connections.
+# `true` enables TLS, enhancing security.
+# `false` disables TLS, which may be appropriate in secure internal networks.
+enabled = false
+
+# Path to the TLS certificate file.
+cert_file = "core/certs/iggy_cert.pem"
+
+# Path to the TLS key file.
+key_file = "core/certs/iggy_key.pem"
+
+# TCP server configuration.
+[tcp]
+# Determines if the TCP server is active.
+# `true` enables the TCP server for handling TCP connections.
+# `false` disables it, preventing any TCP communication.
+enabled = true
+
+# Defines the network address and port for the TCP server.
+# For example, "127.0.0.1:8090" listens on localhost only on port 8090.
+address = "127.0.0.1:8090"
+
+# Enable TCP socket migration across shards.
+socket_migration = true
+
+# Whether to use ipv4 or ipv6
+ipv6 = false
+
+# TLS configuration for the TCP server.
+[tcp.tls]
+# Enables or disables TLS for TCP connections.
+# `true` secures TCP connections with TLS.
+# `false` leaves TCP connections unencrypted.
+enabled = false
+
+# Enables or disables self-signed certificate generation.
+# `true` generates a self-signed certificate if cert files don't exist.
+# `false` requires certificate files to exist at the specified paths.
+self_signed = true
+
+# Path to the TLS certificate file.
+cert_file = "core/certs/iggy_cert.pem"
+
+# Path to the TLS key file.
+key_file = "core/certs/iggy_key.pem"
+
+# Configuration for the TCP socket
+[tcp.socket]
+# Whether to overwrite the OS-default socket parameters
+override_defaults = false
+
+# SO_RCVBUF: maximum size of the receive buffer, can be clamped by the OS
+recv_buffer_size = "100 KB"
+
+# SO_SNDBUF: maximum size of the send buffer, can be clamped by the OS
+send_buffer_size = "100 KB"
+
+# SO_KEEPALIVE: whether to regularly send a keepalive packet maintaining the
connection
+keepalive = false
+
+# TCP_NODELAY: enable/disable the Nagle algorithm which buffers data before
sending segments
+nodelay = false
+
+# SO_LINGER: delay to wait for while data is being transmitted before closing
the socket after a
+# close or shutdown call has been received
+linger = "0 s"
+
+# QUIC protocol configuration.
+[quic]
+# Controls whether the QUIC server is enabled.
+# `true` enables QUIC for fast, secure connections.
+# `false` disables QUIC, possibly for compatibility or simplicity.
+enabled = true
+
+# Network address and port for the QUIC server.
+# For example, "127.0.0.1:8080" binds to localhost on port 8080.
+address = "127.0.0.1:8080"
+
+# Maximum number of simultaneous bidirectional streams in QUIC.
+max_concurrent_bidi_streams = 10_000
+
+# Size of the buffer for sending datagrams in QUIC.
+datagram_send_buffer_size = "100 KB"
+
+# Initial Maximum Transmission Unit (MTU) for QUIC connections.
+initial_mtu = "8 KB"
+
+# Size of the sending window in QUIC, controlling data flow.
+send_window = "100 KB"
+
+# Size of the receiving window in QUIC, controlling data flow.
+receive_window = "100 KB"
+
+# Interval for sending keep-alive messages in QUIC.
+keep_alive_interval = "5 s"
+
+# Maximum idle time before a QUIC connection is closed.
+max_idle_timeout = "10 s"
+
+# QUIC certificate configuration.
+[quic.certificate]
+# Indicates whether the QUIC certificate is self-signed.
+# `true` for self-signed certificates, often used in internal or testing
environments.
+# `false` for certificates issued by a certificate authority, common in
production.
+self_signed = true
+
+# Path to the QUIC TLS certificate file.
+cert_file = "core/certs/iggy_cert.pem"
+
+# Path to the QUIC TLS key file.
+key_file = "core/certs/iggy_key.pem"
+
+# Configuration for the QUIC socket
+[quic.socket]
+# Whether to override the OS-default socket parameters
+override_defaults = false
+
+# SO_RCVBUF: maximum size of the receive buffer, can be clamped by the OS
+recv_buffer_size = "64 KB"
+
+# SO_SNDBUF: maximum size of the send buffer, can be clamped by the OS
+send_buffer_size = "64 KB"
+
+# SO_KEEPALIVE: whether to regularly send a keepalive packet maintaining the
connection
+keepalive = false
+
+# Message saver configuration.
+[message_saver]
+# Enables or disables the background process for saving buffered data to disk.
+# `true` ensures data is periodically written to disk.
+# `false` turns off automatic saving, relying on other triggers for data
persistence.
+enabled = true
+
+# Controls whether data saving is synchronous (enforce fsync) or asynchronous.
+# `true` for synchronous saving, ensuring data integrity at the cost of
performance.
+# `false` for asynchronous saving, improving performance but with delayed data
writing.
+enforce_fsync = true
+
+# Interval for running the message saver.
+interval = "30 s"
+
+# Personal access token configuration.
+[personal_access_token]
+# Sets the maximum number of active tokens allowed per user.
+max_tokens_per_user = 100
+
+# Personal access token cleaner configuration.
+[personal_access_token.cleaner]
+# Enables or disables the token cleaner process.
+# `true` activates periodic token cleaning.
+# `false` disables it, tokens remain active until manually revoked or expired.
+enabled = true
+
+# Interval for running the token cleaner.
+interval = "1 m"
+
+# Heartbeat configuration
+[heartbeat]
+# Enables or disables the client heartbeat verification process.
+enabled = false
+# Interval for expected client heartbeats
+interval = "5 s"
+
+# OpenTelemetry configuration
+[telemetry]
+# Enables or disables telemetry.
+enabled = false
+# Service name for telemetry.
+service_name = "iggy"
+
+# OpenTelemetry logs configuration
+[telemetry.logs]
+# Transport for sending logs. Options: "grpc", "http".
+transport = "grpc"
+# Endpoint for sending logs.
+endpoint = "http://localhost:7281/v1/logs"
+
+# OpenTelemetry traces configuration
+[telemetry.traces]
+# Transport for sending traces. Options: "grpc", "http".
+transport = "grpc"
+# Endpoint for sending traces.
+endpoint = "http://localhost:7281/v1/traces"
+
+# System configuration.
+[system]
+# Base path for system data storage.
+path = "local_data"
+
+# Backup configuration
+[system.backup]
+# Path for storing backup.
+path = "backup"
+
+# Compatibility conversion configuration
+[system.backup.compatibility]
+# Subpath of the backup directory where converted segment data is stored after
compatibility conversion.
+path = "compatibility"
+
+[system.state]
+# Determines whether to enforce file synchronization on state updates
(boolean).
+# `true` ensures immediate writing of data to disk for durability.
+# `false` allows the OS to manage write operations, which can improve
performance.
+enforce_fsync = false
+
+# Maximum number of retries for a failed file operation (e.g., append,
overwrite).
+# This defines how many times the system will attempt the operation before
failing.
+max_file_operation_retries = 1
+
+# Delay between retries in case of a failed file operation.
+# This helps to avoid immediate repeated attempts and can reduce load.
+retry_delay = "1 s"
+
+# Runtime configuration.
+[system.runtime]
+# Path for storing runtime data.
+# Specifies the directory where any runtime data is stored, relative to
`system.path`.
+path = "runtime"
+
+# Logging configuration.
+[system.logging]
+# Path for storing log files.
+path = "logs"
+
+# Log filtering directive using the same syntax as the RUST_LOG environment
variable.
+# Supports simple levels ("trace", "debug", "info", "warn", "error", "off" or
"none")
+# as well as complex directives like "warn,server=debug,iggy=trace".
+# Note: RUST_LOG environment variable always takes precedence over this
setting.
+level = "info"
+
+# Whether to write logs to file. When false, logs are only written to stdout.
+# When enabled, logs are stored in {system.path}/{system.logging.path}
(default: local_data/logs).
+file_enabled = true
+
+# Maximum size of a single log file before rotation occurs. When a log
+# file reaches this size, it will be rotated (closed and a new file
+# created). This setting works together with max_total_size to control
+# log storage. You can set it to 0 to enable unlimited size of single
+# log, but all logs will be written to a single file, thus disabling
+# log rotation. Please configure 0 with caution, esp. RUST_LOG > debug
+max_file_size = "500 MB"
+
+# Maximum total size of all log files. When this size is reached,
+# the oldest log files will be deleted first. Set it to 0 to allow
+# an unlimited number of archived logs. This does not disable time
+# based log rotation or per-log-file size limits.
+max_total_size = "4 GB"
+
+# Time interval for checking log rotation status. Avoid less than 1s.
+rotation_check_interval = "1 h"
+
+# Time to retain log files before deletion. Avoid less than 1s, too.
+retention = "7 days"
+
+# Interval for printing system information to the log.
+sysinfo_print_interval = "10 s"
+
+# Encryption configuration
+[system.encryption]
+# Determines whether server-side data encryption for the messages payloads and
state commands is enabled (boolean).
+# `true` enables encryption for stored data using AES-256-GCM.
+# `false` means data is stored without encryption.
+enabled = false
+
+# The encryption key used when encryption is enabled (string).
+# Should be a 32 bytes length key, provided as a base64 encoded string.
+# This key is required and used only if encryption is enabled.
+key = ""
+
+# Compression configuration
+[system.compression]
+# Allows overriding the default compression algorithm per data segment
(boolean).
+# `true` permits different compression algorithms for individual segments.
+# `false` means all data segments use the default compression algorithm.
+allow_override = false
+
+# The default compression algorithm used for data storage (string).
+# "none" indicates no compression, other values can specify different
algorithms.
+default_algorithm = "none"
+
+# Stream configuration
+[system.stream]
+# Path for storing stream-related data (string).
+# Specifies the directory where stream data is stored, relative to
`system.path`.
+path = "streams"
+
+# Topic configuration - default settings for new topics
+[system.topic]
+# Path for storing topic-related data, relative to `stream.path`.
+path = "topics"
+
+# Messages can be deleted based on two independent policies:
+# 1. Size-based: delete oldest segments when topic exceeds max_size
+# 2. Time-based: delete segments older than message_expiry
+# Both can be active simultaneously. Per-topic overrides via
CreateTopic/UpdateTopic.
+
+# Maximum topic size before oldest segments are deleted.
+# "unlimited" or "0" = no size limit (messages kept indefinitely).
+# When 90% of this limit is reached, oldest segments are removed to make room.
+# Applies to sealed segments only (active segment is protected).
+# Example: "10 GiB"
+max_size = "unlimited"
+
+# Maximum age of messages before segments are deleted.
+# "none" = no time limit (messages kept indefinitely).
+# Applies to sealed segments only (active segment is protected).
+# Example: "7 days", "2 days 4 hours 15 minutes"
+message_expiry = "none"
+
+# Partition configuration
+[system.partition]
+# Path for storing partition-related data (string).
+# Specifies the directory where partition data is stored, relative to
`topic.path`.
+path = "partitions"
+
+# Determines whether to enforce file synchronization on partition updates
(boolean).
+# `true` ensures immediate writing of data to disk for durability.
+# `false` allows the OS to manage write operations, which can improve
performance.
+enforce_fsync = false
+
+# Enables checksum validation for data integrity (boolean).
+# `true` activates CRC checks when loading data, guarding against corruption.
+# `false` skips these checks for faster loading at the risk of undetected
corruption.
+validate_checksum = false
+
+# The count threshold of buffered messages before triggering a save to disk.
+# Together with `size_of_messages_required_to_save` it defines the threshold.
+# This is a soft limit - actual count may be higher depending on last batch
size.
+# Minimum value is 1.
+messages_required_to_save = 1024
+
+# The size threshold of buffered messages before triggering a save to disk.
+# Together with `messages_required_to_save` it defines the threshold.
+# This is a soft limit - actual size may be higher depending on last batch
size.
+size_of_messages_required_to_save = "1 MiB"
+
+# Segment configuration
+[system.segment]
+# Defines the soft limit for the size of a storage segment.
+# When a segment reaches this size, a new segment is created for subsequent
data.
+# Example: if `size` is set "1GiB", the actual segment size may be 1GiB + the
size of remaining messages in received batch.
+# Maximum size is 1 GiB. Size has to be a multiple of 512 B.
+size = "1 GiB"
+
+# Configures whether expired segments are archived (boolean) or just deleted
without archiving.
+archive_expired = false
+
+# Controls whether to cache indexes (time and positional) for segment access.
+# Possible values:
+# - "true" or "all": keeps indexes in memory, speeding up data retrieval at
the cost of memory
+# - "open_segment": keeps indexes in memory only for the currently open segment
+# - "false" or "none": reads indexes from disk, which can conserve memory at
the cost of access speed
+cache_indexes = "open_segment"
+
+# Message deduplication configuration
+[system.message_deduplication]
+# Controls whether message deduplication is enabled (boolean).
+# `true` activates deduplication, ignoring messages with duplicate IDs.
+# `false` treats each message as unique, even if IDs are duplicated.
+enabled = false
+# Maximum number of ID entries in the deduplication cache (u64).
+max_entries = 10000
+# Maximum age of ID entries in the deduplication cache in human-readable
format.
+expiry = "1 m"
+
+# Recovery configuration in case of lost data
+[system.recovery]
+# Controls whether streams/topics/partitions should be recreated if the
expected data for existing state is missing (boolean).
+recreate_missing_state = false
+
+# Memory pool configuration
+[system.memory_pool]
+# Enables or disables the memory pool (boolean).
+# `true` enables the memory pool.
+# `false` disables the memory pool.
+enabled = true
+
+# Size of the memory pool (string).
+# Example: "512 MiB" or "1 GiB".
+# This defines the maximum, total memory allocated for the memory pool.
+# Note: This number has to be multiplication of 4096 (default linux page size).
+# Minimum size is 512 MiB due to internal implementation details.
+size = "4 GiB"
+
+# Maximum number of buffers in each bucket (u32).
+# There are 32 buckets in the memory pool. Each bucket can hold up to this
number of buffers
+# and holds different buffer sizes, from 256 B to 512 MiB.
+# Note: This number has to be a power of 2. Minimum value is 128 due to
internal implementation details.
+bucket_capacity = 8192
+
+# Cluster configuration
+[cluster]
+# Enables or disables cluster mode (boolean).
+# When enabled, this node will participate in the cluster and coordinate with
other nodes.
+enabled = false
+
+# Unique cluster name (string).
+# All nodes in the same cluster must share the same name.
+# This prevents accidental cross-cluster communication.
+name = "iggy-cluster"
+
+# Current node configuration
+[cluster.node.current]
+# Name of this node - must be unique across all nodes in the cluster
+# The node will use its configured transport addresses (tcp.address,
quic.address, etc.)
+name = "iggy-node-1"
+# IP address that other nodes should use to connect to this node
+ip = "127.0.0.1"
+
+# Other nodes in the cluster
+# Each field in 'ports' is optional. If omitted, the current node's configured
port will be used.
+# This is useful when all nodes use the same ports but different IPs, or when
only some ports differ.
+[[cluster.node.others]]
+name = "iggy-node-2"
+ip = "127.0.0.1"
+ports = { tcp = 8091, quic = 8081, http = 3001, websocket = 8093 }
+
+# [[cluster.node.others]]
+# name = "iggy-node-3"
+# ip = "192.168.1.100"
+# # Only some ports specified, others will use defaults from current node
+# ports = { tcp = 8092, http = 3002 }
+
+# Example with all default ports (uses current node's configured ports):
+# [[cluster.node.others]]
+# name = "iggy-node-4"
+# ip = "192.168.1.101"
+# ports = {} # Empty ports - all will use current node's defaults
+
+# Sharding configuration
+[system.sharding]
+# CPU allocation - controls the number of shards and their CPU affinity.
+# Possible values:
+# - "all": Use all available CPU cores (default)
+# - numeric value (e.g. 4): Use 4 shards (4 threads pinned to cores 0, 1, 2, 3)
+# - range (e.g. "5..8"): Use 3 shards with affinity to cores 5, 6, 7
+# - numa settings:
+# + "numa:auto": Use all available numa node, cores
+# + "numa:nodes=0,1;cores=4;no_ht=true": Use NUMA node 0 and 1, each nodes
use 4 cores, and no hyperthreads
+cpu_allocation = "numa:auto"
+
+[websocket]
+enabled = true
+address = "127.0.0.1:8092"
+
+[websocket.tls]
+enabled = false
+self_signed = true
+cert_file = "core/certs/iggy_cert.pem"
+key_file = "core/certs/iggy_key.pem"
diff --git a/core/server-ng/server-ng.http b/core/server-ng/server-ng.http
new file mode 100644
index 000000000..451bca8dd
--- /dev/null
+++ b/core/server-ng/server-ng.http
@@ -0,0 +1,376 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+@url = http://localhost:3000
+@stream_id = 0
+@topic_id = 0
+@partition_id = 0
+@consumer_group_id = 1
+@consumer_id = 1
+@client_id = 1
+@partition_id_payload_base64 = AAAAAA==
+@message_1_payload_base64 = aGVsbG8=
+@message_2_payload_base64 = d29ybGQ=
+@header_key_1_base64 = a2V5XzE=
+@header_value_1_base64 = dmFsdWUgMQ==
+@header_key_2_base64 = Kg==
+@header_value_2_base64 = AAAA
+@root_username = iggy
+@root_password = iggy
+@user1_username = user1
+@user1_password = secret
+@access_token = secret
+@root_id = 1
+@user1_id = 2
+@pat_name = dev_token
+@pat_raw_token = secret
+
+###
+GET {{url}}
+
+###
+GET {{url}}/ping
+
+###
+POST {{url}}/users/login
+Content-Type: application/json
+
+{
+ "username": "{{root_username}}",
+ "password": "{{root_password}}"
+}
+
+###
+POST {{url}}/personal-access-tokens/login
+Content-Type: application/json
+
+{
+ "token": "{{pat_raw_token}}"
+}
+
+###
+GET {{url}}/metrics
+
+###
+GET {{url}}/stats
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/cluster/metadata
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/clients
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/clients/{{client_id}}
+Authorization: Bearer {{access_token}}
+
+###
+POST {{url}}/users/refresh-token
+Content-Type: application/json
+
+{
+ "token": "{{access_token}}"
+}
+
+###
+DELETE {{url}}/users/logout
+Authorization: Bearer {{access_token}}
+
+###
+POST {{url}}/users
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "username": "{{user1_username}}",
+ "password": "{{user1_password}}",
+ "status": "active",
+ "permissions": null
+}
+
+###
+GET {{url}}/users
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/users/{{user1_id}}
+Authorization: Bearer {{access_token}}
+
+###
+PUT {{url}}/users/{{user1_id}}
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "username": "{{user1_username}}",
+ "status": "active",
+ "permissions": null
+}
+
+###
+PUT {{url}}/users/{{user1_id}}/password
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "current_password": "{{user1_password}}",
+ "new_password": "secret1"
+}
+
+###
+PUT {{url}}/users/{{user1_id}}/permissions
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "permissions": {
+ "global": {
+ "manage_servers": false,
+ "read_servers": true,
+ "manage_users": true,
+ "read_users": true,
+ "manage_streams": false,
+ "read_streams": true,
+ "manage_topics": false,
+ "read_topics": true,
+ "poll_messages": true,
+ "send_messages": true
+ },
+ "streams": {
+ "1": {
+ "manage_stream": false,
+ "read_stream": true,
+ "manage_topics": false,
+ "read_topics": true,
+ "poll_messages": true,
+ "send_messages": true,
+ "topics": {
+ "1": {
+ "manage_topic": false,
+ "read_topic": true,
+ "poll_messages": true,
+ "send_messages": true
+ }
+ }
+ }
+ }
+ }
+}
+
+
+###
+DELETE {{url}}/users/{{user1_id}}
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/personal-access-tokens
+Authorization: Bearer {{access_token}}
+
+###
+POST {{url}}/personal-access-tokens
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "name": "{{pat_name}}",
+ "expiry": 1000
+}
+
+###
+
+
+###
+DELETE {{url}}/personal-access-tokens/{{pat_name}}
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/streams
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/streams/{{stream_id}}
+Authorization: Bearer {{access_token}}
+
+###
+POST {{url}}/streams
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "name": "stream1"
+}
+
+###
+PUT {{url}}/streams/{{stream_id}}
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "name": "stream1"
+}
+
+###
+DELETE {{url}}/streams/{{stream_id}}
+Authorization: Bearer {{access_token}}
+
+###
+DELETE {{url}}/streams/{{stream_id}}/purge
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/streams/{{stream_id}}/topics
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/streams/{{stream_id}}/topics/{{topic_id}}
+Authorization: Bearer {{access_token}}
+
+###
+POST {{url}}/streams/{{stream_id}}/topics
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "name": "topic1",
+ "partitions_count": 1,
+ "compression_algorithm": "none",
+ "max_topic_size": 0,
+ "message_expiry": 0
+}
+
+###
+PUT {{url}}/streams/{{stream_id}}/topics/{{topic_id}}
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "name": "topic1",
+ "compression_algorithm": "none",
+ "max_topic_size": 0,
+ "message_expiry": 0
+}
+
+###
+DELETE {{url}}/streams/{{stream_id}}/topics/{{topic_id}}
+Authorization: Bearer {{access_token}}
+
+###
+DELETE {{url}}/streams/{{stream_id}}/topics/{{topic_id}}/purge
+Authorization: Bearer {{access_token}}
+
+###
+POST {{url}}/streams/{{stream_id}}/topics/{{topic_id}}/partitions
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "partitions_count": 3
+}
+
+###
+DELETE
{{url}}/streams/{{stream_id}}/topics/{{topic_id}}/partitions?partitions_count=1
+Authorization: Bearer {{access_token}}
+
+###
+### Delete segments
+DELETE {{url}}/streams/1/topics/1/partitions/1?segments_count=3
+Authorization: Bearer {{access_token}}
+
+###
+POST {{url}}/streams/{{stream_id}}/topics/{{topic_id}}/messages
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "partitioning": {
+ "kind": "partition_id",
+ "value": "{{partition_id_payload_base64}}"
+ },
+ "messages": [{
+ "id": 0,
+ "payload": "{{message_1_payload_base64}}"
+ }, {
+ "id": 0,
+ "payload": "{{message_2_payload_base64}}",
+ "user_headers": [{
+ "key": {
+ "kind": "string",
+ "value": "{{header_key_1_base64}}"
+ },
+ "value": {
+ "kind": "string",
+ "value": "{{header_value_1_base64}}"
+ }
+ }, {
+ "key": {
+ "kind": "uint32",
+ "value": "{{header_key_2_base64}}"
+ },
+ "value": {
+ "kind": "int32",
+ "value": "{{header_value_2_base64}}"
+ }
+ }]
+ }]
+}
+
+###
+GET
{{url}}/streams/{{stream_id}}/topics/{{topic_id}}/messages?consumer_id={{consumer_id}}&partition_id={{partition_id}}&kind=offset&value=0&count=10&auto_commit=false
+Authorization: Bearer {{access_token}}
+
+###
+PUT {{url}}/streams/{{stream_id}}/topics/{{topic_id}}/consumer-offsets
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "consumer_id": {{consumer_id}},
+ "partition_id": {{partition_id}},
+ "offset": 1
+}
+
+###
+GET
{{url}}/streams/{{stream_id}}/topics/{{topic_id}}/consumer-offsets?consumer_id={{consumer_id}}&partition_id={{partition_id}}
+Authorization: Bearer {{access_token}}
+
+###
+DELETE
{{url}}/streams/{{stream_id}}/topics/{{topic_id}}/consumer-offsets/{{consumer_id}}?partition_id={{partition_id}}
+Authorization: Bearer {{access_token}}
+
+###
+GET {{url}}/streams/{{stream_id}}/topics/{{topic_id}}/consumer-groups
+Authorization: Bearer {{access_token}}
+
+###
+GET
{{url}}/streams/{{stream_id}}/topics/{{topic_id}}/consumer-groups/{{consumer_group_id}}
+Authorization: Bearer {{access_token}}
+
+###
+POST {{url}}/streams/{{stream_id}}/topics/{{topic_id}}/consumer-groups
+Authorization: Bearer {{access_token}}
+Content-Type: application/json
+
+{
+ "name": "consumer_group_1"
+}
+
+###
+DELETE
{{url}}/streams/{{stream_id}}/topics/{{topic_id}}/consumer-groups/{{consumer_group_id}}
+Authorization: Bearer {{access_token}}
diff --git a/core/server-ng/src/lib.rs b/core/server-ng/src/lib.rs
new file mode 100644
index 000000000..042f3ce1f
--- /dev/null
+++ b/core/server-ng/src/lib.rs
@@ -0,0 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
diff --git a/core/server-ng/src/main.rs b/core/server-ng/src/main.rs
new file mode 100644
index 000000000..ffc8ee202
--- /dev/null
+++ b/core/server-ng/src/main.rs
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+fn main() {
+ tracing_subscriber::fmt::init();
+ tracing::info!("iggy-server-ng starting...");
+}
diff --git a/justfile b/justfile
index e03e8656f..2694389d3 100644
--- a/justfile
+++ b/justfile
@@ -51,6 +51,9 @@ nextests TEST: build
server *ARGS:
cargo run --bin iggy-server {{ARGS}}
+server-ng *ARGS:
+ cargo run --bin iggy-server-ng {{ARGS}}
+
run-benches:
./scripts/run-benches.sh