<?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: Anoop Singh</title>
    <description>The latest articles on DEV Community by Anoop Singh (@anoop_singh_).</description>
    <link>https://dev.to/anoop_singh_</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%2F4045908%2F9329ac37-adc1-4b8f-85b1-ff8687bc2bef.jpg</url>
      <title>DEV Community: Anoop Singh</title>
      <link>https://dev.to/anoop_singh_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anoop_singh_"/>
    <language>en</language>
    <item>
      <title>Smashed a 2.9GB Memory Monster: On-Device AI Optimization to &lt;400MB</title>
      <dc:creator>Anoop Singh</dc:creator>
      <pubDate>Sat, 25 Jul 2026 05:27:26 +0000</pubDate>
      <link>https://dev.to/anoop_singh_/smashed-a-29gb-memory-monster-on-device-ai-optimization-to-400mb-484l</link>
      <guid>https://dev.to/anoop_singh_/smashed-a-29gb-memory-monster-on-device-ai-optimization-to-400mb-484l</guid>
      <description>&lt;p&gt;When I started building &lt;strong&gt;Nirvana Browser&lt;/strong&gt;, my goal was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create an offline, privacy-first AI browser where every security decision happens locally—without sending user data to the cloud.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The vision was exciting.&lt;/p&gt;

&lt;p&gt;The implementation... wasn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;My first prototype relied on running &lt;strong&gt;PyTorch models&lt;/strong&gt; directly inside the desktop application.&lt;/p&gt;

&lt;p&gt;Although it worked, it introduced three major problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;Huge installer size&lt;/strong&gt; — nearly &lt;strong&gt;2.9GB&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;High RAM consumption&lt;/strong&gt; during local inference&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;Renderer freezes&lt;/strong&gt; caused by unhandled exceptions during domain security evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a desktop browser, these issues were unacceptable.&lt;/p&gt;

&lt;p&gt;Users expect applications to launch instantly, consume minimal resources, and remain responsive. Shipping a multi-gigabyte installer simply wasn't an option.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Optimization Strategy
&lt;/h1&gt;

&lt;p&gt;Rather than making incremental improvements, I redesigned the inference pipeline from the ground up&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Replacing PyTorch with ONNX Runtime
&lt;/h2&gt;

&lt;p&gt;The biggest optimization came from removing the heavy Python runtime from production.&lt;/p&gt;

&lt;p&gt;Instead of bundling PyTorch, I converted the inference models to &lt;strong&gt;ONNX Runtime&lt;/strong&gt; and optimized them for deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch.onnx&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;convert_to_onnx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dummy_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;export_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onnx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;dummy_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;export_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;export_params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;opset_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;do_constant_folding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;input_names&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;output_names&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&lt;/span&gt;&lt;span class="sh"&gt;"&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;After conversion, the models were further optimized through quantization to reduce memory usage and improve inference efficiency.&lt;/p&gt;

&lt;p&gt;The result was a dramatically smaller deployment footprint and significantly faster startup time.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Replacing Large Domain Lists with a Smart Rule Engine
&lt;/h2&gt;

&lt;p&gt;Initially, I experimented with maintaining a large database of malicious domains.&lt;/p&gt;

&lt;p&gt;While functional, loading massive datasets into memory created unnecessary overhead.&lt;/p&gt;

&lt;p&gt;Instead, I designed a lightweight &lt;strong&gt;pattern-based filtering engine&lt;/strong&gt; inside &lt;code&gt;safe.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rather than storing every possible malicious domain, the engine evaluates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Suspicious keyword patterns&lt;/li&gt;
&lt;li&gt;High-risk domain structures&lt;/li&gt;
&lt;li&gt;Content-based indicators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows the browser to identify potentially dangerous domains using constant-time lookup logic while keeping memory usage low.&lt;/p&gt;

&lt;p&gt;Instead of scaling with dataset size, the filtering process remains lightweight and predictable.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Monitoring Runtime Stability with Sentry
&lt;/h2&gt;

&lt;p&gt;Optimization isn't only about speed.&lt;/p&gt;

&lt;p&gt;Reliability matters just as much.&lt;/p&gt;

&lt;p&gt;To identify crashes and unexpected execution paths during testing, I integrated &lt;strong&gt;Sentry&lt;/strong&gt; for runtime monitoring.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sentry_sdk&lt;/span&gt;

&lt;span class="n"&gt;sentry_sdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;dsn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_SENTRY_DSN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;traces_sample_rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;profiles_sample_rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&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;This helped surface latency spikes, renderer exceptions, and asynchronous failures that were difficult to reproduce locally.&lt;/p&gt;

&lt;p&gt;Fixing these edge cases noticeably improved browser stability.&lt;/p&gt;




&lt;h1&gt;
  
  
  Key Takeaways
&lt;/h1&gt;

&lt;p&gt;This project reinforced several engineering lessons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quantization Matters
&lt;/h3&gt;

&lt;p&gt;Production applications don't always need heavyweight machine learning frameworks.&lt;/p&gt;

&lt;p&gt;Optimized ONNX Runtime deployments can provide excellent performance while dramatically reducing application size.&lt;/p&gt;

&lt;h3&gt;
  
  
  Algorithms Beat Raw Data
&lt;/h3&gt;

&lt;p&gt;A carefully designed rule engine can often outperform loading massive static datasets into memory.&lt;/p&gt;

&lt;p&gt;Better algorithms frequently provide greater gains than simply adding more data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy Doesn't Have to Be Slow
&lt;/h3&gt;

&lt;p&gt;Building an offline-first AI browser showed me that local inference can be both private and performant when the deployment architecture is designed carefully.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;Performance optimization isn't about chasing benchmarks.&lt;/p&gt;

&lt;p&gt;It's about removing unnecessary complexity until the software feels effortless to use.&lt;/p&gt;

&lt;p&gt;Watching &lt;strong&gt;Nirvana Browser&lt;/strong&gt; evolve from a bloated prototype into a lightweight desktop application has been one of the most rewarding engineering experiences of this project.&lt;/p&gt;

&lt;p&gt;There are still many improvements ahead, but solving this optimization challenge fundamentally changed how I think about deploying AI on end-user devices.&lt;/p&gt;




&lt;h2&gt;
  
  
  Useful Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Microsoft Store&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apps.microsoft.com/detail/9mvcm5j0ldcx?ocid=webpdpshare" rel="noopener noreferrer"&gt;https://apps.microsoft.com/detail/9mvcm5j0ldcx?ocid=webpdpshare&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;*Built in public by Anoop Singh.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>bugsmash</category>
      <category>python</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
