<?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: Harihar Nautiyal</title>
    <description>The latest articles on DEV Community by Harihar Nautiyal (@hariharnautiyal).</description>
    <link>https://dev.to/hariharnautiyal</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%2F3653911%2F58e782fe-abd6-4ede-b293-4f5c8c2184fe.png</url>
      <title>DEV Community: Harihar Nautiyal</title>
      <link>https://dev.to/hariharnautiyal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hariharnautiyal"/>
    <language>en</language>
    <item>
      <title>Astrophage: Building a Two-Stage Random Forest Exoplanet Classifier in Rust</title>
      <dc:creator>Harihar Nautiyal</dc:creator>
      <pubDate>Mon, 29 Jun 2026 11:33:27 +0000</pubDate>
      <link>https://dev.to/hariharnautiyal/astrophage-building-a-two-stage-random-forest-exoplanet-classifier-in-rust-119e</link>
      <guid>https://dev.to/hariharnautiyal/astrophage-building-a-two-stage-random-forest-exoplanet-classifier-in-rust-119e</guid>
      <description>&lt;p&gt;A weeks ago my teammate and I decided to enter the AI for Astronomy Hackathon 2026. The task was to classify thousands of Kepler Objects of Interest as confirmed exoplanets, candidates or false positives.&lt;/p&gt;

&lt;p&gt;Most teams would use Python and scikit-learn. We did something. We built Astrophage, a custom Two-Stage Random Forest classifier written entirely in Rust. It uses Polars for data handling and a from-scratch machine learning implementation. Astrophage achieves 94.81% accuracy making it the accurate tabular-data model in the competition.&lt;/p&gt;

&lt;p&gt;Here is how we did it why two-stage classification works and what we learned about building machine learning systems in Rust.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Not Every Signal Is a Planet
&lt;/h2&gt;

&lt;p&gt;The Kepler space telescope found thousands of exoplanet candidates.. Most of them are not planets at all. They are binary star systems, instrumental noise or stellar variability. Every false wastes precious telescope time. Every missed candidate is a habitable world we never study. The classification problem is real. It is hard.&lt;/p&gt;

&lt;p&gt;The dataset gives you tabular features like periods, transit depths, signal-to-noise ratios, stellar temperatures and false positive flags. No images, no curves as pixels. Structured numbers that encode astrophysical reality.. That is where most machine learning approaches go wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Insight: Astronomers Do Not Think in Three Classes
&lt;/h2&gt;

&lt;p&gt;We noticed that NASA astronomers do not look at a Kepler Object of Interest and ask "is this confirmed, candidate or false positive?" all once. They think in stages. They ask "is this definitely a planet?" If the answer is yes it is confirmed. If not they ask "is it worth telescope time?" If the answer is yes it is a candidate. If not it is a positive.&lt;/p&gt;

&lt;p&gt;This is not a machine learning trick. It is literally how the science works. So we asked: what if our model did the thing?&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture: Two-Stage Random Forest
&lt;/h2&gt;

&lt;p&gt;Instead of a single 3-class classifier Astrophage uses two binary Random Forests in sequence. The first stage separates confirmed planets from not confirmed planets. The second stage separates candidates from positives.&lt;/p&gt;

&lt;p&gt;The improvement is 3-4% accuracy gain over a single-stage approach. That may not sound like much. In exoplanet discovery every percentage point represents hundreds of potential worlds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Rust?
&lt;/h2&gt;

&lt;p&gt;We wrote a Random Forest from scratch in Rust. Why did we do that when Python and scikit-learn exist? It started as a challenge. It ended as a solution.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Astrophage (Rust)&lt;/th&gt;
&lt;th&gt;sklearn (Python)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Inference&lt;/td&gt;
&lt;td&gt;~1ms/sample&lt;/td&gt;
&lt;td&gt;~10ms/sample&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Training&lt;/td&gt;
&lt;td&gt;~30 seconds&lt;/td&gt;
&lt;td&gt;~2 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binary size&lt;/td&gt;
&lt;td&gt;~2 MB&lt;/td&gt;
&lt;td&gt;~500 MB+ (with env)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime crashes&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;td&gt;Occasionally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory safety&lt;/td&gt;
&lt;td&gt;Compile-time guarantees&lt;/td&gt;
&lt;td&gt;Manual management&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The speed is not just nice to have. If you are classifying millions of Kepler Objects of Interest. Running real-time pipeline analysis, 10x faster inference matters.. The binary size? You could ship Astrophage on a Raspberry Pi if you wanted.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Feature Engineering: Where Astrophysics Meets Code
&lt;/h2&gt;

&lt;p&gt;We did not throw 28 raw features at a model. We spent time understanding what each number actually means physically then engineered 8 derived features that encode astrophysical intuition.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Star Feature: &lt;code&gt;fpflag_sum&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;NASA already flags signals with four binary indicators. We simply added them up. &lt;code&gt;Fpflag_sum&lt;/code&gt; has an importance score of 0.29. It alone explains a third of the models decision-making. When this value is non-zero the signal is certainly not a planet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Derived Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;snr_x_prad&lt;/code&gt;&lt;/strong&gt;. Signal-to-noise ratio × radius. Real planets have SNR to their size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;depth_duration_ratio&lt;/code&gt;&lt;/strong&gt;. Transit depth ÷ duration. Planets make Ushaped transits; binary stars make V-shaped eclipses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;impact_penalty&lt;/code&gt;&lt;/strong&gt;. If impact parameter &amp;gt; 1.0 the "planet" would miss the star entirely. Physically impossible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;log_period&lt;/code&gt;&lt;/strong&gt;. Orbital periods follow log- distributions, not normal ones. Taking the log makes the feature model-friendly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;koi_prad_squared&lt;/code&gt;&lt;/strong&gt;. Objects &amp;gt; 15 Earth radii are companions, not planets. Squaring creates a threshold.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every derived feature has a story. That is not accidental. It is the reason the model generalizes well.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accuracy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94.81%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Macro F1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;92.64%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Weighted F1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94.51%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Per-class breakdown:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Precision&lt;/th&gt;
&lt;th&gt;Recall&lt;/th&gt;
&lt;th&gt;F1-Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FALSE POSITIVE&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;99.69%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;98.35%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;99.01%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CONFIRMED&lt;/td&gt;
&lt;td&gt;89.95%&lt;/td&gt;
&lt;td&gt;94.54%&lt;/td&gt;
&lt;td&gt;92.18%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CANDIDATE&lt;/td&gt;
&lt;td&gt;88.42%&lt;/td&gt;
&lt;td&gt;85.06%&lt;/td&gt;
&lt;td&gt;86.71%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The false positive precision is nearly perfect because false positives often have flags. The candidate class is hardest. But that is by design. Candidates are supposed to be ambiguous.&lt;/p&gt;




&lt;h2&gt;
  
  
  What We Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Two-stage decomposition just works
&lt;/h3&gt;

&lt;p&gt;Breaking a 3-class problem into two easier binary ones sounds obvious in retrospect but most machine learning pipelines do not do it. The accuracy gain is real. The architecture mirrors actual scientific workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Domain knowledge beats compute
&lt;/h3&gt;

&lt;p&gt;36 well-designed features outperform 100 generic ones. Understanding why orbital periods are log-normal why impact parameters matter geometrically and why NASA flags exist was worth more than any hyperparameter tuning.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Rust is viable for machine learning
&lt;/h3&gt;

&lt;p&gt;Polars and NDArray can absolutely compete with Pythons ecosystem. The borrow checker is annoying for the week. Then you stop having memory bugs&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Stratified sampling saves you from yourself
&lt;/h3&gt;

&lt;p&gt;Without it our model would have learned "say false positive every time". Called it a day. The class distribution is that imbalanced.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Sometimes the best feature is already in the data
&lt;/h3&gt;

&lt;p&gt;We thought we would discover some interaction no one had found. Nope. NASAs pre-vetting flags aggregated simply were our move. The experts already knew what to look for.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;** term:** Hyperparameter grid search, K-fold cross-validation recursive feature elimination to find the optimal subset.&lt;/p&gt;

&lt;p&gt;** term:** Model serialization, a REST API for real-time classification, a web dashboard for interactive exploration.&lt;/p&gt;

&lt;p&gt;** term:** Direct NASA Exoplanet Archive integration extending to TESS and JWST data explanations for every prediction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The dream:&lt;/strong&gt; Astrophage becomes a tool in the exoplanet discovery pipeline. Helping astronomers prioritize telescope time identify the most promising candidates and find more worlds, like our own.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/harihar-nautiyal/astrophage" rel="noopener noreferrer"&gt;github.com/harihar-nautiyal/astrophage&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://astrophage.hariharnautiyal.com" rel="noopener noreferrer"&gt;astrophage.hariharnautiyal.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Google Colab:&lt;/strong&gt; Run it without installing Rust. &lt;a href="https://colab.research.google.com/github/harihar-nautiyal/astrophage/blob/main/Astrophage_Colab.ipynb" rel="noopener noreferrer"&gt;Notebook link&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/harihar-nautiyal/astrophage.git
&lt;span class="nb"&gt;cd &lt;/span&gt;astrophage
cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;
./target/release/astrophage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first build takes a minutes but subsequent runs are instant.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Somewhere something incredible is waiting to be known."&lt;/em&gt;. Carl Sagan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am really interested in machine learning that uses tables. I also like learning about planets outside our solar system. If you like these things too or if you just want to know more about using the programming language Rust for science I would love to hear what you think. You can write a comment. Tell me about a problem, on GitHub.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This was made using Rust, Polars, NDArray, Tokio and a lot of coffee.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>machinelearning</category>
      <category>exoplanets</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Stop Using Raw UUIDs: Type-Safe, Prefixed IDs in Rust (Stripe-style)</title>
      <dc:creator>Harihar Nautiyal</dc:creator>
      <pubDate>Wed, 24 Dec 2025 05:46:37 +0000</pubDate>
      <link>https://dev.to/hariharnautiyal/stop-using-raw-uuids-type-safe-prefixed-ids-in-rust-stripe-style-2a6h</link>
      <guid>https://dev.to/hariharnautiyal/stop-using-raw-uuids-type-safe-prefixed-ids-in-rust-stripe-style-2a6h</guid>
      <description>&lt;p&gt;We have all been there. You are staring at your server logs at 2 AM, trying to debug a request, and you see this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Processing request for ID: 550e8400-e29b-41d4-a716-446655440000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is that a &lt;strong&gt;User ID&lt;/strong&gt;? An &lt;strong&gt;Order ID&lt;/strong&gt;? An &lt;strong&gt;API Key&lt;/strong&gt;? Who knows. It’s just a blob of hex characters.&lt;/p&gt;

&lt;p&gt;Even worse, have you ever written a function like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;process_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you accidentally call &lt;code&gt;process_payment(order_id, user_id)&lt;/code&gt;, the compiler won’t stop you. They are both just &lt;code&gt;Uuid&lt;/code&gt;. You won't find out until your database throws a "Record not found" error—or worse, you corrupt data.&lt;/p&gt;

&lt;p&gt;I’ve always admired how &lt;strong&gt;Stripe&lt;/strong&gt; handles this. Their IDs look like &lt;code&gt;cus_018...&lt;/code&gt; or &lt;code&gt;ch_018...&lt;/code&gt;. They are self-describing and readable.&lt;/p&gt;

&lt;p&gt;I wanted that same experience in Rust, but with the compiler enforcing safety. So, I built &lt;strong&gt;&lt;a href="https://github.com/h01-team/puuid" rel="noopener noreferrer"&gt;puuid&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is puuid?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;puuid&lt;/code&gt; (Prefixed UUID) is a lightweight Rust crate that wraps the standard &lt;code&gt;uuid&lt;/code&gt; library. It gives you two main things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Readability:&lt;/strong&gt; IDs print as &lt;code&gt;"user_018c..."&lt;/code&gt; instead of just numbers.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Type Safety:&lt;/strong&gt; You cannot mix up a &lt;code&gt;UserId&lt;/code&gt; with an &lt;code&gt;OrderId&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;It’s surprisingly simple to set up. You define your prefixes once (usually in your &lt;code&gt;types.rs&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;puuid&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Puuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// 1. Define your prefixes&lt;/span&gt;
&lt;span class="nd"&gt;prefix!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;prefix!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ord"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Create strong types&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;UserId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Puuid&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;OrderId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Puuid&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, look at what happens when we try to make that mistake from earlier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;delete_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OrderId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deleting order: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_v7&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// ❌ COMPILE ERROR: expected OrderId, found UserId&lt;/span&gt;
    &lt;span class="nf"&gt;delete_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rust compiler now protects you from your own typos.&lt;/p&gt;

&lt;h2&gt;
  
  
  "But does it kill performance?"
&lt;/h2&gt;

&lt;p&gt;This was my main concern when building it. The answer is &lt;strong&gt;no&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Puuid&amp;lt;T&amp;gt;&lt;/code&gt; is a &lt;code&gt;#[repr(transparent)]&lt;/code&gt; wrapper around the standard &lt;code&gt;uuid::Uuid&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Memory:&lt;/strong&gt; It takes up the exact same space as a standard UUID (16 bytes).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Database:&lt;/strong&gt; You can insert it directly as a UUID type (via &lt;code&gt;.into_inner()&lt;/code&gt;) or store it as text if you want to keep the prefix visible.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Methods:&lt;/strong&gt; It implements &lt;code&gt;Deref&lt;/code&gt;, so you can still call &lt;code&gt;.as_bytes()&lt;/code&gt;, &lt;code&gt;.get_version()&lt;/code&gt;, or any other method from the standard &lt;code&gt;uuid&lt;/code&gt; crate.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Note on UUID v7
&lt;/h2&gt;

&lt;p&gt;By default, &lt;code&gt;puuid&lt;/code&gt; encourages &lt;strong&gt;UUID v7&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you haven't switched from v4 (random) to v7 yet, you should. v7 UUIDs are &lt;strong&gt;time-sortable&lt;/strong&gt;. This means that when you store them in a database, they naturally index according to time creation. It prevents index fragmentation and makes &lt;code&gt;INSERT&lt;/code&gt; performance much faster for large tables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_v7&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Output: user_018c6427-4f30-7f89-a1b2-c3d4e5f67890&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Serde is Magic
&lt;/h2&gt;

&lt;p&gt;If you are building a JSON API (with Axum, Actix, etc.), &lt;code&gt;puuid&lt;/code&gt; handles the serialization for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Serialize,&lt;/span&gt; &lt;span class="nd"&gt;Deserialize)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Checkout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OrderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a client sends this JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ord_018..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user_018..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works perfectly. But if they send a raw UUID or mix up the prefixes, the deserializer rejects it immediately with a validation error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it out
&lt;/h2&gt;

&lt;p&gt;I’d love to hear your thoughts on the API design. I’ve been using it in my own projects to clean up my logs and it has saved me from at least three "argument swap" bugs already.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crates.io:&lt;/strong&gt; &lt;a href="https://crates.io/crates/puuid" rel="noopener noreferrer"&gt;crates.io/crates/puuid&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href="https://h01.in/projects/puuid" rel="noopener noreferrer"&gt;h01.in/projects/puuid&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/h01-team/puuid" rel="noopener noreferrer"&gt;github.com/h01-team/puuid&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know what you think! 🦀&lt;/p&gt;

</description>
      <category>rust</category>
      <category>backend</category>
      <category>webdev</category>
      <category>database</category>
    </item>
    <item>
      <title>Why I chose Rust over Node.js for my Code Execution Backend</title>
      <dc:creator>Harihar Nautiyal</dc:creator>
      <pubDate>Tue, 09 Dec 2025 14:53:23 +0000</pubDate>
      <link>https://dev.to/hariharnautiyal/why-i-chose-rust-over-nodejs-for-my-code-execution-backend-hff</link>
      <guid>https://dev.to/hariharnautiyal/why-i-chose-rust-over-nodejs-for-my-code-execution-backend-hff</guid>
      <description>&lt;p&gt;I’m building a coding platform (Unifwe) where users run untrusted code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4899bfnft3utlpk754m0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4899bfnft3utlpk754m0.png" alt=" " width="800" height="539"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Problem: Running user code is dangerous. You need sandboxing. Node.js is great, but heavy for spinning up thousands of isolated instances.&lt;/p&gt;

&lt;p&gt;Why Rust? :&lt;br&gt;
    Memory safety (critical for sandboxes).&lt;br&gt;
    Performance (cold start times were 40000 ms faster).&lt;br&gt;
    WebAssembly potential.&lt;/p&gt;

&lt;p&gt;The Architecture: Briefly explain how your Next.js frontend sends code to the Rust API.&lt;/p&gt;

&lt;p&gt;It was hard to build, but the speed is worth it.&lt;/p&gt;

&lt;p&gt;if you want to test the speed of the engine, you can try the challenges here: &lt;a href="https://unifwe.h01.in/courses/7400777905099243520" rel="noopener noreferrer"&gt;Demo course&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqld0dfarwkpl3onnvbpx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqld0dfarwkpl3onnvbpx.png" alt="Course demo" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
