<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title>Sitegui&apos;s Blog</title><id>https://sitegui.dev/</id><updated>2026-03-10T03:00:30.815715787+00:00</updated><author><name>sitegui</name></author><category term="programming"/><category term="math"/><category term="boardgames"/><icon>https://sitegui.dev/static/favicon.png</icon><link href="https://sitegui.dev/feed.xml" rel="self"/><subtitle>My personal webspace, with content about programming, math and boardgames</subtitle><entry><title>Understanding Bytes in Rust, one bit at a time</title><id>9aaf95cc-858e-40df-bf2c-a53b8f53668f</id><updated>2026-02-27T00:00:00+00:00</updated><author><name>sitegui</name></author><category term="programming"/><category term="rust"/><category term="bytes"/><link href="https://sitegui.dev/post/2026/understanding-bytes-in-rust-one-bit-at-a-time" rel="alternate"/><published>2026-02-27T00:00:00+00:00</published><content xml:base="https://sitegui.dev/post/2026/understanding-bytes-in-rust-one-bit-at-a-time" type="html">&lt;p&gt;In Rust, the tokio&apos;s ecosystem has a fundamental crate called &lt;a href=&quot;https://crates.io/crates/bytes&quot;&gt;&lt;code&gt;bytes&lt;/code&gt;&lt;/a&gt; that abstracts
and helps dealing with bytes (you don&apos;t say!). I&apos;ve indirectly used it a billion times and I thought that I had a good
mental model of how it worked.&lt;/p&gt;
&lt;p&gt;So, in the spirit of the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLqbS7AVVErFirH9armw8yXlE6dacF-A6z&quot;&gt;&amp;quot;decrusting&amp;quot; series&lt;/a&gt;
by the excellent Jon Gjengset, I&apos;ve decided to peek behind the curtains to understand more what axum, tokio, hyper and
the kind do to them bytes! The code is well written, but surprisingly complex. I understand now what it does, but I
still don&apos;t fully grasp &lt;em&gt;why&lt;/em&gt; it does some things in a certain way.&lt;/p&gt;
&lt;p&gt;I&apos;m ready to share with you my discoveries. I hope that you are sitting, laying or squatting comfortably. This is the
first post in a small series. I&apos;m legally required by my marketing department to remind you that you can &lt;a href=&quot;#end-of-page&quot;&gt;subscribe to
my low-traffic newsletter&lt;/a&gt;, so that you&apos;ll know when new posts are up!&lt;/p&gt;
&lt;p&gt;A quick note before we start: this posts is based on the current &lt;code&gt;bytes&lt;/code&gt; version 1.11.1.&lt;/p&gt;
&lt;h2&gt;What the Bytes?&lt;/h2&gt;
&lt;p&gt;&lt;a name=&quot;continue-reading&quot; class=&quot;continue-reading&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;bytes&lt;/code&gt; crate does many things, but its public API is quite small: it basically has two structs and two traits.
Quoting from the documentation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;struct Bytes&lt;/code&gt;: a cheaply cloneable and sliceable chunk of contiguous memory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;struct BytesMut&lt;/code&gt;: a unique reference to a contiguous slice of memory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trait Buf&lt;/code&gt;: read bytes from a buffer&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trait BufMut&lt;/code&gt;: a trait for values that provide sequential write access to bytes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this series, I&apos;ll focus on the &lt;code&gt;Bytes&lt;/code&gt; struct, because yeah, it&apos;s not as simple as one may be led to believe!&lt;/p&gt;
&lt;h2&gt;A compelling example&lt;/h2&gt;
&lt;p&gt;I would like to start concrete, with an example of what the problem that &lt;code&gt;Bytes&lt;/code&gt; helps solve: zero-copy parsing.
Imagine that you&apos;re parsing HTTP requests and your code receives these bytes from the network:&lt;/p&gt;
&lt;pre style=&quot;background-color:#111; color:#eee&quot;&gt;
&lt;span style=&quot;background-color:#633&quot;&gt;GET&lt;/span&gt; &lt;span style=&quot;background-color:#363&quot;&gt;/post/2026/some-post&lt;/span&gt; &lt;span style=&quot;background-color:#336&quot;&gt;HTTP/2&lt;/span&gt;
&lt;span style=&quot;background-color:#366&quot;&gt;Host&lt;/span&gt;: &lt;span style=&quot;background-color:#636&quot;&gt;sitegui.dev&lt;/span&gt;
&lt;span style=&quot;background-color:#366&quot;&gt;Accept&lt;/span&gt;: &lt;span style=&quot;background-color:#636&quot;&gt;text/html&lt;/span&gt;
&lt;span style=&quot;background-color:#366&quot;&gt;Referer&lt;/span&gt;: &lt;span style=&quot;background-color:#636&quot;&gt;https://sitegui.dev/&lt;/span&gt;
&lt;span style=&quot;background-color:#366&quot;&gt;Connection&lt;/span&gt;: &lt;span style=&quot;background-color:#636&quot;&gt;keep-alive&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;You would like to efficiently parse it into a struct like this:&lt;/p&gt;
&lt;pre style=&quot;background-color:#111; color:#eee&quot;&gt;
struct Request {
    method: &lt;span style=&quot;background-color:#633&quot;&gt;Something&lt;/span&gt;,
    path: &lt;span style=&quot;background-color:#363&quot;&gt;Something&lt;/span&gt;,
    version: &lt;span style=&quot;background-color:#336&quot;&gt;Something&lt;/span&gt;,
    /// Note: headers can repeat, so I&apos;m using a
    /// `Vec` not a `HashMap` to represent them
    headers: Vec&lt;(&lt;span style=&quot;background-color:#366&quot;&gt;Something&lt;/span&gt;, &lt;span style=&quot;background-color:#636&quot;&gt;Something&lt;/span&gt;)&gt;,
}
&lt;/pre&gt;
&lt;p&gt;This post is not about the parsing bit, instead it&apos;s about the bytes themselves. What should we choose as &lt;code&gt;Something&lt;/code&gt;
above?&lt;/p&gt;
&lt;p&gt;If you chose a type like &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt;, your parser would need to allocate and copy the information into many
multiple instances of &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt;. But with &lt;code&gt;Bytes&lt;/code&gt;, all these instances are cheap to produce as they share the same
storage (your initial bytes are represented only once) and each instance then has a &amp;quot;window&amp;quot; to
this buffer. The underlying buffer will only be deallocated when &lt;em&gt;all&lt;/em&gt; the instances sharing it are dropped.&lt;/p&gt;
&lt;p&gt;As usual in computing, using &lt;code&gt;Bytes&lt;/code&gt; (or any &amp;quot;shared&amp;quot; construction) vs &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt; (or any &amp;quot;owned&amp;quot;
construction) is a matter of trade-offs. For example, if your parser code only produces output that references a
small part of the input, it&apos;s probably better to copy over just that. Otherwise, the &lt;code&gt;Bytes&lt;/code&gt; instances will keep the
whole input around in memory.&lt;/p&gt;
&lt;h2&gt;An initial mental model&lt;/h2&gt;
&lt;p&gt;As I said before, I had a useful mental model before embarking in this exploration: a &lt;code&gt;Bytes&lt;/code&gt; instance simply has a
reference-counted shared reference to the actual bytes and some information to where in the buffer those bytes are.
The fundamental operations available are:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;trait &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;BytesStorage {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;/// Create a new instance with some data
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;/// It should &amp;quot;adopt&amp;quot; the data, not copy it
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: Vec&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;gt;) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;Self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;/// Create a new instance that references some part of this data
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;/// Constant time, and it should not copy the actual data
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: Range&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;usize&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;gt;) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;Self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;/// Return the bytes slice
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;/// Very cheap
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;as_ref&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;) -&amp;gt; &amp;amp;[&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;];
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We could draft a similar-in-spirit implementation using &lt;code&gt;Arc&amp;lt;Vec&amp;lt;u8&amp;gt;&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;pub struct &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;SharedBytes {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: Range&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;usize&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;gt;,
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: Arc&amp;lt;Vec&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;gt;&amp;gt;,
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;impl &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;BytesStorage &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;for &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;SharedBytes {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: Vec&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;gt;) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;Self &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;Self &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;            range: &lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;            data: Arc::new(data),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: Range&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;usize&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;gt;) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;Self &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;// Translate the &amp;quot;local&amp;quot; range to a &amp;quot;global&amp;quot; range
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt; root_range = range.start + &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;.range.start..range.end + &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;.range.start;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;Self &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;            range: root_range,
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;            data: &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;.data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;clone&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;as_ref&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;) -&amp;gt; &amp;amp;[&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;] {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;.data[&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;.range.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;clone&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;()]
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note how &lt;code&gt;new()&lt;/code&gt; does not clone the data, instead the &lt;code&gt;Vec&lt;/code&gt; is adopted into the &lt;code&gt;SharedBytes&lt;/code&gt; instance.
Also, &lt;code&gt;slice()&lt;/code&gt; clones the &lt;code&gt;Arc&amp;lt;_&amp;gt;&lt;/code&gt;, which uses reference counting and avoids cloning the actual data in the &lt;code&gt;Vec&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, &lt;code&gt;as_ref()&lt;/code&gt; is not very good for two reasons: Rust will execute bound checks to ensure that the range is valid
at every access, and the actual buffer is behind two memory references &lt;code&gt;Arc&lt;/code&gt; (in &lt;code&gt;SharedBytes&lt;/code&gt;) -&amp;gt; &lt;code&gt;Vec&lt;/code&gt; -&amp;gt; buffer.&lt;/p&gt;
&lt;p&gt;The actual &lt;code&gt;Bytes&lt;/code&gt; implementation avoids these two problems by storing the slice components (pointer to first byte and
length) as two fields directly in the struct, trading off some bloat in the struct and a small performance hit in the
&lt;code&gt;slice()&lt;/code&gt; operation for a simpler &lt;code&gt;as_slice()&lt;/code&gt;:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;pub struct &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;Bytes {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;ptr&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: *const &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;,
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;usize&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;,
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;// ... more fields ...
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;impl &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;Bytes {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    #[&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;inline&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;]
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;as_slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;) -&amp;gt; &amp;amp;[&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;] {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;unsafe &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{ slice::from_raw_parts(&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;.ptr, &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;.len) }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Let&apos;s test our mental model&lt;/h2&gt;
&lt;p&gt;In Rust, you can set a different global memory allocator like this:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;std::alloc::{GlobalAlloc, Layout, System};
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;/// A global allocator that can track all allocations made
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;struct &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;TrackingAllocator;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;// Ask Rust to use our allocator as the global allocator
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;#[&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;global_allocator&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;]
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;static &lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;ALLOCATOR&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: TrackingAllocator = TrackingAllocator;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;unsafe impl &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;GlobalAlloc &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;for &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;TrackingAllocator {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;unsafe fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;alloc&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;layout&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: Layout) -&amp;gt; *&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;mut u8 &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;// Do stuff
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;unsafe &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{ System.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;alloc&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(layout) }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;unsafe fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;dealloc&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;ptr&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;mut u8&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;layout&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: Layout) {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;// Do stuff
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;unsafe &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{ System.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;dealloc&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(ptr, layout) };
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There
is &lt;a href=&quot;https://github.com/rust-lang/wg-allocators&quot;&gt;a Rust working group to have a more fine control of the allocator&lt;/a&gt;,
allowing us to overwrite it only for some parts of the code. But for this reduced example, it&apos;s okay to capture all
allocations.&lt;/p&gt;
&lt;p&gt;I used this mechanism to track exactly which allocations and deallocations the code was doing for &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt;, our own
&lt;code&gt;SharedBytes&lt;/code&gt; and &lt;code&gt;bytes::Bytes&lt;/code&gt; and where in the source code they
happened. &lt;a href=&quot;https://git.sitegui.dev/sitegui/blog-post-understanding-bytes&quot;&gt;You can check the full code here&lt;/a&gt;,
if you are curious or want to reproduce my work.&lt;/p&gt;
&lt;p&gt;To simulate the HTTP parser, I&apos;m using this simple code:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;parse_request&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;lt;B: BytesStorage&amp;gt;(&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;: Vec&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;gt;) -&amp;gt; Request&amp;lt;B&amp;gt; {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt; data = B::new(data);
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    Request {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        method: data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        path: data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;24&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        version: data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;25&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;31&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        headers: vec![
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;            (data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;33&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;37&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;), data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;39&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;)),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;            (data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;52&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;58&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;), data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;69&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;)),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;            (data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;71&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;78&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;), data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;80&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;)),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;            (data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;102&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;112&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;), data.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;114&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;124&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;)),
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        ],
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    }
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following table shows what each line of the code above allocates for &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt;, &lt;code&gt;SharedBytes&lt;/code&gt; and &lt;code&gt;bytes::Bytes&lt;/code&gt;, in
bytes.&lt;/p&gt;
&lt;p&gt;But before looking at the results, take a while to run this code against your mental model and try to predict
how many allocations will occur for each implementation and where that will happen.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code source&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;&lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt;&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;&lt;code&gt;SharedBytes&lt;/code&gt;&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;&lt;code&gt;bytes::Bytes&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;data = B::new(data)&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;40&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;method: data.slice(0..3)&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;3&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;path: data.slice(4..24)&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;20&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;version: data.slice(25..31)&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;6&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vec![...]&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;192&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;192&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;256&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8x &lt;code&gt;data.slice(...)&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;57&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;298&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;232&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;280&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As I expected, &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt; allocates a new independent buffer in every call to &lt;code&gt;.slice()&lt;/code&gt;, with the necessary capacity for
the data piece then copy it. &lt;code&gt;SharedBytes&lt;/code&gt; allocates the &lt;code&gt;Arc&amp;lt;Vec&amp;lt;u8&amp;gt;&amp;gt;&lt;/code&gt; once at the start, and later the
&lt;code&gt;Vec&amp;lt;(B, B)&amp;gt;&lt;/code&gt; with 8
× 24 bytes.&lt;/p&gt;
&lt;p&gt;I want to explore in a separate blog post the whys and the hows &lt;code&gt;Arc&amp;lt;Vec&amp;lt;u8&amp;gt;&amp;gt;&lt;/code&gt; has 40 bytes, and also compare it
against &lt;code&gt;Arc&amp;lt;[u8]&amp;gt;&lt;/code&gt;. Stay
tuned!&lt;/p&gt;
&lt;p&gt;The behavior of &lt;code&gt;Bytes&lt;/code&gt; was interesting to me for two reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it somehow defers the first allocation: &lt;code&gt;B::new()&lt;/code&gt; doesn&apos;t allocate (in this case), but the first call to &lt;code&gt;.slice()&lt;/code&gt;
does. Spoiler alert: it&apos;s pretty neat but complex. I&apos;ll explore it in details later on.&lt;/li&gt;
&lt;li&gt;it&apos;s big! 32 bytes each instance. So &lt;code&gt;Vec&amp;lt;(B, B)&amp;gt;&lt;/code&gt; has 8 × 32 bytes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;No &lt;code&gt;Arc&lt;/code&gt; in sight&lt;/h2&gt;
&lt;p&gt;Armed with the above initial mental model, it&apos;s not a surprise that the documentation and comments in the file
implementing &lt;code&gt;Bytes&lt;/code&gt; mention &lt;code&gt;Arc&lt;/code&gt; 6 times. What is a bit eyebrow-raising is that the code itself does not use &lt;code&gt;Arc&lt;/code&gt;
at all!&lt;/p&gt;
&lt;p&gt;Maybe it&apos;s related to the defered allocation we saw before? Maybe it&apos;s related to the 32 bytes needed for each instance?
Well, kind of...&lt;/p&gt;
&lt;p&gt;I&apos;ll use memory diagrams like this one below to represent what the structs (in grey) are made of. Simple numerical
fields are in yellow and pointers are in green. In parentheses, I&apos;ve put the memory size in bytes, assuming a 64-bit
system.&lt;/p&gt;
&lt;p&gt;For example, in Rust you can represent a &lt;em&gt;growable&lt;/em&gt; owned sequence with &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; and a &lt;em&gt;fixed&lt;/em&gt; owned sequence
with &lt;code&gt;Box&amp;lt;[T]&amp;gt;&lt;/code&gt;. The physical difference is that &lt;code&gt;Vec&lt;/code&gt; may have allocated more space than it is currently using, to
amortize buffer grow on inserts, so it uses an additional &lt;code&gt;capacity&lt;/code&gt; field. A &lt;code&gt;Box&lt;/code&gt; uses exactly the bufffer&apos;s size, so
length and capacity are the same. Converting from a &lt;code&gt;Vec&lt;/code&gt; that is &amp;quot;full&amp;quot; (that is, for which capacity is the same as
length) is cheap because the underlying buffer is reused:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/understanding-bytes-in-rust-one-bit-at-a-time/vec_to_box.png&quot; alt=&quot;Converting a Vec to Box&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Here&apos;s a Box. Give-me Bytes&lt;/h2&gt;
&lt;p&gt;The implementation of &lt;code&gt;Bytes::from(Vec&amp;lt;u8&amp;gt;)&lt;/code&gt; will first check if it&apos;s a &amp;quot;full&amp;quot; Vec to convert it into a
&lt;code&gt;Box&amp;lt;[u8]&amp;gt;&lt;/code&gt; and build a &lt;code&gt;Bytes&lt;/code&gt; instance like below. When the &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt; it not &amp;quot;full&amp;quot;, a different logic is used, but
let&apos;s
put that aside for now.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/understanding-bytes-in-rust-one-bit-at-a-time/box_to_bytes.png&quot; alt=&quot;Converting a Box to Bytes&quot; /&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s a lot to unpack. I&apos;ll explain what I&apos;ve understood of the design and the trade-offs of this representation:&lt;/p&gt;
&lt;p&gt;First, note that the buffer is reused, as expected.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;length&lt;/code&gt; fields simply represent the slice information. It seems a bit redundant with the &lt;code&gt;data&lt;/code&gt;
field, that also points to the buffer. However, this distinction will be useful when we slice this data: the start
of our &amp;quot;window&amp;quot; will be different from the buffer&apos;s start, and we need to keep the buffer&apos;s start around so that we
can deallocate it when the moment comes.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;vtable&lt;/code&gt; field implements the &amp;quot;dynamic dispatch&amp;quot; pattern. Rust has &amp;quot;trait objects&amp;quot; to implement this pattern with
&lt;code&gt;&amp;amp;dyn SomeTrait&lt;/code&gt; or &lt;code&gt;Box&amp;lt;dyn SomeTrait&amp;gt;&lt;/code&gt;, but I guess the designers of the crate didn&apos;t use them because this pattern
has restrictions that are a deal-breaker for this use. If you know more why, please tell me!&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;vtable&lt;/code&gt; points to a statically declared instance of &lt;code&gt;VTable&lt;/code&gt; called &amp;quot;promotable&amp;quot;. Aha! This name is related
to how &lt;code&gt;Bytes&lt;/code&gt; deferr allocation as we observed earlier.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;data&lt;/code&gt; field is funny-looking (no judgements!): it&apos;s an &lt;code&gt;AtomicPtr&amp;lt;_&amp;gt;&lt;/code&gt;, that unlike a normal pointer, uses atomic
operations to read/write to it. But why do we need atomic operations here? Spoiler alert: it&apos;s the deferred allocation
again. Somehow (we&apos;ll see next), this pointer will point to something else in the future.&lt;/p&gt;
&lt;p&gt;Continuing on the &lt;code&gt;data&lt;/code&gt; field, it&apos;s not just a pointer. It uses the pattern of &amp;quot;tagged pointer&amp;quot; to store one bit of
information there. I think you can already guess it: it&apos;s the deferred allocation again. This trick avoids having a
separate field for this, but it requires the code to ensure and check that the pointer to the buffer is always a
multiple of 2, so that the least bit carries no useful information and can be co-opted as a tag.&lt;/p&gt;
&lt;h2&gt;The other side of the river&lt;/h2&gt;
&lt;p&gt;Let&apos;s spring straight into action: what happens when we slice our newly-created &lt;code&gt;Bytes&lt;/code&gt;? I&apos;ve tried my best to
convey everything that happens in the diagram below without making it too busy. Take some time to navigate it first.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/understanding-bytes-in-rust-one-bit-at-a-time/slice_promotable.png&quot; alt=&quot;Slicing a promotable Bytes&quot; /&gt;&lt;/p&gt;
&lt;p&gt;First, note that calling &lt;code&gt;.slice(&amp;amp;self)&lt;/code&gt; the first time actually modifies the original &lt;code&gt;Bytes&lt;/code&gt;: the previous state of
the instance is represented in a dashed countour, the new state uses red on the changed field: &lt;code&gt;data&lt;/code&gt;. Naturally, only
this field can be modified, because &lt;code&gt;.slice(&amp;amp;self)&lt;/code&gt; takes a shared reference, so only internal mutation is possible,
through the
&lt;code&gt;AtomicPtr&amp;lt;_&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As we&apos;ve observed earlier, a new piece of data is allocated: an instance of the &lt;code&gt;Shared&lt;/code&gt; struct with 24 bytes. It
carries information about the original buffer that will be used to deallocate (&lt;code&gt;buffer&lt;/code&gt; and &lt;code&gt;capacity&lt;/code&gt;). I was surprised
to learn that in Rust the original size of the buffer is actually necessary to deallocate it. I was used to C&apos;s
&lt;code&gt;free(ptr)&lt;/code&gt; that clearly doesn&apos;t need it.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Shared&lt;/code&gt; struct also carries an atomic counter with the number of &lt;code&gt;Bytes&lt;/code&gt; instances referencing this buffer. The
implementation doesn&apos;t use Rust&apos;s native &lt;code&gt;Arc&lt;/code&gt;. Instead the designers preferred re-implementing it. I could not find a
definitive answer to why, but I guess that&apos;s because they wanted to avoid the overhead in &lt;code&gt;Arc&lt;/code&gt; related to the
implementation of &amp;quot;weak references&amp;quot;, that is not necessary for &lt;code&gt;Bytes&lt;/code&gt;&apos; use case. To implement it, &lt;code&gt;Arc&lt;/code&gt; uses an
additional atomic counter and executes some extra atomic instructions when cloning and droping.&lt;/p&gt;
&lt;p&gt;Finally, note how the &lt;code&gt;vtable&lt;/code&gt; pointer does not change: it&apos;s still the same &amp;quot;promotable&amp;quot; method list. The code uses the
tag in the &lt;code&gt;data&lt;/code&gt; pointer to distinguish a not-yet-promoted &lt;code&gt;data&lt;/code&gt; (tag = 1) from a promoted &lt;code&gt;data&lt;/code&gt; (tag = 0).&lt;/p&gt;
&lt;p&gt;The deferred allocation feature is a trade-off: the code is more complex because we need an &lt;code&gt;AtomicPtr&lt;/code&gt; and a tag to
implement it. However, for code that creates a &lt;code&gt;Bytes&lt;/code&gt; without actually slicing and sharing them, it avoids the &lt;code&gt;Shared&lt;/code&gt;
allocation entirely.&lt;/p&gt;
&lt;h2&gt;It&apos;s a lie&lt;/h2&gt;
&lt;p&gt;Let&apos;s step back a bit: the behavior above only happens when we create a &lt;code&gt;Bytes&lt;/code&gt; from a &lt;code&gt;Box&amp;lt;[u8]&amp;gt;&lt;/code&gt; or &amp;quot;full&amp;quot; &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt;.
When we start with a non-full &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt;, the code will not use the deferred mechanism and instead allocates a &lt;code&gt;Shared&lt;/code&gt;
struct right away. In this case, there&apos;s no tagging of the &lt;code&gt;data&lt;/code&gt; field and a dedicated &lt;code&gt;vtable&lt;/code&gt; is used that will not
check for the tag:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/understanding-bytes-in-rust-one-bit-at-a-time/vec_to_bytes.png&quot; alt=&quot;Converting a Vec to Bytes&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is very similar to how the simpler &lt;code&gt;SharedBytes&lt;/code&gt; work, except that &lt;code&gt;Bytes&lt;/code&gt; has 8 more bytes for the &lt;code&gt;vtable&lt;/code&gt; and
&lt;code&gt;Shared&lt;/code&gt; has 8 fewer bytes than &lt;code&gt;Arc&amp;lt;Vec&amp;lt;u8&amp;gt;&amp;gt;&lt;/code&gt; for the lack of weak references.&lt;/p&gt;
&lt;h2&gt;Bytes are versatile&lt;/h2&gt;
&lt;p&gt;The dynamic dispatch implemented by &lt;code&gt;Bytes&lt;/code&gt; with the &lt;code&gt;vtable&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt; fields effectively allows it to use custom
implementation for different backing storages of the data.&lt;/p&gt;
&lt;p&gt;We saw what happens to &lt;code&gt;Box&lt;/code&gt; and &lt;code&gt;Vec&lt;/code&gt;. Here&apos;s what happens when you create a &lt;code&gt;Bytes&lt;/code&gt; from an existing statically
allocated slice of bytes (in Rust represented as &lt;code&gt;&amp;amp;&apos;static [u8]&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/understanding-bytes-in-rust-one-bit-at-a-time/static_to_bytes.png&quot; alt=&quot;Converting static slice to Bytes&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Note that there is no reference counting, because in this mode, &lt;code&gt;Bytes&lt;/code&gt; does not own the data: instead it borrows data
that outlives it, as indicated by the &lt;code&gt;&apos;static&lt;/code&gt; lifetime.&lt;/p&gt;
&lt;p&gt;Another interesting usage of the dynamic dispatch is to create &lt;code&gt;Bytes&lt;/code&gt; from anything else that somehow owns a buffer.
For example, from a &lt;code&gt;memmap2::Mmap&lt;/code&gt; instance that represents a memory-mapped region:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/understanding-bytes-in-rust-one-bit-at-a-time/owned_to_bytes.png&quot; alt=&quot;Converting owned struct to Bytes&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Note that the owned struct is copied over into &lt;code&gt;Onwed&lt;/code&gt; that, just like &lt;code&gt;Shared&lt;/code&gt;, acts like an &lt;code&gt;Arc&amp;lt;_&amp;gt;&lt;/code&gt; without the weak
reference feature. The major distinction between &lt;code&gt;Owned&lt;/code&gt; and &lt;code&gt;Shared&lt;/code&gt; is that &lt;code&gt;Bytes&lt;/code&gt; does not know how to take
ownership of the buffer, as it only requires that the given type implements &lt;code&gt;AsRef&amp;lt;[u8]&amp;gt;&lt;/code&gt; to produces a
borrowed slice of bytes.&lt;/p&gt;
&lt;h2&gt;Micro benchmarks&lt;/h2&gt;
&lt;p&gt;Never trust a benchmark you see online. So here&apos;s one more for you to ignore:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;lt;B: BytesStorage&amp;gt;() {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt; data = &lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;black_box&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;example_request_package&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;());
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt; request = parse_request::&amp;lt;B&amp;gt;(data);
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;assert_example_request&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;amp;request);
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;&lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt;&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;&lt;code&gt;SharedBytes&lt;/code&gt;&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;&lt;code&gt;bytes::Bytes&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Allocated (bytes)&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;298&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;232&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;280&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execution time (ns)&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;115&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;115&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;150&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;So &lt;code&gt;Bytes&lt;/code&gt; seems both chunkier and slower than my half-backed &lt;code&gt;SharedBytes&lt;/code&gt; on this synthetic benchmark 🫣. But of
course, my implementation does not offer the same versatility.&lt;/p&gt;
&lt;p&gt;I searched for public benchmarks that justified some design decisions on the &lt;code&gt;bytes&lt;/code&gt; crate, but could not find them. If
you know any, please tell me!&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;end-of-page&quot;&gt;&lt;/a&gt;&lt;/p&gt;
</content></entry><entry><title>Web server auto-reload in Rust</title><id>76221558-958b-4072-afa3-3e602f92ac9a</id><updated>2026-02-14T00:00:00+00:00</updated><author><name>sitegui</name></author><category term="programming"/><category term="rust"/><category term="axum"/><link href="https://sitegui.dev/post/2026/web-server-auto-reload-in-rust" rel="alternate"/><published>2026-02-14T00:00:00+00:00</published><content xml:base="https://sitegui.dev/post/2026/web-server-auto-reload-in-rust" type="html">&lt;p&gt;This blog is written in Rust, and I wanted a way to reload the web pages automatically while I change the posts&apos;
contents, styles, etc. This is common-place with JavaScript frameworks, but not automatic in the Rust land. So I&apos;ve
embarked on a side quest to achieve just that: the &amp;quot;type and auto-reload&amp;quot; experience. In the end, I was surprised to
learn a bit more about sockets and processes in Linux.&lt;/p&gt;
&lt;p&gt;This post is a note to myself about these nuggets that I&apos;ve learned and to share the solution. It may be helpful for
future me and I hope for someonelse out there.&lt;/p&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;You can check the solution
here:  &lt;a href=&quot;https://git.sitegui.dev/sitegui/axum-web-auto-reload-example/src/branch/main/src/main.rs&quot;&gt;https://git.sitegui.dev/sitegui/axum-web-auto-reload-example/src/branch/main/src/main.rs&lt;/a&gt;. The README in that
repo has some nice diagrams as well.&lt;/p&gt;
&lt;h2&gt;Shopping list&lt;/h2&gt;
&lt;p&gt;&lt;a name=&quot;continue-reading&quot; class=&quot;continue-reading&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To reload the browser page on a source file change, you will need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;your server: I&apos;m developing mine with &lt;a href=&quot;https://docs.rs/axum/latest/axum/&quot;&gt;axum&lt;/a&gt; in Rust&lt;/li&gt;
&lt;li&gt;a tool to listen to a port, pass down the socket to the server, detect file changes, and restart the server. I&apos;m using
&lt;a href=&quot;https://github.com/watchexec/watchexec&quot;&gt;&lt;code&gt;watchexec&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;a browser&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To run it all, I use this command:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;watchexec \
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;  --socket 8080 \
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;  --restart \
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;  --stop-signal SIGINT -- \
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;  cargo run
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Accepting the passed socket&lt;/h2&gt;
&lt;p&gt;This part is very important for smooth reloads: when the browser reloads, it will try to restablish a connection with
your server. However, at the same time your server is reloading and probably not yet available on the localhost
port, causing the browser to fail immediately with a passive-aggressive message telling it was ghostest by its dearest
friend localhost.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/watchexec/watchexec/blob/main/doc/socket.md&quot;&gt;The solution is a bit complex but quite brilliant&lt;/a&gt;:
let&apos;s leave the socket connection to the &lt;code&gt;watchexec&lt;/code&gt; process, which will stay alive through the session. When the
browser tries to connect, the connection will not fail immediately because no process was listening. Of course,
&lt;code&gt;watchexec&lt;/code&gt; has no idea what to do with that incomming connection: it is &lt;em&gt;your&lt;/em&gt; server that knows. So &lt;code&gt;watchexec&lt;/code&gt; spawns
your server and pass it the socket, so that it can do its serverly stuff, like accepting connections and spitting HTML
or whatever. To &amp;quot;pass the socket&amp;quot;, &lt;code&gt;watchexec&lt;/code&gt; uses two environment variables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;LISTEN_FDS&lt;/code&gt;: the number of sockets being passed&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LISTEN_FDS_FIRST_FD&lt;/code&gt;: the file-descriptor id of the first socket being passed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The sockets are created with &lt;code&gt;ReuseAddr&lt;/code&gt; and &lt;code&gt;ReusePort&lt;/code&gt; so that the server can listen to it again.&lt;/p&gt;
&lt;p&gt;To make it work, your server should detect that it is called by something like &lt;code&gt;watchexec&lt;/code&gt; and that it has received a
socket. I&apos;m using the crate &lt;a href=&quot;https://crates.io/crates/listenfd&quot;&gt;&lt;code&gt;listenfd&lt;/code&gt;&lt;/a&gt; to help with that:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;listenfd::ListenFd;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;std::error::Error;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;tokio::net::TcpListener;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;#[&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;tokio&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#f2777a;&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;]
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;async &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;// Use the crate `listenfd` to get the socket passed by `watchexec`
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt; inherited_socket = ListenFd::from_env().&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;take_tcp_listener&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;)?;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(auto_refresh, listener) = &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;if let &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;Some(inherited_socket) = inherited_socket {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        println!(&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#99cc99;&quot;&gt;Listening on inherit socket&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;quot;);
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        inherited_socket.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;set_nonblocking&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;)?; &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;// required by TcpListener::from_std()
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        (&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;, TcpListener::from_std(inherited_socket)?)
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;else &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;// Fallback to the typical way of listening to a new port
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt; listener = TcpListener::bind((&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#99cc99;&quot;&gt;127.0.0.1&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;quot;, &lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;8000&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;)).await?;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        println!(&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#99cc99;&quot;&gt;Listening on http://&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;{}&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;quot;, listener.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;local_addr&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;()?);
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        (&lt;/span&gt;&lt;span style=&quot;color:#f99157;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;, listener)
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    };
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Add a page script to reload&lt;/h2&gt;
&lt;p&gt;When &lt;code&gt;auto_refresh&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt; in the code above, it means that we&apos;re in &amp;quot;let&apos;s reload guys!&amp;quot; territory.&lt;/p&gt;
&lt;p&gt;In my server, I&apos;m using &lt;a href=&quot;https://crates.io/crates/minijinja&quot;&gt;&lt;code&gt;minijinja&lt;/code&gt;&lt;/a&gt; to render Jinja2 templates, so I do something
like this:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-jinja&quot;&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{% if AUTO_REFRESH %}
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;lt;script&amp;gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;  // Connect to the server and reload when a new message is received
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;  const eventSource = new EventSource(`/auto_refresh`)
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;  eventSource.addEventListener(&amp;quot;message&amp;quot;, () =&amp;gt; location.reload())
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;lt;/script&amp;gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{% endif %}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and in my main:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;() {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    jinja_env.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;add_global&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#99cc99;&quot;&gt;AUTO_REFRESH&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;quot;, auto_refresh);
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To tell that the browser should reload, I&apos;m
using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events&quot;&gt;server-sent events (SSE)&lt;/a&gt;
which are pretty cool in fact! My use case here is very simple: whenever the server sends an event, reload.&lt;/p&gt;
&lt;h2&gt;Please call me&lt;/h2&gt;
&lt;p&gt;The last piece of the puzzle is to implement the &lt;code&gt;/auto_refresh&lt;/code&gt; SSE endpoint in the server:&lt;/p&gt;
&lt;pre style=&quot;background-color:#2d2d2d;&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;axum::response::sse::{Event, KeepAlive};
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;axum::response::Sse;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;std::convert::Infallible;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;tokio::signal;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;tokio::sync::mpsc;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;tokio_stream::Stream;
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;use &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;tokio_stream::wrappers::UnboundedReceiverStream;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;/// Create a server-sent event stream that will send a single &amp;quot;goodbye&amp;quot; event when the server is
&lt;/span&gt;&lt;span style=&quot;color:#747369;&quot;&gt;/// stopped.
&lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt; async &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;get_auto_refresh&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;() -&amp;gt; Sse&amp;lt;impl Stream&amp;lt;Item=Result&amp;lt;Event, Infallible&amp;gt;&amp;gt;&amp;gt; {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    println!(&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#99cc99;&quot;&gt;GET /auto_refresh&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;quot;);
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(tx, rx) = mpsc::unbounded_channel();
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    tokio::spawn(async &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;move &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;{
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;wait_ctrl_c&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;().await;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        println!(&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#99cc99;&quot;&gt;SSE: sending goodbye&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;quot;);
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt; event = Event::default().&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#99cc99;&quot;&gt;goodbye&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;&amp;quot;);
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;_ = tx.&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;send&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(Ok(event));
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    });
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    Sse::new(UnboundedReceiverStream::new(rx)).&lt;/span&gt;&lt;span style=&quot;color:#66cccc;&quot;&gt;keep_alive&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;(KeepAlive::new())
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;async &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;fn &lt;/span&gt;&lt;span style=&quot;color:#6699cc;&quot;&gt;wait_ctrl_c&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;() {
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color:#cc99cc;&quot;&gt;let &lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;_ = signal::ctrl_c().await;
&lt;/span&gt;&lt;span style=&quot;color:#d3d0c8;&quot;&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that&apos;s it! For sure, the JavaScript ecosystem has perfected this integration of different pieces into a better
experience, but now I can enjoy it also. Maybe as a next step I can package all the different pieces into a single
crate?&lt;/p&gt;
</content></entry><entry><title>The 15-game blew my mind</title><id>7a0ba4ae-54da-4400-9940-28ff4ae721fb</id><updated>2026-02-11T00:00:00+00:00</updated><author><name>sitegui</name></author><category term="maths"/><link href="https://sitegui.dev/post/2026/the-15-game-blew-my-mind" rel="alternate"/><published>2026-02-11T00:00:00+00:00</published><content xml:base="https://sitegui.dev/post/2026/the-15-game-blew-my-mind" type="html">&lt;p&gt;I&apos;ve just watched the calmly titled &lt;a href=&quot;https://www.youtube.com/watch?v=UafhPUOCM1E&quot;&gt;&amp;quot;The 15-game&amp;quot;&lt;/a&gt; in the Numberphile
Youtube channel and boy oh boy, I cannot stop thinking about it!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/the-15-game-blew-my-mind.png&quot; alt=&quot;The video thumbnail&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I will not spoil the end, but if you ever got intrigued by games, maths, brain-teasers, just take a 15-minute break and
watch it. At school, I loved to solve the same problem from different angles, not only to increase my chances of getting
the good answer, but also because it was fun. This video hit right there in my heart.&lt;/p&gt;
&lt;p&gt;One of my first programs was a game of &lt;span style=&quot;color:black;background-color:black&quot;&gt;tic-tac-toe&lt;/span&gt;. If only
someone had shown me the 15-game back then!&lt;/p&gt;
&lt;p&gt;I choose 5. Your turn!&lt;/p&gt;
</content></entry><entry><title>Welcome Framework Laptop</title><id>23c517d2-1021-4df4-bb6a-d9ba95f8f649</id><updated>2026-01-29T00:00:00+00:00</updated><author><name>sitegui</name></author><category term="hardware"/><link href="https://sitegui.dev/post/2026/welcome-framework" rel="alternate"/><published>2026-01-29T00:00:00+00:00</published><content xml:base="https://sitegui.dev/post/2026/welcome-framework" type="html">&lt;p&gt;Around 3 years ago my phone&apos;s screen broke and changing the screen would cost close to a half the device&apos;s original
price. It was cheaper to throw away and buy a new one.&lt;/p&gt;
&lt;p&gt;This is clearly wasteful, but I guess this is a typical experience with well-known consumer brands.
But hey, I don&apos;t want to move to a new home because my sink broke!&lt;/p&gt;
&lt;p&gt;In Europe, new regulations
like &lt;a href=&quot;https://commission.europa.eu/law/law-topic/consumer-protection-law/directive-repair-goods_en&quot;&gt;Right-to-Repair Directive&lt;/a&gt;
represent a smart step to force the hand of manufacturers. It requires them, for example, to keep spare parts stocked
for at least 10 years. In France, I always check
the &lt;a href=&quot;https://www.ecologie.gouv.fr/politiques-publiques/indice-reparabilite&quot;&gt;repairability index&lt;/a&gt; before buying. I&apos;m more
than willing to pay a bonus price for good product design and engineering, that respects the resources and costumers.&lt;/p&gt;
&lt;p&gt;So I&apos;ve begrudgingly replaced my phone. But this time I wanted to break the wasteful cycle, so I&apos;ve
bought &lt;a href=&quot;https://www.fairphone.com/&quot;&gt;a Fairphone&lt;/a&gt;, which promises 10 year software and hardware support. Also, if
something breaks I can just order a replacement and repair it myself. So far, I&apos;m pretty happy with the experience! It
works, it just does. I feel soon I&apos;ll replace my battery, and that&apos;s it: it will probably stick with me a bunch more
years.&lt;/p&gt;
&lt;p&gt;Since my old laptop became my home server, I needed a new one for hacking on the loose. Following a similar strategy,
I&apos;m going with
&lt;a href=&quot;https://frame.work/&quot;&gt;Framework&lt;/a&gt; for my new rig.&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;continue-reading&quot; class=&quot;continue-reading&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;They send the machine in a very simple DIY kit. It&apos;s a bit too easy for those used to tinker: snap, screw, click, boom!
But it&apos;s a genius brand
move to prove less experienced people that they can do it too.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/welcome-framework-2.jpg&quot; alt=&quot;Framework DYI laptop in fragments&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The final result is pretty good. Come back in 3 years and I&apos;ll share my thoughts.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/welcome-framework-3.jpg&quot; alt=&quot;Framework 13 laptop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: smaller&quot;&gt;sent from my framework&lt;/span&gt;&lt;/p&gt;
</content></entry><entry><title>Nice people don&apos;t play board games for 27 straight hours</title><id>6f2ab63e-a870-4a63-91f1-e79352a15c11</id><updated>2026-01-22T00:00:00+00:00</updated><author><name>sitegui</name></author><category term="boardgame"/><link href="https://sitegui.dev/post/2026/28h-board-games" rel="alternate"/><published>2026-01-22T00:00:00+00:00</published><content xml:base="https://sitegui.dev/post/2026/28h-board-games" type="html">&lt;p&gt;They play for &lt;strong&gt;28&lt;/strong&gt; hours! We did it and it was pretty cool o/&lt;/p&gt;
&lt;p&gt;Well... not all those hours were spent actually playing, we also had to decide what to play next! With more than 500
games available at the event, this sometimes took a while :)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/28h-board-games-2.jpeg&quot; alt=&quot;a display with lots of board games&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can picture 3 rooms like the one below, full of meeples, cards, coins and fun.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sitegui.dev/post/2026/28h-board-games-1.jpeg&quot; alt=&quot;a room full of people playing board games&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;continue-reading&quot; class=&quot;continue-reading&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It was the 16th edition of the festival &lt;em&gt;24h Chaud les Jeux!&lt;/em&gt; in &lt;a href=&quot;https://www.cholet.fr/&quot;&gt;Cholet&lt;/a&gt;.
The festival name (and the association behind it) is a well-chosen self-referential pun! It translates to something like
&amp;quot;hot for games&amp;quot;, and the &lt;em&gt;chaud les&lt;/em&gt; sounds exactly the same as the city&apos;s name. French people, especially &lt;a href=&quot;https://tif.hair/&quot;&gt;hairdressing
owners&lt;/a&gt;, love their &lt;em&gt;jeu de mots&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The festival is made not only for hardcore gamers: it&apos;s open for anyone that passes by. I always find it heart-warming
to see friends and family sitting around, just enjoying their company on a Sunday afternoon, while they fight furiously
for the control of Tokyo, or accuse each other of being a Moriarty malfeasant ready to explode the Big Ben, or just
casually arranging their azulejos the best they can.&lt;/p&gt;
&lt;p&gt;For my part, I&apos;ve managed to discover 9 new games and play other 2 that I already knew. The big ones were Endeavor: age
of sail, Coming of age, Nemesis. I like them and would happily play another time.&lt;/p&gt;
&lt;p&gt;Playing Nemesis for the first time at 08:00 was a difficult task hhaha! After 3 hours, we all exploded in space before
coming back to Earth because one of the players decided that it HAD to auto-destroy the spaceship in order to content
their desire for chaos! It was a nice play though, we were all dead and happy (and ready
for lunch).&lt;/p&gt;
&lt;p&gt;We made good choices of lighter party games to cool down: Decrypto, Nosferatu and Cabanga!.&lt;/p&gt;
&lt;p&gt;A big Thank You! for the game club &lt;a href=&quot;https://sectionjeuxasptt.wordpress.com/&quot;&gt;Chaud les jeux&lt;/a&gt; for all the time and effort
you&apos;ve put into this event. I&apos;ll be happy to see you again next time.&lt;/p&gt;
</content></entry><entry><title>Hello world 2026</title><id>e654d01f-b5f6-49c8-9417-f09b06d011a2</id><updated>2026-01-01T00:00:00+00:00</updated><author><name>sitegui</name></author><link href="https://sitegui.dev/post/2026/hello-world-2026" rel="alternate"/><published>2026-01-01T00:00:00+00:00</published><content xml:base="https://sitegui.dev/post/2026/hello-world-2026" type="html">&lt;p&gt;&lt;a href=&quot;https://web.archive.org/web/20110715000000*/sitegui.com.br/blog&quot;&gt;I used to blog as a kid back in the 2010s&lt;/a&gt;, and for a
long time I wanted to get back to it. Now it&apos;s the time! This is my personal space on the web, it&apos;s not the shiniest,
not the most visited, but it is mine :)&lt;/p&gt;
&lt;p&gt;For now there isn&apos;t much to see here, this first post is mostly a hack to get me going.&lt;/p&gt;
&lt;p class=&quot;fun&quot;&gt;See you next time!&lt;/p&gt;
</content></entry></feed>