<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Leonid Ganeline</title>
    <description>The latest articles on DEV Community by Leonid Ganeline (@leogan).</description>
    <link>https://dev.to/leogan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4219770%2Fe3bbe85e-3a4a-4dab-b482-01b06b9326bd.png</url>
      <title>DEV Community: Leonid Ganeline</title>
      <link>https://dev.to/leogan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/leogan"/>
    <language>en</language>
    <item>
      <title>Kiln - implemented the same wire format from scratch in 11 languages</title>
      <dc:creator>Leonid Ganeline</dc:creator>
      <pubDate>Sat, 31 Oct 2026 23:58:28 +0000</pubDate>
      <link>https://dev.to/leogan/kiln-implemented-the-same-wire-format-from-scratch-in-11-languages-4a25</link>
      <guid>https://dev.to/leogan/kiln-implemented-the-same-wire-format-from-scratch-in-11-languages-4a25</guid>
      <description>&lt;p&gt;I benchmarked ~300 serializers across 14 languages, then built my own.&lt;br&gt;
&lt;code&gt;Kiln&lt;/code&gt; is a frozen, positional, little-endian wire format - and I wrote it&lt;br&gt;
from scratch eleven times: Mojo, Go, Rust, Zig, C, C++, Python, Java,&lt;br&gt;
Swift, C#, and TypeScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one idea
&lt;/h2&gt;

&lt;p&gt;JSON writes the names next to the values. Take a struct with two 32-bit&lt;br&gt;
integers, &lt;code&gt;x = 9&lt;/code&gt; and &lt;code&gt;y = -4&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON: &lt;code&gt;{"x":9,"y":-4}&lt;/code&gt; - 14 bytes, names included.&lt;/li&gt;
&lt;li&gt;Protocol Buffers: 13 bytes in this illustration, with a field number in
front of each value (and &lt;code&gt;-4&lt;/code&gt; widened to a 10-byte varint).&lt;/li&gt;
&lt;li&gt;Kiln: &lt;code&gt;09 00 00 00 fc ff ff ff&lt;/code&gt; - 8 bytes. Just the two values, in
declaration order, least significant byte first.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both sides are built from the same struct, so each side already knows&lt;br&gt;
which four bytes are &lt;code&gt;x&lt;/code&gt;. The names stay in the source code, not on the&lt;br&gt;
wire - and they are not written again on every copy of a batch, either.&lt;/p&gt;

&lt;h2&gt;
  
  
  The price, stated plainly
&lt;/h2&gt;

&lt;p&gt;There is no name and no field number to jump over, so an unknown field&lt;br&gt;
cannot be skipped. If the writer adds a third field, a reader built from&lt;br&gt;
the two-field struct stops instead of guessing. That is the trade Kiln&lt;br&gt;
makes on purpose, and version 2 of the spec writes its refusals down:&lt;br&gt;
no per-field evolution tags, no columnar profile, no compression&lt;br&gt;
wrapper, no dequantization, no GPU pointer. If you need those jobs,&lt;br&gt;
other formats already do them well - Kiln refuses to pretend to be them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What kept eleven implementations honest
&lt;/h2&gt;

&lt;p&gt;One spec, and golden files. A Python reference codec writes the golden&lt;br&gt;
files; every from-scratch codec is tested against them. That was the&lt;br&gt;
only thing that could catch eleven independent implementations drifting&lt;br&gt;
apart - and it is why the format is one format, not eleven similar ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measured, not claimed
&lt;/h2&gt;

&lt;p&gt;On an Intel i7-12800H (powersave governor, one pinned core, Mojo 1.1.0),&lt;br&gt;
&lt;code&gt;experiments/decode_small.mojo&lt;/code&gt; measured a 44-byte message at mean 15 ns&lt;br&gt;
to encode and mean 28 ns to decode into owned strings. A batch of 100&lt;br&gt;
messages encodes in mean 339 ns and decodes in mean 1.56 µs when UTF-8&lt;br&gt;
is checked. The experiments page records the machine and the decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to find it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://leo-gan.github.io/gld-kiln" rel="noopener noreferrer"&gt;Spec + docs:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/leo-gan/gld-kiln" rel="noopener noreferrer"&gt;Flagship (Mojo):&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;package &lt;code&gt;mojo-kiln&lt;/code&gt; on prefix.dev (linux-64), import &lt;code&gt;kiln&lt;/code&gt;,
generator &lt;code&gt;gld-kilngen-mojo&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The other ten codecs: serialization, gld-kiln-go, gld-kiln-rust, gld-kiln-zig,
gld-kiln-c, gld-kiln-cpp, gld-kiln-python, gld-kiln-java,
gld-kiln-swift, gld-kiln-csharp, gld-kiln-typescript
(all under github.com/leo-gan/)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If Kiln is useful to you, a star on the repo for the language you use&lt;br&gt;
is the fastest way to help it grow. Feedback on the spec itself is&lt;br&gt;
welcome - that is what a young format needs most.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
