[{"data":1,"prerenderedAt":1982},["ShallowReactive",2],{"blog-post-\u002Fblog\u002Fkafka-rust-clients":3},{"id":4,"title":5,"body":6,"date":1967,"description":1968,"extension":1969,"meta":1970,"navigation":1971,"ogImage":1972,"ogImageHeight":1972,"ogImageWidth":1972,"path":1973,"pinned":1974,"seo":1975,"sitemap":1976,"stem":1977,"tags":1978,"__hash__":1981},"blog\u002Fblog\u002Fkafka-rust-clients.md","Kafka Rust Clients: rdkafka vs rskafka vs krafka",{"type":7,"value":8,"toc":1929},"minimark",[9,23,42,45,50,132,139,143,146,200,213,228,231,235,241,506,509,512,526,531,648,654,656,663,667,728,733,735,742,746,823,828,830,848,852,912,917,920,938,941,944,1007,1010,1013,1016,1019,1022,1041,1044,1102,1109,1112,1134,1137,1141,1144,1148,1210,1216,1220,1368,1372,1499,1506,1510,1656,1659,1663,1685,1688,1692,1699,1711,1715,1718,1722,1738,1748,1757,1761,1769,1772,1793,1801,1805,1812,1820,1828,1835,1839,1843,1846,1850,1856,1860,1869,1873,1882,1886,1899,1903,1909,1913,1916,1920,1923,1926],[10,11,12,13,17,18,22],"p",{},"Among the clients compared here, ",[14,15,16],"strong",{},"rdkafka"," leads crates.io downloads by a wide margin: about 7.7 million in the 90 days to 8 Oct 2026, more than ten times any pure Rust client. It wraps the ",[19,20,21],"code",{},"librdkafka"," C library, so a default build compiles librdkafka from C source.",[10,24,25,26,29,30,33,34,37,38,41],{},"The pure Rust clients skip that build step but differ in scope and maturity. ",[14,27,28],{},"rskafka"," reads and writes individual partitions and has no consumer groups. ",[14,31,32],{},"krafka"," supports consumer groups and transactions, but the project was created in February 2026. ",[14,35,36],{},"kafka-rust",", published as the ",[19,39,40],{},"kafka"," crate, last shipped in September 2023 and matters mainly to services that already use it.",[10,43,44],{},"This guide compares rdkafka, rskafka, and krafka for new projects and covers migration from kafka-rust. It looks at build requirements, consumer groups, transactions, authentication, default partitioners, and Schema Registry integration, with capabilities checked against specific releases.",[46,47,49],"h2",{"id":48},"quick-decision","Quick decision",[51,52,53,69],"table",{},[54,55,56],"thead",{},[57,58,59,63,66],"tr",{},[60,61,62],"th",{},"Situation",[60,64,65],{},"Best starting point",[60,67,68],{},"Why",[70,71,72,89,101,113],"tbody",{},[57,73,74,80,82],{},[75,76,77],"td",{},[14,78,79],{},"Production service that needs consumer groups or transactions",[75,81,16],{},[75,83,84,85,88],{},"Mature consumer groups and transactions through librdkafka. A default build compiles librdkafka from C source, and TLS needs the ",[19,86,87],{},"ssl"," feature. The default partitioner hashes keys with CRC32, not Java's Murmur2.",[57,90,91,96,98],{},[75,92,93],{},[14,94,95],{},"Consumer groups or transactions without librdkafka",[75,97,32],{},[75,99,100],{},"Consumer groups and transactions in a pure Rust implementation. Pre-1.0, so minor releases can break the API. Requires Kafka 3.9+ and Rust 1.95+.",[57,102,103,108,110],{},[75,104,105],{},[14,106,107],{},"You track offsets yourself and read or write known partitions",[75,109,28],{},[75,111,112],{},"A small partition-level API. No consumer groups, offset commits, or transactions; your code picks the partition for every record.",[57,114,115,120,123],{},[75,116,117],{},[14,118,119],{},"Existing kafka-rust service",[75,121,122],{},"Plan a move to rdkafka or krafka",[75,124,125,126,131],{},"kafka-rust 0.10.0 cannot produce to or fetch from Kafka 4.0+ brokers, and its key hashing matches neither destination. See ",[127,128,130],"a",{"href":129},"#moving-from-kafka-rust","Moving from kafka-rust",".",[10,133,134,135,131],{},"If you use Avro, Protobuf, or JSON Schema with a schema registry, pair your chosen client with a registry crate; none of these clients bundles Schema Registry serializers. See ",[127,136,138],{"href":137},"#schema-registry-in-rust","Schema Registry in Rust",[46,140,142],{"id":141},"librdkafka-wrapper-or-pure-rust","librdkafka wrapper or pure Rust?",[10,144,145],{},"rdkafka gives a Rust service the same producer, consumer group, and transaction code that Confluent's Go, Python, and .NET clients use. The trade-off is native build and deployment requirements. By default, rdkafka compiles librdkafka from C source and links it statically:",[147,148,149,170,194],"ul",{},[150,151,152,155,156,159,160,163,164,167,168,131],"li",{},[14,153,154],{},"Toolchain:"," The default build needs a C compiler, GNU ",[19,157,158],{},"make",", and ",[19,161,162],{},"pthreads",". The README encourages the ",[19,165,166],{},"cmake-build"," feature, which needs CMake. On Windows, the build requires ",[19,169,166],{},[150,171,172,175,176,178,179,182,183,186,187,190,191,131],{},[14,173,174],{},"Native libraries:"," TLS and SASL\u002FSCRAM need the ",[19,177,87],{}," feature (OpenSSL), and Kerberos needs ",[19,180,181],{},"gssapi"," (Cyrus SASL). These and zlib link against system libraries unless you enable ",[19,184,185],{},"ssl-vendored",", ",[19,188,189],{},"gssapi-vendored",", or ",[19,192,193],{},"libz-static",[150,195,196,199],{},[14,197,198],{},"Cross-compiling:"," Building for another target or for musl needs a C toolchain for that target. Test the binary inside the production container image.",[201,202,203],"blockquote",{},[10,204,205,208,209,212],{},[14,206,207],{},"Tip:"," To skip compiling librdkafka, enable the ",[19,210,211],{},"dynamic-linking"," feature to link an installed copy instead. The installed version must be at least as new as the bundled one, and the shared library must also be available at runtime.",[10,214,215,216,219,220,223,224,227],{},"rskafka and krafka avoid librdkafka and OpenSSL and use rustls for TLS. Their default feature sets still require a C toolchain: krafka enables ring, while rskafka enables lz4 and zstd codecs backed by C libraries. rskafka also uses ring when ",[19,217,218],{},"transport-tls"," is enabled, and krafka's optional ",[19,221,222],{},"zstd"," feature adds another C dependency. Cross-compiling requires the corresponding target toolchain. kafka-rust's default ",[19,225,226],{},"security"," feature links OpenSSL.",[10,229,230],{},"Choose based on protocol coverage and release maturity, then check whether the native dependencies fit your build and deployment environment. Among the pure Rust clients compared here, only krafka covers consumer groups and transactions, and it is the youngest of the four.",[46,232,234],{"id":233},"kafka-rust-clients-compared","Kafka Rust clients compared",[10,236,237,240],{},[14,238,239],{},"Capabilities verified against each release's source and documentation:"," 8 Oct 2026",[51,242,243,279],{},[54,244,245],{},[57,246,247,250,258,265,272],{},[60,248,249],{},"Area",[60,251,252],{},[127,253,257],{"href":254,"rel":255},"https:\u002F\u002Fdocs.rs\u002Frdkafka\u002F0.39.0",[256],"nofollow","rdkafka 0.39.0",[60,259,260],{},[127,261,264],{"href":262,"rel":263},"https:\u002F\u002Fdocs.rs\u002Frskafka\u002F0.6.0",[256],"rskafka 0.6.0",[60,266,267],{},[127,268,271],{"href":269,"rel":270},"https:\u002F\u002Fdocs.rs\u002Fkrafka\u002F0.26.0",[256],"krafka 0.26.0",[60,273,274],{},[127,275,278],{"href":276,"rel":277},"https:\u002F\u002Fdocs.rs\u002Fkafka\u002F0.10.0",[256],"kafka-rust 0.10.0",[70,280,281,298,346,367,388,410,427,446,468,487],{},[57,282,283,288,291,294,296],{},[75,284,285],{},[14,286,287],{},"Implementation",[75,289,290],{},"Bundles librdkafka 2.12.1",[75,292,293],{},"Pure Rust",[75,295,293],{},[75,297,293],{},[57,299,300,305,322,328,339],{},[75,301,302],{},[14,303,304],{},"API style",[75,306,307,308,311,312,315,316,311,319],{},"Async ",[19,309,310],{},"StreamConsumer"," and ",[19,313,314],{},"FutureProducer","; poll-based ",[19,317,318],{},"BaseConsumer",[19,320,321],{},"BaseProducer",[75,323,324,325],{},"Async, per-partition ",[19,326,327],{},"PartitionClient",[75,329,307,330,186,333,186,336],{},[19,331,332],{},"Producer",[19,334,335],{},"Consumer",[19,337,338],{},"AdminClient",[75,340,341,342,311,344],{},"Blocking ",[19,343,332],{},[19,345,335],{},[57,347,348,353,359,362,364],{},[75,349,350],{},[14,351,352],{},"Async runtime",[75,354,355,356],{},"Tokio by default; others through ",[19,357,358],{},"AsyncRuntime",[75,360,361],{},"Tokio",[75,363,361],{},[75,365,366],{},"None",[57,368,369,374,380,382,385],{},[75,370,371],{},[14,372,373],{},"Consumer groups",[75,375,376,377],{},"Classic, including cooperative-sticky; KIP-848 with ",[19,378,379],{},"group.protocol=consumer",[75,381,366],{},[75,383,384],{},"Classic and KIP-848",[75,386,387],{},"Offset storage only; no group membership or rebalancing",[57,389,390,395,398,401,403],{},[75,391,392],{},[14,393,394],{},"Default offset commits",[75,396,397],{},"Automatic every 5 s",[75,399,400],{},"Not supported",[75,402,397],{},[75,404,405,406,409],{},"Manual (",[19,407,408],{},"commit_consumed",")",[57,411,412,417,420,423,425],{},[75,413,414],{},[14,415,416],{},"Transactions",[75,418,419],{},"Yes",[75,421,422],{},"No",[75,424,419],{},[75,426,422],{},[57,428,429,434,437,440,443],{},[75,430,431],{},[14,432,433],{},"Security",[75,435,436],{},"TLS\u002FmTLS; SASL PLAIN, SCRAM, OAUTHBEARER, GSSAPI",[75,438,439],{},"TLS\u002FmTLS; SASL PLAIN, SCRAM, OAUTHBEARER",[75,441,442],{},"TLS\u002FmTLS; SASL PLAIN, SCRAM, OAUTHBEARER; AWS MSK IAM",[75,444,445],{},"TLS\u002FmTLS; no SASL",[57,447,448,453,459,462,465],{},[75,449,450],{},[14,451,452],{},"Default partitioner for keys",[75,454,455,456,409],{},"CRC32 (",[19,457,458],{},"consistent_random",[75,460,461],{},"None; the caller picks the partition",[75,463,464],{},"Murmur2, Java-compatible",[75,466,467],{},"XxHash32",[57,469,470,475,478,481,484],{},[75,471,472],{},[14,473,474],{},"Brokers",[75,476,477],{},"Kafka 0.8+ through librdkafka",[75,479,480],{},"Not documented",[75,482,483],{},"Kafka 3.9+",[75,485,486],{},"Tested with selected versions from 0.8.2 to 3.1.0; cannot produce or fetch on Kafka 4.0+",[57,488,489,494,497,500,503],{},[75,490,491],{},[14,492,493],{},"Minimum Rust",[75,495,496],{},"1.74",[75,498,499],{},"1.85",[75,501,502],{},"1.95",[75,504,505],{},"Not declared",[10,507,508],{},"KIP-848 moves partition assignment to the broker and is production-ready in Kafka 4.0 and later. It is a separate feature from cooperative-sticky rebalancing under the classic protocol. rdkafka and krafka support both protocols and still default to the classic one. rskafka and kafka-rust do not join consumer groups.",[510,511,16],"h3",{"id":16},[10,513,514,518,519,522,523,131],{},[127,515,16],{"href":516,"rel":517},"https:\u002F\u002Fgithub.com\u002Ffede1024\u002Frust-rdkafka",[256]," is a safe Rust interface to librdkafka. Release 0.39.0 (25 Jan 2026) bundles librdkafka 2.12.1, so the behavior of the protocol comes from that C library. Configuration uses librdkafka property names, such as ",[19,520,521],{},"bootstrap.servers",", through ",[19,524,525],{},"ClientConfig",[10,527,528],{},[14,529,530],{},"Capabilities and limitations",[147,532,533,553,565,579,592,608,634],{},[150,534,535,538,539,311,541,543,544,311,546,548,549,552],{},[14,536,537],{},"API:"," ",[19,540,310],{},[19,542,314],{}," fit into async code. ",[19,545,318],{},[19,547,321],{}," must be polled from your own loop, and ",[19,550,551],{},"ThreadedProducer"," polls on a background thread.",[150,554,555,558,559,562,563,131],{},[14,556,557],{},"Protocol coverage:"," librdkafka provides idempotent and transactional producers, ",[19,560,561],{},"read_committed"," consumers, and an ",[19,564,338],{},[150,566,567,570,571,574,575,578],{},[14,568,569],{},"Consumer commits:"," librdkafka commits every 5 seconds by default, and it can commit a record that your code has not finished. For at-least-once processing, set ",[19,572,573],{},"enable.auto.offset.store=false"," and call ",[19,576,577],{},"store_offset_from_message"," after each record is processed.",[150,580,581,584,585,588,589,591],{},[14,582,583],{},"Consumer groups:"," Set ",[19,586,587],{},"partition.assignment.strategy=cooperative-sticky"," for incremental rebalances. librdkafka made KIP-848 generally available in 2.12.0; enable it with ",[19,590,379],{}," on Kafka 4.0+.",[150,593,594,538,597,599,600,603,604,607],{},[14,595,596],{},"Default partitioner:",[19,598,458],{}," hashes keys with CRC32. Set ",[19,601,602],{},"partitioner=murmur2_random"," for Java-compatible key-to-partition mapping, or implement the ",[19,605,606],{},"Partitioner"," trait for custom placement.",[150,609,610,613,614,617,618,621,622,625,626,633],{},[14,611,612],{},"AWS MSK IAM:"," Implement ",[19,615,616],{},"ClientContext"," with ",[19,619,620],{},"ENABLE_REFRESH_OAUTH_TOKEN = true"," and override ",[19,623,624],{},"generate_oauth_token"," to supply MSK IAM tokens through SASL\u002FOAUTHBEARER. The community ",[127,627,630],{"href":628,"rel":629},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Faws-msk-iam-sasl-signer",[256],[19,631,632],{},"aws-msk-iam-sasl-signer"," crate, a port of AWS's Go signer, includes rdkafka examples.",[150,635,636,639,640,644,645,647],{},[14,637,638],{},"Maintenance:"," The ",[127,641,643],{"href":642},"#github-repository-metrics","repository snapshot"," shows no default-branch commits or merged PRs in 90 days and 50 open PRs. With the default static build, librdkafka fixes require an updated rdkafka-sys bundle and a rebuild. With ",[19,646,211],{},", the installed shared library can be updated separately.",[10,649,650,653],{},[14,651,652],{},"When to choose:"," Choose rdkafka for production services that need consumer groups, transactions, or GSSAPI, and whose build and deployment environment can support librdkafka's native dependencies. It has by far the most crates.io downloads of the four.",[510,655,28],{"id":28},[10,657,658,662],{},[127,659,28],{"href":660,"rel":661},"https:\u002F\u002Fgithub.com\u002Finfluxdata\u002Frskafka",[256]," is a minimal client that InfluxData wrote for using Kafka as a write-ahead log. Its README states that InfluxDB 3.0 originally used it but no longer does. The latest release is 0.6.0 (20 Mar 2025).",[10,664,665],{},[14,666,530],{},[147,668,669,678,684,701,709,722],{},[150,670,671,674,675,677],{},[14,672,673],{},"Model:"," You get a ",[19,676,327],{}," for one topic partition, then produce to it or fetch from it at an offset. There is no partitioner, so your code decides where each record goes.",[150,679,680,683],{},[14,681,682],{},"Missing by design:"," No consumer groups, offset commits, or transactions.",[150,685,686,538,689,692,693,696,697,700],{},[14,687,688],{},"Producer:",[19,690,691],{},"PartitionClient::produce"," sends the supplied records as one batch. ",[19,694,695],{},"BatchProducer"," combines multiple produce calls using an ",[19,698,699],{},"Aggregator"," and a configurable linger timeout. There is no idempotent producer support, so retries can produce duplicates.",[150,702,703,538,706,708],{},[14,704,705],{},"Consumer:",[19,707,310],{}," reads one partition from a start offset and advances its read position in memory. To resume after a restart, persist the next offset after processing, for example in your own database.",[150,710,711,714,715,717,718,721],{},[14,712,713],{},"Security:"," TLS through rustls needs the ",[19,716,218],{}," feature, which is off by default. SASL PLAIN, SCRAM-SHA-256\u002F512, and OAUTHBEARER are supported, and ",[19,719,720],{},"transport-socks5"," adds a SOCKS5 proxy.",[150,723,724,727],{},[14,725,726],{},"Admin:"," The controller client can create and delete topics.",[10,729,730,732],{},[14,731,652],{}," Choose rskafka for workloads that manage offsets outside Kafka and read or write a small number of high-throughput partitions. Do not choose it for a service that needs consumer groups.",[510,734,32],{"id":32},[10,736,737,741],{},[127,738,32],{"href":739,"rel":740},"https:\u002F\u002Fgithub.com\u002Fhupe1980\u002Fkrafka",[256]," is a pure Rust, Tokio-based client. Its repository was created on 6 Feb 2026, and it has published 32 crates.io releases since then, the latest being 0.26.0 (6 Oct 2026). The coverage below comes from the project's own documentation and source; test it against your brokers.",[10,743,744],{},[14,745,530],{},[147,747,748,757,773,785,797,806,816],{},[150,749,750,753,754,756],{},[14,751,752],{},"Coverage:"," Idempotent and transactional producers, classic and KIP-848 consumers, a KIP-932 share consumer (Kafka 4.2+), and an ",[19,755,338],{},". It requires Kafka 3.9 or later.",[150,758,759,761,762,765,766,769,770,772],{},[14,760,569],{}," Auto-commit is enabled with a default interval of 5 seconds and commits positions advanced by ",[19,763,764],{},"poll()",", which may include records still being processed. For at-least-once processing, disable auto-commit and call ",[19,767,768],{},"commit()"," after processing the entire batch returned by ",[19,771,764],{},", before polling again.",[150,774,775,777,778,781,782,131],{},[14,776,583],{}," Choose KIP-848 with ",[19,779,780],{},".group_protocol(GroupProtocol::Consumer)"," on Kafka 4.0+. The default is still ",[19,783,784],{},"Classic",[150,786,787,789,790,793,794,131],{},[14,788,596],{}," The default ",[19,791,792],{},"UniformStickyPartitioner"," hashes keys with Murmur2 for Java-compatible key-to-partition mapping. Records without keys use sticky partitioning to build batches on one partition. Set a custom partitioner with ",[19,795,796],{},".partitioner(...)",[150,798,799,801,802,805],{},[14,800,713],{}," TLS and mTLS through rustls; SASL PLAIN, SCRAM, and OAUTHBEARER; and AWS MSK IAM, with the ",[19,803,804],{},"aws-msk"," feature adding the AWS SDK credential chain. GSSAPI is out of scope.",[150,807,808,811,812,815],{},[14,809,810],{},"Stability:"," krafka is pre-1.0, and minor releases can carry breaking changes. Pin the version and read the ",[19,813,814],{},"Breaking"," section of each changelog entry before upgrading. The minimum Rust version is 1.95.",[150,817,818,639,820,822],{},[14,819,638],{},[127,821,643],{"href":642}," shows the most commits and merged PRs of the four. Two commit authors were active in the past year, and one account merged every PR.",[10,824,825,827],{},[14,826,652],{}," Choose krafka when you want to avoid librdkafka and the service still needs consumer groups, transactions, or MSK IAM. Allow time for API changes when upgrading.",[510,829,36],{"id":36},[10,831,832,836,837,839,840,843,844,847],{},[127,833,36],{"href":834,"rel":835},"https:\u002F\u002Fgithub.com\u002Fkafka-rust\u002Fkafka-rust",[256],", created in 2015, is the oldest client in this guide. It is published on crates.io as ",[19,838,40],{},", so ",[19,841,842],{},"Cargo.toml"," lists it as ",[19,845,846],{},"kafka = \"0.10\"",". Its README says: \"Use it in production at your own risk.\"",[10,849,850],{},[14,851,530],{},[147,853,854,863,875,880,892,901,906],{},[150,855,856,538,858,311,860,862],{},[14,857,537],{},[19,859,332],{},[19,861,335],{}," are blocking. There is no async API.",[150,864,865,868,869,874],{},[14,866,867],{},"Protocol versions:"," 0.10.0 sends version 0 of Produce, Fetch, and ListOffsets, and it only parses the oldest message format, which has no headers. Kafka 4.0 removed those request versions (",[127,870,873],{"href":871,"rel":872},"https:\u002F\u002Fcwiki.apache.org\u002Fconfluence\u002Fdisplay\u002FKAFKA\u002FKIP-896%3A+Remove+old+client+protocol+API+versions+in+Kafka+4.0",[256],"KIP-896","), so 0.10.0 cannot produce to or fetch from Kafka 4.0+ brokers.",[150,876,877,879],{},[14,878,583],{}," The group name is used only to store offsets. Consumers do not join a group or rebalance, so each instance reads the partitions it was configured with.",[150,881,882,884,885,888,889,891],{},[14,883,569],{}," Offsets are not committed automatically. After processing every record in a message set, call ",[19,886,887],{},"consume_messageset"," to mark it consumed, then call ",[19,890,408],{}," to persist the offsets.",[150,893,894,896,897,900],{},[14,895,596],{}," Keys are hashed with XxHash32 and placed by ",[19,898,899],{},"hash % partition_count",". Records without keys go round-robin over partitions that have a leader.",[150,902,903,905],{},[14,904,713],{}," TLS through OpenSSL. 0.10.0 has no SASL support, and compression covers gzip and Snappy only.",[150,907,908,911],{},[14,909,910],{},"Release status:"," The master branch carries 0.11.0, with a changelog entry dated 2 Jul 2026 that adds rustls and SASL\u002FPLAIN. As of 8 Oct 2026 it has no tag or crates.io release. Produce, Fetch, and ListOffsets still use version 0, so these changes do not resolve Kafka 4.0 compatibility.",[10,913,914,916],{},[14,915,652],{}," Do not start new work on kafka-rust. If a service already uses it, plan the move before its brokers reach Kafka 4.0.",[10,918,919],{},"Two other crates come up in searches:",[147,921,922,930],{},[150,923,924,929],{},[127,925,928],{"href":926,"rel":927},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Fkafka-protocol",[256],"kafka-protocol"," (0.18.0) generates types for the Kafka wire protocol but is not a client. It suits proxies and tools that speak the protocol directly.",[150,931,932,937],{},[127,933,936],{"href":934,"rel":935},"https:\u002F\u002Fgithub.com\u002FCallistoLabsNYC\u002Fsamsa",[256],"samsa"," is another pure Rust client with consumer groups, TLS, and SASL. Its last release, 0.1.8, shipped in September 2025, and it had 3,488 downloads in the 90 days to 8 Oct 2026.",[46,939,138],{"id":940},"schema-registry-in-rust",[10,942,943],{},"None of the four clients ships Schema Registry serializers. They hand your code bytes, and a separate crate encodes and decodes them:",[51,945,946,959],{},[54,947,948],{},[57,949,950,953,956],{},[60,951,952],{},"Crate",[60,954,955],{},"Formats",[60,957,958],{},"Notes",[70,960,961,977,992],{},[57,962,963,971,974],{},[75,964,965,970],{},[127,966,969],{"href":967,"rel":968},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Fschema_registry_converter",[256],"schema_registry_converter"," 5.0.0",[75,972,973],{},"Avro, Protobuf, JSON Schema",[75,975,976],{},"The most downloaded option. Async and blocking APIs; compatible with Confluent's Java client and with Karapace.",[57,978,979,987,989],{},[75,980,981,986],{},[127,982,985],{"href":983,"rel":984},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Fschema-registry-client",[256],"schema-registry-client"," 0.4.2",[75,988,973],{},[75,990,991],{},"Async APIs; data quality rules, schema migration rules, and client-side field-level encryption through optional features.",[57,993,994,1002,1004],{},[75,995,996,1001],{},[127,997,1000],{"href":998,"rel":999},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Fschemreg",[256],"schemreg"," 0.6.0",[75,1003,973],{},[75,1005,1006],{},"Async APIs; supports Confluent, Apicurio Registry v3, and AWS Glue. Registry backends and codecs require opt-in features.",[10,1008,1009],{},"These crates are independent of the Kafka client: encode before producing and decode after consuming. Header-based schema identifiers require record-header support, which kafka-rust 0.10.0 lacks.",[10,1011,1012],{},"Check each crate's Cargo features for optional codecs, registry backends, and rule executors.",[10,1014,1015],{},"Whichever you pick, check the framing against records written by your other services. Confluent's schema-ID payload format starts with a zero magic byte and a 4-byte schema ID, for both keys and values. Protobuf adds message indexes identifying the message type before the encoded payload.",[46,1017,130],{"id":1018},"moving-from-kafka-rust",[10,1020,1021],{},"kafka-rust 0.10.0 cannot produce to or fetch from Kafka 4.0+ brokers, so moving is a question of timing. Pick the destination first:",[147,1023,1024,1035],{},[150,1025,1026,1029,1030,311,1032,1034],{},[14,1027,1028],{},"rdkafka:"," The most mature option, if your build and deployment environment can support librdkafka's native dependencies. ",[19,1031,318],{},[19,1033,321],{}," let you keep a blocking, thread-per-consumer design.",[150,1036,1037,1040],{},[14,1038,1039],{},"krafka:"," Avoids librdkafka, but you adopt a young, pre-1.0 API and Tokio.",[10,1042,1043],{},"Then check each behavior that changes:",[147,1045,1046,1052,1061,1074,1084,1096],{},[150,1047,1048,1051],{},[14,1049,1050],{},"Group membership:"," kafka-rust consumers with the same group name do not coordinate. If you switch to group subscription, instances with the same group ID share partitions. Decide whether you want group subscription or explicit partition assignment.",[150,1053,1054,1057,1058,1060],{},[14,1055,1056],{},"Commits:"," kafka-rust commits only when you call ",[19,1059,408],{},". rdkafka and krafka commit automatically by default, so set up commits after processing if the old code depended on that.",[150,1062,1063,584,1066,1069,1070,1073],{},[14,1064,1065],{},"Starting offset:",[19,1067,1068],{},"auto.offset.reset"," in rdkafka or ",[19,1071,1072],{},"auto_offset_reset"," in krafka explicitly. Both default to the latest offset when a group has no committed offset.",[150,1075,1076,1079,1080,1083],{},[14,1077,1078],{},"Existing offsets:"," If the old consumer stored offsets in Kafka (",[19,1081,1082],{},"GroupOffsetStorage::Kafka","), a new consumer with the same group ID should resume from them. Before reusing the group ID, let the old consumers finish the records they have fetched, commit offsets, and stop; then start the new consumers. Confirm this on a test topic before the cutover.",[150,1085,1086,1089,1090,1092,1093,1095],{},[14,1087,1088],{},"Null and empty data:"," kafka-rust's ",[19,1091,332],{}," converts empty keys and values to ",[19,1094,366],{},". Preserve that behavior explicitly when migrating: an empty key was keyless, and an empty value was a tombstone on compacted topics.",[150,1097,1098,1101],{},[14,1099,1100],{},"Headers:"," The new producer can send record headers. Consumers that still run kafka-rust 0.10.0 cannot read them.",[10,1103,1104,1105,1108],{},"Finally, check key placement. kafka-rust places a record with a non-empty key at ",[19,1106,1107],{},"XxHash32(key) % partition_count",", using a zero seed. rdkafka defaults to CRC32 and krafka to Murmur2, so the same key usually lands on a different partition after the switch. That can break per-key ordering across the cutover.",[10,1110,1111],{},"You have two options:",[147,1113,1114,1125],{},[150,1115,1116,1119,1120,1122,1123,131],{},[14,1117,1118],{},"Keep the old placement:"," Implement a custom partitioner that computes the same 32-bit XxHash with seed 0, then takes the remainder by the partition count. Use rdkafka's ",[19,1121,606],{}," trait or krafka's ",[19,1124,796],{},[150,1126,1127,1130,1131,1133],{},[14,1128,1129],{},"Switch to Java placement:"," Accept a one-time move of keys to Murmur2. Use krafka's default or rdkafka's ",[19,1132,602],{},". Stop the old producers and drain their records before starting producers with the new partitioner.",[10,1135,1136],{},"Either way, produce representative records with the old and new producers to a test topic with the same partition count. Compare partition placement for non-empty keys, and verify that empty and null keys and values preserve the old behavior.",[46,1138,1140],{"id":1139},"github-repository-metrics","GitHub repository metrics",[10,1142,1143],{},"The tables below compare the four clients' GitHub activity, maintenance, and public usage, with crates.io downloads as the usage signal. Snapshot: 8 Oct 2026.",[510,1145,1147],{"id":1146},"project-overview","Project overview",[51,1149,1150,1176],{},[54,1151,1152],{},[57,1153,1154,1156,1161,1166,1171],{},[60,1155],{},[60,1157,1158],{},[127,1159,16],{"href":516,"rel":1160},[256],[60,1162,1163],{},[127,1164,28],{"href":660,"rel":1165},[256],[60,1167,1168],{},[127,1169,32],{"href":739,"rel":1170},[256],[60,1172,1173],{},[127,1174,36],{"href":834,"rel":1175},[256],[70,1177,1178,1195],{},[57,1179,1180,1183,1186,1189,1192],{},[75,1181,1182],{},"Repository created",[75,1184,1185],{},"29 Oct 2016",[75,1187,1188],{},"4 Jan 2022",[75,1190,1191],{},"6 Feb 2026",[75,1193,1194],{},"7 May 2015",[57,1196,1197,1200,1203,1206,1208],{},[75,1198,1199],{},"License",[75,1201,1202],{},"MIT",[75,1204,1205],{},"MIT OR Apache-2.0",[75,1207,1205],{},[75,1209,1205],{},[10,1211,1212,1213,1215],{},"Licenses are taken from each crate's ",[19,1214,842],{},". GitHub shows only one of the two license files for the dual-licensed crates.",[510,1217,1219],{"id":1218},"activity","Activity",[51,1221,1222,1249],{},[54,1223,1224],{},[57,1225,1226,1229,1234,1239,1244],{},[60,1227,1228],{},"Metric",[60,1230,1231],{},[127,1232,16],{"href":516,"rel":1233},[256],[60,1235,1236],{},[127,1237,28],{"href":660,"rel":1238},[256],[60,1240,1241],{},[127,1242,32],{"href":739,"rel":1243},[256],[60,1245,1246],{},[127,1247,36],{"href":834,"rel":1248},[256],[70,1250,1251,1268,1285,1301,1318,1335,1352],{},[57,1252,1253,1256,1259,1262,1265],{},[75,1254,1255],{},"Latest default-branch commit",[75,1257,1258],{},"14 Jun 2026",[75,1260,1261],{},"5 Oct 2026",[75,1263,1264],{},"6 Oct 2026",[75,1266,1267],{},"2 Jul 2026",[57,1269,1270,1273,1276,1279,1282],{},[75,1271,1272],{},"Latest crates.io release",[75,1274,1275],{},"0.39.0 (25 Jan 2026)",[75,1277,1278],{},"0.6.0 (20 Mar 2025)",[75,1280,1281],{},"0.26.0 (6 Oct 2026)",[75,1283,1284],{},"0.10.0 (24 Sep 2023)",[57,1286,1287,1290,1293,1296,1299],{},[75,1288,1289],{},"crates.io releases (12 mo)",[75,1291,1292],{},"1",[75,1294,1295],{},"0",[75,1297,1298],{},"32",[75,1300,1295],{},[57,1302,1303,1306,1309,1312,1315],{},[75,1304,1305],{},"Commits",[75,1307,1308],{},"0 (90 d) · 11 (12 mo)",[75,1310,1311],{},"4 (90 d) · 35 (12 mo)",[75,1313,1314],{},"54 (90 d) · 444 (12 mo)",[75,1316,1317],{},"0 (90 d) · 6 (12 mo)",[57,1319,1320,1323,1326,1329,1332],{},[75,1321,1322],{},"Issue flow (90 d)",[75,1324,1325],{},"6 opened · 0 closed",[75,1327,1328],{},"1 opened · 1 closed",[75,1330,1331],{},"7 opened · 7 closed",[75,1333,1334],{},"2 opened · 1 closed",[57,1336,1337,1340,1343,1346,1349],{},[75,1338,1339],{},"PR flow (90 d)",[75,1341,1342],{},"12 opened · 0 merged",[75,1344,1345],{},"4 opened · 4 merged",[75,1347,1348],{},"15 opened · 15 merged",[75,1350,1351],{},"0 opened · 0 merged",[57,1353,1354,1357,1360,1363,1366],{},[75,1355,1356],{},"Activity assessment",[75,1358,1359],{},"🔴 No commits and no merged PRs in the last 90 days.",[75,1361,1362],{},"🟡 4 commits and 4 merged PRs in the last 90 days.",[75,1364,1365],{},"🟢 54 commits and 15 merged PRs in the last 90 days.",[75,1367,1359],{},[510,1369,1371],{"id":1370},"maintenance","Maintenance",[51,1373,1374,1400],{},[54,1375,1376],{},[57,1377,1378,1380,1385,1390,1395],{},[60,1379,1228],{},[60,1381,1382],{},[127,1383,16],{"href":516,"rel":1384},[256],[60,1386,1387],{},[127,1388,28],{"href":660,"rel":1389},[256],[60,1391,1392],{},[127,1393,32],{"href":739,"rel":1394},[256],[60,1396,1397],{},[127,1398,36],{"href":834,"rel":1399},[256],[70,1401,1402,1418,1432,1449,1466,1482],{},[57,1403,1404,1407,1410,1413,1416],{},[75,1405,1406],{},"Active commit authors (12 mo)",[75,1408,1409],{},"9",[75,1411,1412],{},"4",[75,1414,1415],{},"2",[75,1417,1415],{},[57,1419,1420,1423,1426,1428,1430],{},[75,1421,1422],{},"PR merge distribution (12 mo)",[75,1424,1425],{},"1 account · 100% of non-bot merges",[75,1427,1425],{},[75,1429,1425],{},[75,1431,1425],{},[57,1433,1434,1437,1440,1443,1446],{},[75,1435,1436],{},"Issue backlog",[75,1438,1439],{},"118 open · median age 2.9 y",[75,1441,1442],{},"13 open · median age 4.4 y",[75,1444,1445],{},"1 open · median age 149 d",[75,1447,1448],{},"48 open · median age 5 y",[57,1450,1451,1454,1457,1460,1463],{},[75,1452,1453],{},"PR backlog",[75,1455,1456],{},"50 open · median age 1 y",[75,1458,1459],{},"4 open · median age 4.1 y",[75,1461,1462],{},"0 open PRs",[75,1464,1465],{},"6 open · median age 2.5 y",[57,1467,1468,1471,1474,1477,1480],{},[75,1469,1470],{},"Median PR merge time (90 d)",[75,1472,1473],{},"N\u002FA — no merged PRs in window",[75,1475,1476],{},"5.5 h (n=4 — small sample)",[75,1478,1479],{},"\u003C1 h (n=15)",[75,1481,1473],{},[57,1483,1484,1487,1490,1493,1496],{},[75,1485,1486],{},"Responsiveness assessment",[75,1488,1489],{},"🔴 No PRs merged in 90 d, while 50 open PRs have a median age of 1 y.",[75,1491,1492],{},"🟡 4 PRs merged in 90 d (median 5.5 h), but 4 open PRs have a median age of 4.1 y.",[75,1494,1495],{},"🟢 For the 15 PRs merged in the last 90 d, the median creation-to-merge time was \u003C1 h.",[75,1497,1498],{},"🔴 No PRs merged in 90 d, while 6 open PRs have a median age of 2.5 y.",[10,1500,1501,1502,1505],{},"PR merge distribution counts non-bot ",[19,1503,1504],{},"mergedBy"," accounts. It does not measure reviewer or maintainer headcount. None of the four crates has a RustSec advisory.",[510,1507,1509],{"id":1508},"public-usage-and-interest","Public usage and interest",[51,1511,1512,1538],{},[54,1513,1514],{},[57,1515,1516,1518,1523,1528,1533],{},[60,1517,1228],{},[60,1519,1520],{},[127,1521,16],{"href":516,"rel":1522},[256],[60,1524,1525],{},[127,1526,28],{"href":660,"rel":1527},[256],[60,1529,1530],{},[127,1531,32],{"href":739,"rel":1532},[256],[60,1534,1535],{},[127,1536,36],{"href":834,"rel":1537},[256],[70,1539,1540,1557,1573,1606,1623],{},[57,1541,1542,1545,1548,1551,1554],{},[75,1543,1544],{},"Stars",[75,1546,1547],{},"2,005",[75,1549,1550],{},"342",[75,1552,1553],{},"25",[75,1555,1556],{},"1,454",[57,1558,1559,1562,1565,1568,1570],{},[75,1560,1561],{},"Forks",[75,1563,1564],{},"371",[75,1566,1567],{},"47",[75,1569,1412],{},[75,1571,1572],{},"151",[57,1574,1575,1578,1585,1592,1599],{},[75,1576,1577],{},"crates.io downloads (all time)",[75,1579,1580],{},[127,1581,1584],{"href":1582,"rel":1583},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Frdkafka",[256],"39,260,454",[75,1586,1587],{},[127,1588,1591],{"href":1589,"rel":1590},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Frskafka",[256],"1,170,945",[75,1593,1594],{},[127,1595,1598],{"href":1596,"rel":1597},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Fkrafka",[256],"21,418",[75,1600,1601],{},[127,1602,1605],{"href":1603,"rel":1604},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Fkafka",[256],"1,171,184",[57,1607,1608,1611,1614,1617,1620],{},[75,1609,1610],{},"crates.io downloads (90 d)",[75,1612,1613],{},"7,657,245",[75,1615,1616],{},"756,862",[75,1618,1619],{},"20,369",[75,1621,1622],{},"142,602",[57,1624,1625,1628,1635,1642,1649],{},[75,1626,1627],{},"Dependent crates on crates.io",[75,1629,1630],{},[127,1631,1634],{"href":1632,"rel":1633},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Frdkafka\u002Freverse_dependencies",[256],"304",[75,1636,1637],{},[127,1638,1641],{"href":1639,"rel":1640},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Frskafka\u002Freverse_dependencies",[256],"17",[75,1643,1644],{},[127,1645,1648],{"href":1646,"rel":1647},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Fkrafka\u002Freverse_dependencies",[256],"3",[75,1650,1651],{},[127,1652,1655],{"href":1653,"rel":1654},"https:\u002F\u002Fcrates.io\u002Fcrates\u002Fkafka\u002Freverse_dependencies",[256],"23",[10,1657,1658],{},"Downloads include CI builds and transitive dependencies, not unique users. Dependent crates covers only crates published on crates.io.",[510,1660,1662],{"id":1661},"overall-repository-signals","Overall repository signals",[147,1664,1665,1670,1675,1680],{},[150,1666,1667,1669],{},[14,1668,16],{}," leads crates.io downloads by a wide margin, with 7,657,245 downloads in 90 days and 304 dependent crates, but it had no default-branch commits or merged PRs in the last 90 days, and 50 open PRs have a median age of 1 year.",[150,1671,1672,1674],{},[14,1673,28],{}," had 756,862 downloads in 90 days but only 17 dependent crates; 4 PRs merged in 90 days with a median merge time of 5.5 hours, and it has not published to crates.io since 0.6.0 in March 2025.",[150,1676,1677,1679],{},[14,1678,32],{}," is the most active by far, with 54 commits and 15 merged PRs in 90 days and 32 crates.io releases since February 2026, but it is the youngest project, with 20,369 downloads in 90 days and two commit authors.",[150,1681,1682,1684],{},[14,1683,36],{}," has not published to crates.io since 0.10.0 in September 2023; master prepared 0.11.0 in July 2026, but that version is untagged and unpublished. It had no commits or merged PRs in the last 90 days; its 48 open issues have a median age of 5 years, yet it still had 142,602 downloads in 90 days.",[10,1686,1687],{},"In all four repositories, one account handled every recorded PR merge in the past year. These are maintenance and adoption signals, not evidence of runtime quality or feature fit.",[46,1689,1691],{"id":1690},"test-rust-kafka-clients-with-kafma","Test Rust Kafka clients with Kafma",[10,1693,1694,1695,1698],{},"A clean ",[19,1696,1697],{},"cargo build"," does not show which partition a key reached, what bytes a producer wrote, or what a consumer does with a record it cannot decode. All four clients hand keys and values to your code as bytes, so decoding and tombstone handling live in your code.",[10,1700,1701,1705,1706,1710],{},[127,1702,1704],{"href":1703},"\u002F","Kafma"," is a desktop Kafka GUI that runs alongside your Rust service. Its ",[127,1707,1709],{"href":1708},"\u002Ffeatures\u002Fkafka-console","Kafka console"," gives you one client-independent place to inspect producer output, send controlled records, and watch a consumer group's committed position.",[510,1712,1714],{"id":1713},"compare-partitions-for-the-same-keys","Compare partitions for the same keys",[10,1716,1717],{},"Produce the same keys from the old and new producers to a test topic with the same partition count. In Kafma, compare each record's key and partition. A kafka-rust producer and an rdkafka or krafka producer will usually place the same key on different partitions unless you reproduce the XxHash32 placement.",[510,1719,1721],{"id":1720},"check-schema-registry-framing","Check Schema Registry framing",[10,1723,1724,1725,1728,1729,1732,1733,1737],{},"When a consumer cannot decode a record, open it in Kafma. With Schema Registry configured, ",[14,1726,1727],{},"Decoded"," shows the value resolved through its schema ID, and ",[14,1730,1731],{},"Raw"," shows the original bytes as hexadecimal. Browse subjects and versions in Kafma's ",[127,1734,1736],{"href":1735},"\u002Ffeatures\u002Fkafka-schema-registry","Schema Registry UI",", then compare their schema IDs with the record.",[10,1739,1740,1741,1743,1744,1747],{},"If your consumer expects the Confluent payload-prefix format, ",[14,1742,1731],{}," should start with ",[19,1745,1746],{},"00"," followed by a four-byte schema ID. If it starts with plain JSON or text instead, the schema prefix is missing. Check whether the producer intentionally puts schema IDs in headers before treating the record as unframed.",[10,1749,1750],{},[1751,1752],"img",{"alt":1753,"height":1754,"src":1755,"width":1756},"Kafma showing an Avro record decoded through schema ID 7, with the Decoded and Raw views",1520,"https:\u002F\u002Fmedia.kafma.app\u002Fblog\u002Fkafka-javascript-clients\u002Fconsumer.png",2160,[510,1758,1760],{"id":1759},"test-consumer-errors-and-shutdown","Test consumer errors and shutdown",[10,1762,1763,1764,1768],{},"Use a test topic without an automatic schema binding, because Kafma validates input against a schema bound by topic name. Keep the consumer running and use the ",[127,1765,1767],{"href":1766},"\u002Fdocs\u002Fconsole\u002Fproducing-messages","producer panel"," to send, to one partition: a valid record, a payload your decoder rejects, a tombstone, and another valid record. Choose String or Bytes for the invalid payload and Null for the tombstone.",[10,1770,1771],{},"Check whether the invalid payload is retried, skipped, or stops processing, and whether the final record is processed and committed. Handle null values explicitly: unwrapping a tombstone's value panics, and inside a spawned Tokio task the process can keep running while that consumer silently stops.",[10,1773,1774,1775,1778,1779,1782,1783,1787,1788,1792],{},"For consumers that join a group, use ",[14,1776,1777],{},"Loop"," to keep records arriving, then send the service ",[19,1780,1781],{},"SIGTERM",". Open ",[127,1784,1786],{"href":1785},"\u002Fdocs\u002Fconsole\u002Fconsuming-messages#live-and-watch-group-modes","Watch Group"," and check that the member leaves, assignments settle, and the committed offset points to the next record after the last one processed. Kafma reads this state without joining the group or committing offsets; its ",[127,1789,1791],{"href":1790},"\u002Ffeatures\u002Fkafka-consumer-groups","consumer group UI"," shows lag across every member.",[10,1794,1795],{},[1751,1796],{"alt":1797,"height":1798,"src":1799,"width":1800},"Kafma watching pending and consumed records around a consumer group's committed offsets",1368,"https:\u002F\u002Fmedia.kafma.app\u002Fdocs\u002Fconsole\u002Fconsuming-messages\u002Fwatch-group.png",1562,[510,1802,1804],{"id":1803},"clone-data-for-migration-tests","Clone data for migration tests",[10,1806,1807,1811],{},[127,1808,1810],{"href":1809},"\u002Ffeatures\u002Fkafka-data-clone","Kafma Data Clone"," copies a selected range of real records to a test topic. Use it to exercise older schema versions, missing headers, tombstones, and other cases that hand-written fixtures miss. It can copy keys, values, timestamps, and headers, register required schemas, and mask selected fields.",[10,1813,1814,1815,1819],{},"Copied records receive new offsets and may land on different partitions. Use the clone to check decoding and consumer behavior, and compare partitions with records produced directly by the old and new clients. See the ",[127,1816,1818],{"href":1817},"\u002Fdocs\u002Fdata-clone\u002Foverview","Data Clone guide"," for copy behavior.",[10,1821,1822],{},[1751,1823],{"alt":1824,"height":1825,"src":1826,"width":1827},"Kafma cloning selected topics and masked records into a test cluster",1564,"https:\u002F\u002Fmedia.kafma.app\u002Fchangelog\u002Fv1.0.0\u002Fhomepage-data-clone.png",2740,[10,1829,1830,1834],{},[127,1831,1833],{"href":1832},"\u002Fdownload","Download Kafma"," and connect to the same test cluster as the Rust service.",[46,1836,1838],{"id":1837},"frequently-asked-questions","Frequently asked questions",[510,1840,1842],{"id":1841},"is-there-an-official-apache-kafka-client-for-rust","Is there an official Apache Kafka client for Rust?",[10,1844,1845],{},"No. Apache Kafka's first-party client is Java, and Confluent does not publish a Rust client. rdkafka is a community-maintained wrapper around Confluent's librdkafka, and rskafka, krafka, and kafka-rust are independent pure Rust implementations.",[510,1847,1849],{"id":1848},"can-i-build-rdkafka-without-a-c-compiler","Can I build rdkafka without a C compiler?",[10,1851,1852,1853,1855],{},"Not with the default features, which compile librdkafka from source. The ",[19,1854,211],{}," feature links a librdkafka that pkg-config can find instead, and that library must then be installed on every runtime host. rskafka and krafka avoid librdkafka, but their default feature sets still compile native dependencies and require a C toolchain.",[510,1857,1859],{"id":1858},"does-kafka-rust-work-with-kafka-40","Does kafka-rust work with Kafka 4.0?",[10,1861,1862,1863,1866,1867,131],{},"No. Release 0.10.0 sends version 0 of the Produce, Fetch, and ListOffsets requests, and Kafka 4.0 removed those versions under ",[127,1864,873],{"href":871,"rel":1865},[256],". The unreleased 0.11.0 on master still uses version 0. See ",[127,1868,130],{"href":129},[510,1870,1872],{"id":1871},"which-rust-kafka-clients-support-kip-848","Which Rust Kafka clients support KIP-848?",[10,1874,1875,1876,1878,1879,1881],{},"rdkafka 0.39.0 and krafka 0.26.0, both on Kafka 4.0+. In rdkafka, set ",[19,1877,379],{},"; the bundled librdkafka 2.12.1 includes the generally available implementation. In krafka, use ",[19,1880,780],{},". rskafka and kafka-rust do not support consumer group membership at all.",[510,1883,1885],{"id":1884},"which-rust-kafka-client-works-with-aws-msk-iam","Which Rust Kafka client works with AWS MSK IAM?",[10,1887,1888,1889,1891,1892,1894,1895,1898],{},"krafka supports AWS MSK IAM directly; enable the ",[19,1890,804],{}," feature for the AWS SDK credential chain. rdkafka can connect through SASL\u002FOAUTHBEARER using tokens from the community ",[19,1893,632],{}," crate; see ",[127,1896,16],{"href":1897},"#rdkafka"," for the token callback configuration. rskafka and kafka-rust have no built-in MSK IAM support.",[510,1900,1902],{"id":1901},"do-rust-kafka-clients-partition-keys-the-same-way-as-java","Do Rust Kafka clients partition keys the same way as Java?",[10,1904,1905,1906,1908],{},"krafka does by default, using Murmur2. rdkafka needs ",[19,1907,602],{},", because its default uses CRC32. kafka-rust uses XxHash32, which no other client matches without a custom partitioner. rskafka has no partitioner; your code chooses the partition.",[510,1910,1912],{"id":1911},"is-rdkafka-still-maintained","Is rdkafka still maintained?",[10,1914,1915],{},"The repository is not archived, and 0.39.0 shipped on 25 Jan 2026. However, the 8 Oct 2026 snapshot found no default-branch commits or merged PRs in the preceding 90 days and 50 open PRs with a median age of 1 year. Recent activity in the Rust wrapper is limited. Much of the protocol work happens upstream in librdkafka.",[46,1917,1919],{"id":1918},"conclusion","Conclusion",[10,1921,1922],{},"For most production services, start with rdkafka: it has librdkafka's mature consumer groups and transactions and by far the most crates.io downloads of the four. Choose krafka when you want to avoid librdkafka and can accommodate API changes during upgrades. Use rskafka for explicit partition-level reads and writes, managing offsets yourself when consuming.",[10,1924,1925],{},"If you still run kafka-rust, plan the move before your brokers reach Kafka 4.0, and compare where keyed records land before the new producer takes over.",[10,1927,1928],{},"This guide is maintained by the team behind Kafma.",{"title":1930,"searchDepth":1931,"depth":1931,"links":1932},"",3,[1933,1935,1936,1942,1943,1944,1951,1957,1966],{"id":48,"depth":1934,"text":49},2,{"id":141,"depth":1934,"text":142},{"id":233,"depth":1934,"text":234,"children":1937},[1938,1939,1940,1941],{"id":16,"depth":1931,"text":16},{"id":28,"depth":1931,"text":28},{"id":32,"depth":1931,"text":32},{"id":36,"depth":1931,"text":36},{"id":940,"depth":1934,"text":138},{"id":1018,"depth":1934,"text":130},{"id":1139,"depth":1934,"text":1140,"children":1945},[1946,1947,1948,1949,1950],{"id":1146,"depth":1931,"text":1147},{"id":1218,"depth":1931,"text":1219},{"id":1370,"depth":1931,"text":1371},{"id":1508,"depth":1931,"text":1509},{"id":1661,"depth":1931,"text":1662},{"id":1690,"depth":1934,"text":1691,"children":1952},[1953,1954,1955,1956],{"id":1713,"depth":1931,"text":1714},{"id":1720,"depth":1931,"text":1721},{"id":1759,"depth":1931,"text":1760},{"id":1803,"depth":1931,"text":1804},{"id":1837,"depth":1934,"text":1838,"children":1958},[1959,1960,1961,1962,1963,1964,1965],{"id":1841,"depth":1931,"text":1842},{"id":1848,"depth":1931,"text":1849},{"id":1858,"depth":1931,"text":1859},{"id":1871,"depth":1931,"text":1872},{"id":1884,"depth":1931,"text":1885},{"id":1901,"depth":1931,"text":1902},{"id":1911,"depth":1931,"text":1912},{"id":1918,"depth":1934,"text":1919},"2026-10-08","kafka-rust last shipped in 2023, and rskafka has no consumer groups. Compare Rust Kafka clients: rdkafka, rskafka, and krafka.","md",{},true,null,"\u002Fblog\u002Fkafka-rust-clients",false,{"title":5,"description":1968},{"loc":1973},"blog\u002Fkafka-rust-clients",[1979,1980],"Kafka Client Libraries","Rust","eoNf4YOTPK8COWzpTMmoKlb2u9Owd6Ei-VLTLbzNKG0",1791456455281]