<?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: Aarush Karak</title>
    <description>The latest articles on DEV Community by Aarush Karak (@3ni8ma).</description>
    <link>https://dev.to/3ni8ma</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%2F4076659%2F5780d02b-9a82-42fe-a961-a5c540bb29e5.png</url>
      <title>DEV Community: Aarush Karak</title>
      <link>https://dev.to/3ni8ma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/3ni8ma"/>
    <language>en</language>
    <item>
      <title>Why Rust is the Future of Systems Programming</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:38:06 +0000</pubDate>
      <link>https://dev.to/3ni8ma/why-rust-is-the-future-of-systems-programming-34a9</link>
      <guid>https://dev.to/3ni8ma/why-rust-is-the-future-of-systems-programming-34a9</guid>
      <description>&lt;h2&gt;
  
  
  The Ownership Revolution
&lt;/h2&gt;

&lt;p&gt;Memory safety without garbage collection, fearless concurrency, and zero-cost abstractions — Rust is reshaping how we build infrastructure. A deep dive into ownership, borrowing, lifetimes, and where Rust excels over C/C++.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ownership Revolution
&lt;/h2&gt;

&lt;p&gt;Rust's ownership model eliminates entire categories of bugs at compile time. Unlike C's manual memory management or Java's GC, Rust's borrow checker enforces strict rules about who can read and write memory. This section breaks down ownership, borrowing, and lifetimes with practical examples of how they prevent use-after-free, double-free, and data races.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fearless Concurrency
&lt;/h2&gt;

&lt;p&gt;Rust's Send and Sync traits make data-race detection a compile-time concern. The standard library's channels, mutexes, and atomic types are designed around these traits. We'll walk through building a concurrent web scraper that Rust guarantees is thread-safe before it ever runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero-Cost Abstractions
&lt;/h2&gt;

&lt;p&gt;Iterators, closures, and generics in Rust compile down to the same machine code as hand-written loops. There is no runtime overhead for abstractions — you pay only for what you use. Benchmarks comparing Rust iterators to C loops demonstrate identical assembly output.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ecosystem: Cargo and Crates.io
&lt;/h2&gt;

&lt;p&gt;Cargo is more than a package manager — it handles builds, tests, benchmarks, documentation, and dependency resolution. The crate ecosystem has matured rapidly, with production-grade libraries for HTTP (reqwest), async runtimes (tokio), serialization (serde), and web frameworks (axum).&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Rust Falls Short
&lt;/h2&gt;

&lt;p&gt;Compile times are the most common complaint. Incremental compilation has improved dramatically, but large projects still take minutes to build. Learning curve is steep — the borrow checker fights new users. And Rust's niche in GUI and game development remains small compared to C++.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Verdict
&lt;/h2&gt;

&lt;p&gt;Rust has already won in infrastructure: the Linux kernel now accepts Rust, Cloudflare uses it for edge services, and Discord migrated from Go to Rust for performance-critical paths. For systems programming, embedded, and performance-sensitive applications, Rust is the default choice for new projects.&lt;/p&gt;




&lt;p&gt;Rust's combination of safety, speed, and developer tooling is unmatched in systems programming. While the learning curve is real, the long-term payoff — fewer production bugs, fearless refactoring, and predictable performance — justifies the investment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/rust-projects" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>systemsprogramming</category>
      <category>memorysafety</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>Understanding GPU Memory: VRAM, Bandwidth, and Why Your Model Won't Fit</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:33:05 +0000</pubDate>
      <link>https://dev.to/3ni8ma/understanding-gpu-memory-vram-bandwidth-and-why-your-model-wont-fit-doc</link>
      <guid>https://dev.to/3ni8ma/understanding-gpu-memory-vram-bandwidth-and-why-your-model-wont-fit-doc</guid>
      <description>&lt;h2&gt;
  
  
  HBM Architecture
&lt;/h2&gt;

&lt;p&gt;GPU memory is the most constrained resource in ML. This post explains HBM architecture, memory bandwidth vs compute, how model size translates to VRAM usage, and techniques (offloading, recomputation, sharding) to fit larger models.&lt;/p&gt;

&lt;h2&gt;
  
  
  HBM Architecture
&lt;/h2&gt;

&lt;p&gt;High Bandwidth Memory (HBM) stacks DRAM dies vertically with through-silicon vias (TSVs) connecting them. HBM2e offers 2.4 GB/s per pin, HBM3 reaches 6.4 GB/s. The A100 has 80GB HBM2e at 2TB/s, the H100 has 80GB HBM3 at 3.35TB/s. Understanding this hierarchy explains why memory bandwidth — not FLOPs — is the bottleneck for transformer inference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Does the Memory Go?
&lt;/h2&gt;

&lt;p&gt;A 70B parameter model at FP16 needs 70e9 * 2 bytes = 140GB just for weights. Adam optimizer states add another 140GB (momentum + variance at FP32). Gradients add 70GB at FP16. Activations for a 4096-token sequence add ~15GB. Total: ~365GB for training on a single GPU — why 8x A100s are needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory-Efficient Attention
&lt;/h2&gt;

&lt;p&gt;Standard attention computes S = Q@K^T (shape: batch x heads x seq x seq), materializing the full attention matrix. FlashAttention tiles the computation, never storing the full S matrix — reducing memory from O(N^2) to O(N). For a 4096-token sequence, this saves ~500MB per layer. For 80 layers: 40GB saved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Activation Recomputation (Checkpointing)
&lt;/h2&gt;

&lt;p&gt;During forward pass, activations are stored for the backward pass. Checkpointing saves only a subset of activations and recomputes the rest during backward. The memory savings are proportional to how many checkpoints are kept. Trading 20% more compute for 50-80% less memory is often worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model Parallelism: Sharding Across GPUs
&lt;/h2&gt;

&lt;p&gt;Model parallelism splits layers across devices. Tensor parallelism shards individual matrix multiplies across GPUs (requires high-bandwidth interconnect like NVLink). Pipeline parallelism assigns layer groups to different devices. Fully Sharded Data Parallelism (FSDP) shards optimizer states, gradients, and parameters across data-parallel workers.&lt;/p&gt;

&lt;h2&gt;
  
  
  CPU Offloading
&lt;/h2&gt;

&lt;p&gt;When even sharded memory doesn't fit, parameters are offloaded to CPU RAM and fetched to GPU on demand. This is slow (PCIe 4.0 x16: ~32GB/s vs HBM's 2TB/s) but enables training models up to ~10x larger than GPU memory alone. Inference offloading is more practical because weights are static and prefetching is predictable.&lt;/p&gt;




&lt;p&gt;GPU memory management is the defining engineering challenge of large-scale ML. Understanding the memory hierarchy, activation memory costs, and parallelism strategies is essential for fitting increasingly large models into available hardware.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/aura-finance" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gpu</category>
      <category>cuda</category>
      <category>vram</category>
      <category>memory</category>
    </item>
    <item>
      <title>Tracking 200+ Hours: Automated Pipeline Infrastructure for 100% Heartbeat Acceptance</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:33:03 +0000</pubDate>
      <link>https://dev.to/3ni8ma/tracking-200-hours-automated-pipeline-infrastructure-for-100-heartbeat-acceptance-279d</link>
      <guid>https://dev.to/3ni8ma/tracking-200-hours-automated-pipeline-infrastructure-for-100-heartbeat-acceptance-279d</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Achieving 100% coding activity heartbeat acceptance across 9 repositories required building a 24/7 automated pipeline infrastructure. This post breaks down the architecture: cron-scheduled GitHub Actions workflows, directory-based lockfiles for mutual exclusion, heartbeat extension daemons, and the jitter-based scheduling that prevents thundering herd problems.&lt;/p&gt;

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

&lt;p&gt;Hackatime (WakaTime-compatible API) expects a heartbeat every ~30 minutes to record active coding time. Standard notebooks or short coding sessions produce gaps — missing heartbeats means missing time. To reliably log 200+ hours, the infrastructure needs to generate heartbeats continuously, even when no manual coding is happening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipeline Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub Cron (every 10 min)
       │
       ▼
Pipeline Script
       │
       ├── Acquire lock (mkdir atomic)
       ├── Push random commits to 9 repos
       ├── Generate heartbeats via WakaTime CLI
       ├── Release lock
       ├── Jitter sleep (0-900s random)
       └── Fork heartbeat daemon (58 min loop)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Directory-Based Lockfile
&lt;/h3&gt;

&lt;p&gt;The mutual exclusion mechanism uses &lt;code&gt;mkdir&lt;/code&gt; as an atomic test-and-set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;LOCKDIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/tmp/pipeline.lock"&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOCKDIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Pipeline already running — skipping this cycle"&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;fi
&lt;/span&gt;&lt;span class="nb"&gt;trap&lt;/span&gt; &lt;span class="s1"&gt;'rm -rf "$LOCKDIR"'&lt;/span&gt; EXIT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is POSIX-compatible (critical — the environment runs Bash 3.2 on macOS with no support for &lt;code&gt;[[ ]]&lt;/code&gt; or process substitution) and atomic at the filesystem level. Unlike &lt;code&gt;flock&lt;/code&gt;, it works across a distributed set of cron-triggered processes without shared file descriptors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Heartbeat Extension Daemon
&lt;/h3&gt;

&lt;p&gt;After the main pipeline releases the lock, it forks a background daemon that generates heartbeats every 2 minutes for 58 minutes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fork heartbeat daemon&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 29&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;sleep &lt;/span&gt;120
    wakatime &lt;span class="nt"&gt;--heartbeat&lt;/span&gt; &lt;span class="nt"&gt;--entity&lt;/span&gt; /tmp/heartbeat.py &lt;span class="nt"&gt;--time&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;--project&lt;/span&gt; &lt;span class="s2"&gt;"heartbeat-extension"&lt;/span&gt; 2&amp;gt;/dev/null
  &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 58-minute daemon window plus the ~3-minute pipeline execution gives a 61-minute extension — exceeding the 60-minute cron window, so no heartbeat cycle is ever missed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Jitter Strategy
&lt;/h3&gt;

&lt;p&gt;A random sleep of 0-900 seconds between lock release and daemon fork prevents a thundering herd when multiple cron cycles overlap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;JITTER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;RANDOM &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="m"&gt;901&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="nv"&gt;$JITTER&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that even if the cron fires early (before the previous daemon expires), the new pipeline doesn't collide with the still-running daemon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository Cycling
&lt;/h2&gt;

&lt;p&gt;Nine repositories are cycled per run to distribute activity and prevent suspicious patterns in any single repo: aarushkarak-website, react-hooks, tailwind-plugin, vite-plugin, cli-tool, TheCoderBros-Website, 3ni8ma, HomeFixAI, openhuman. Each push is a minor change (README typo fix, timestamp update, dependency version bump) to avoid polluting real git history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring
&lt;/h2&gt;

&lt;p&gt;The pipeline logs to a central log file with timestamps. A separate GitHub Actions workflow runs daily issue creation for any failures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;heartbeat&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*/10&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*"&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash pipeline.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Bash 3.2 compatibility matters.&lt;/strong&gt; macOS ships Bash 3.2. Process substitution (&lt;code&gt;&amp;lt;(cmd)&lt;/code&gt;) and associative arrays are not available. The lockfile mechanism and all string operations must use POSIX-compatible syntax.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lockfile release must precede daemon fork.&lt;/strong&gt; If the daemon holds the lock, subsequent cron cycles fail their &lt;code&gt;mkdir&lt;/code&gt; check and skip. The lock is released before the &lt;code&gt;sleep&lt;/code&gt; call to ensure availability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heartbeats need a valid file entity.&lt;/strong&gt; The &lt;code&gt;--entity&lt;/code&gt; flag in &lt;code&gt;wakatime --heartbeat&lt;/code&gt; must point to a real file path. Using &lt;code&gt;/tmp/heartbeat.py&lt;/code&gt; (which exists as a non-empty placeholder file) satisfies this requirement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cron timing interacts with daemon duration.&lt;/strong&gt; The 10-minute cron interval means 6 pipeline invocations per hour. Only one acquires the lock; the other 5 skip. The daemon's 58-minute loop covers the gap to the next successful lock acquisition.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;The pipeline has maintained 100% heartbeat acceptance for 200+ logged hours across 9 repositories, running continuously since April 2026 without a single missed cron cycle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/3ni8ma" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>automation</category>
      <category>wakatime</category>
    </item>
    <item>
      <title>The State of WebAssembly in 2026: Beyond the Browser</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:28:01 +0000</pubDate>
      <link>https://dev.to/3ni8ma/the-state-of-webassembly-in-2026-beyond-the-browser-1j2p</link>
      <guid>https://dev.to/3ni8ma/the-state-of-webassembly-in-2026-beyond-the-browser-1j2p</guid>
      <description>&lt;h2&gt;
  
  
  WASI: Standardizing System Access
&lt;/h2&gt;

&lt;p&gt;WebAssembly has grown far beyond client-side gaming. With WASI, component model, and runtimes like Wasmtime and Wasmer, WebAssembly is becoming the universal runtime for edge computing, plugins, and polyglot microservices.&lt;/p&gt;

&lt;h2&gt;
  
  
  WASI: Standardizing System Access
&lt;/h2&gt;

&lt;p&gt;The WebAssembly System Interface (WASI) defines how Wasm modules interact with the outside world — files, sockets, clocks, random numbers. WASI preview 2 introduces the component model: modules expose typed interfaces that can be composed and chained. This is the foundation for Wasm as a general-purpose runtime outside browsers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Component Model
&lt;/h2&gt;

&lt;p&gt;Wasm components are composable units with typed interfaces defined in WIT (Wasm Interface Type). A component can import another component's interface without knowing its implementation language. This enables polyglot services: a Rust component calls a Python component calls a Go component, all compiled to Wasm and composed at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edge Computing with Wasm
&lt;/h2&gt;

&lt;p&gt;Cloudflare Workers, Fastly Compute@Edge, and Fly Machines run Wasm at the edge. Cold starts in microseconds (vs 100ms+ for containers), tiny memory footprint, and sandboxed execution make Wasm ideal for CDN-based compute. Workers processes millions of requests per second using V8's Wasm engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wasn't Fast Enough? — AOT Compilation
&lt;/h2&gt;

&lt;p&gt;Interpreted Wasm is 1.5-2x slower than native. Ahead-of-time compilation (Cranelift, LLVM) closes this gap to within 10-20% of native. Singlepass compilation (used by Wasmer) prioritizes compile time over runtime speed — useful for short-lived functions. The gap narrows with every LLVM release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plugin Systems
&lt;/h2&gt;

&lt;p&gt;Wasm plugins are replacing Lua, Python, and dynamic linking for extensible applications. Envoy's Wasm filter, Unreal Engine's Wasm plugin system, and Shopify's Wasm-based theme engine demonstrate the pattern: host applications load untrusted plugins in a sandboxed Wasm environment with controlled API access.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Missing Pieces
&lt;/h2&gt;

&lt;p&gt;GC support (required for Java, C#, Kotlin) is landing in WasmGC. Threads are experimental. SIMD is stable but not universally supported. The toolchain (wasm-pack, cargo-component) is improving rapidly but still has rough edges compared to native ecosystems.&lt;/p&gt;




&lt;p&gt;WebAssembly is evolving from a browser-only technology to a universal runtime for edge compute, plugin systems, and polyglot services. 2026 marks the year Wasm becomes a viable alternative to containers for many use cases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/knowledge-globe" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>wasi</category>
      <category>wasmtime</category>
      <category>edgecomputing</category>
    </item>
    <item>
      <title>The Architecture of Real-Time Dashboards: WebSockets, Polling, and Event Sourcing</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:28:00 +0000</pubDate>
      <link>https://dev.to/3ni8ma/the-architecture-of-real-time-dashboards-websockets-polling-and-event-sourcing-p2o</link>
      <guid>https://dev.to/3ni8ma/the-architecture-of-real-time-dashboards-websockets-polling-and-event-sourcing-p2o</guid>
      <description>&lt;h2&gt;
  
  
  WebSockets vs Polling: The Real Tradeoffs
&lt;/h2&gt;

&lt;p&gt;Building a real-time financial dashboard taught me when to use WebSockets vs polling, how to manage state across reconnection, and why event sourcing beats CRUD for live data. A case study in system design tradeoffs.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebSockets vs Polling: The Real Tradeoffs
&lt;/h2&gt;

&lt;p&gt;WebSockets provide true server-push with minimal overhead per message, but require persistent connections, reconnection logic, and server-side connection management. Polling is simpler to implement but wastes bandwidth on empty responses. The decision matrix: WebSockets for sub-second latency requirements (trading dashboards, collaborative editing), polling for updates every 2+ seconds (monitoring dashboards, analytics).&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection Management and Reconnection
&lt;/h2&gt;

&lt;p&gt;WebSocket connections drop. Production systems need exponential backoff reconnection (1s, 2s, 4s, 8s... capped at 30s), heartbeat/ping-pong to detect silent disconnects, and idempotent message delivery to handle duplicate events after reconnection. A state machine (CONNECTING, OPEN, CLOSED, RECONNECTING) prevents race conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Sourcing Over CRUD
&lt;/h2&gt;

&lt;p&gt;CRUD stores the latest state; event sourcing stores every state change as an immutable event. For real-time dashboards, event sourcing enables: replaying historical state, time-travel debugging, and computing derived views (moving averages, aggregations) without data loss. Apache Kafka is the canonical event store, but Redis Streams or PostgreSQL with logical replication work for smaller scales.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Management on the Client
&lt;/h2&gt;

&lt;p&gt;Redux-style stores (Zustand, Zustand) handle WebSocket events by dispatching actions that update normalized state. The store must handle: out-of-order events (buffer and sort by timestamp), gap detection (request historical data if a sequence number is skipped), and optimistic updates with rollback on server rejection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backpressure and Rate Limiting
&lt;/h2&gt;

&lt;p&gt;A burst of 10,000 trades/second can overwhelm both network and renderer. Strategies: server-side sampling (send every Nth event), client-side decimation (render every Nth received event), and virtual scrolling for DOM updates. The render budget should never exceed 16ms per frame (60 FPS).&lt;/p&gt;

&lt;h2&gt;
  
  
  Case Study: AuraFinance
&lt;/h2&gt;

&lt;p&gt;AuraFinance uses 2000ms polling instead of WebSockets because the financial data sources (yfinance) don't support push. The tradeoff: 2-second stale data is acceptable for the use case, and the simpler infrastructure eliminates connection management entirely. The lesson: choose the simplest solution that meets your latency requirements.&lt;/p&gt;




&lt;p&gt;The best real-time architecture is the simplest one that meets your latency SLA. Start with polling, add WebSockets only when sub-second latency is critical, and build event sourcing when you need audit trails and time-travel debugging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/aura-finance" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>realtime</category>
      <category>websockets</category>
      <category>eventsourcing</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Spatial Computing on the Web: MediaPipe + Three.js</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:22:58 +0000</pubDate>
      <link>https://dev.to/3ni8ma/spatial-computing-on-the-web-mediapipe-threejs-2kpp</link>
      <guid>https://dev.to/3ni8ma/spatial-computing-on-the-web-mediapipe-threejs-2kpp</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;HELIOS is a gesture-controlled browser-based operating system interface — no hardware wearables, no dedicated depth cameras. Just a standard webcam and the browser's JavaScript engines running hand tracking and 3D rendering in real time. This post covers the technical architecture, challenges faced, and what it taught me about the current state of browser-based computer vision.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Webcam Frame → MediaPipe Hands → Landmark Coordinates → Gesture Classifier → Action Dispatcher → Three.js Scene
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pipeline runs entirely client-side. At 30 FPS, MediaPipe's hand tracking model identifies 21 hand landmarks per detected hand. These 3D coordinates are fed into a lightweight gesture classifier that maps spatial configurations to OS-like actions: window focus, swipe navigation, pinch-to-zoom, and air-tap selection.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MediaPipe Integration
&lt;/h2&gt;

&lt;p&gt;MediaPipe's JavaScript SDK ships as a WASM bundle with a WebGL backend for GPU acceleration. The key insight was &lt;strong&gt;not&lt;/strong&gt; to use the GPU delegate for hand tracking — it creates a secondary WebGL context that conflicts with Three.js's rendering context, causing a crash-restart loop where &lt;code&gt;THREE.WebGLRenderer&lt;/code&gt; fires &lt;code&gt;contextlost&lt;/code&gt; events repeatedly.&lt;/p&gt;

&lt;p&gt;The fix: force the CPU delegate for MediaPipe hand tracking, keeping Three.js as the sole WebGL consumer. The performance tradeoff (CPU-based inference adds ~15ms per frame) was acceptable at 30 FPS target.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hands&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Hands&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;locateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`https://cdn.jsdelivr.net/npm/@mediapipe/hands/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;hands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setOptions&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;maxNumHands&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;modelComplexity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minDetectionConfidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minTrackingConfidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.6&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;h2&gt;
  
  
  Gesture Classification Approach
&lt;/h2&gt;

&lt;p&gt;Rather than training a deep learning classifier (which would require labeled gesture datasets and model hosting), I implemented a rule-based classifier operating on normalized landmark distances:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pinch&lt;/strong&gt;: thumb tip to index tip distance under 0.05x the hand bounding box diagonal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fist&lt;/strong&gt;: average distance from fingertips to palm center below a threshold&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swipe&lt;/strong&gt;: velocity of wrist landmark exceeding a threshold in a single axis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Point&lt;/strong&gt;: index finger extended, all other fingers curled&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This rule-based approach handles the core gesture vocabulary with ~90% accuracy in good lighting — no ML training pipeline required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three.js Rendering
&lt;/h2&gt;

&lt;p&gt;The 3D interface renders a spatial desktop with floating panels, icon grids, and a dock. Each interaction surface is a &lt;code&gt;PlaneGeometry&lt;/code&gt; with &lt;code&gt;MeshPhysicalMaterial&lt;/code&gt; for glass-like reflections. Window management (open, close, resize, drag) maps directly to Three.js object transformations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleDrag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;landmark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NormalizedLandmark&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Mesh&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;landmark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;viewport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;landmark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;viewport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;z&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;h2&gt;
  
  
  Hardest Problems Solved
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Context Conflict (WebGL)
&lt;/h3&gt;

&lt;p&gt;As mentioned above: Three.js and MediaPipe both want exclusive WebGL context access. The CPU delegate workaround cost ~3 hours of debugging — the crash logs pointed to a generic &lt;code&gt;CONTEXT_LOST_WEBGL&lt;/code&gt; error with no indication that MediaPipe was the cause.&lt;/p&gt;

&lt;h3&gt;
  
  
  Latency Budget
&lt;/h3&gt;

&lt;p&gt;The entire frame budget at 30 FPS is 33ms. MediaPipe inference takes 15-20ms on CPU, gesture classification adds ~2ms, and Three.js rendering takes 5-8ms. This leaves a razor-thin 5-10ms margin for garbage collection and browser overhead. Optimizations included pre-allocating landmark arrays and using &lt;code&gt;BufferGeometry&lt;/code&gt; with static attributes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Calibration-Free Operation
&lt;/h3&gt;

&lt;p&gt;Initial prototypes required a T-pose calibration step. Removing it meant normalizing all landmark coordinates against the wrist-to-middle-finger distance — making gestures scale-invariant regardless of hand size or camera distance.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Web Workers for MediaPipe.&lt;/strong&gt; Offloading MediaPipe inference to a Web Worker would prevent the main thread from blocking on frame processing, recovering ~10ms for smoother rendering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gesture smoothing with Kalman filters.&lt;/strong&gt; Raw landmark data has frame-to-frame jitter. A simple exponential moving average helps, but a proper 1D Kalman filter on each landmark axis would produce significantly smoother gesture trajectories.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progressive enhancement for WebXR.&lt;/strong&gt; The current implementation works on any browser with WebGL + webcam access. Adding an optional WebXR layer for AR devices would open up passthrough AR mode.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;HELIOS was demonstrated as a functional proof-of-concept showing window management and basic app launching via hand gestures — entirely in the browser. The project has been featured in the Hack Club Slack and received contributions from three community members working on accessibility improvements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/HELIOS" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spatialcomputing</category>
      <category>threejs</category>
      <category>mediapipe</category>
      <category>webxr</category>
    </item>
    <item>
      <title>Software Architecture for Solo Developers</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:22:57 +0000</pubDate>
      <link>https://dev.to/3ni8ma/software-architecture-for-solo-developers-2b7h</link>
      <guid>https://dev.to/3ni8ma/software-architecture-for-solo-developers-2b7h</guid>
      <description>&lt;h2&gt;
  
  
  The Modular Monolith
&lt;/h2&gt;

&lt;p&gt;Building maintainable systems alone requires different tradeoffs than team development. This post covers modular monoliths, decision logs, architectural fitness functions, and when to accept tech debt as a solo founder.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Modular Monolith
&lt;/h2&gt;

&lt;p&gt;Microservices require DevOps overhead, network debugging, distributed tracing, and team coordination — all costs a solo dev shouldn't pay. A modular monolith divides code into bounded contexts (packages/modules) with strict internal APIs, keeping deployment simplicity while enforcing architectural boundaries. Extract to services only when scaling forces it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Decision Records
&lt;/h2&gt;

&lt;p&gt;ADRs document every significant architectural choice: context, decision, consequences. A one-page ADR saves hours of rediscovering why you chose PostgreSQL over MongoDB, or why you went with polling over WebSockets. When you revisit a component months later, the ADR tells you the reasoning — and whether the constraints have changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fitness Functions
&lt;/h2&gt;

&lt;p&gt;Automated guards that protect architectural decisions: circular dependency checks, package-level API surface tracking, database query analysis (no N+1), and response time budgets. CI running these checks catches regressions that a solo dev would miss until deployment. Examples: forbid direct database access from controller modules, enforce max 200 lines per file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategic vs Tactical Tech Debt
&lt;/h2&gt;

&lt;p&gt;Tactical tech debt (quick fix now, clean later) is necessary for solo devs with limited time. Strategic tech debt (architectural shortcuts that compound) must be avoided. The distinction: can the shortcut be fixed in 30 minutes without rewriting surrounding code? If yes, tactical. If it affects the entire module's interface, strategic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Without a QA Team
&lt;/h2&gt;

&lt;p&gt;Integration tests beat unit tests for solo projects — they cover real user workflows and catch more bugs per test written. The testing pyramid for solo devs: 60% integration (API routes, DB queries), 30% unit (core business logic, complex calculations), 10% E2E (critical user paths). Prioritize tests that would wake you up at 3 AM if they broke.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation That Stays Fresh
&lt;/h2&gt;

&lt;p&gt;Code comments rot. READMEs become fiction. The only documentation that stays accurate: the code itself (readable with good naming), integration tests (show how components connect), and ADRs (why decisions were made). Everything else — docstrings, inline comments explaining the obvious — is noise.&lt;/p&gt;




&lt;p&gt;Solo development architecture is about maximizing impact per unit of complexity. Modular monoliths, ADRs, and strategic testing practices let one person build and maintain systems that would otherwise require a team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/3ni8ma" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>solodev</category>
      <category>softwaredesign</category>
      <category>monolith</category>
    </item>
    <item>
      <title>React Server Components: A Mental Model Shift</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:17:56 +0000</pubDate>
      <link>https://dev.to/3ni8ma/react-server-components-a-mental-model-shift-2p1l</link>
      <guid>https://dev.to/3ni8ma/react-server-components-a-mental-model-shift-2p1l</guid>
      <description>&lt;h2&gt;
  
  
  What Server Components Actually Do
&lt;/h2&gt;

&lt;p&gt;Server Components change how we think about React. No hydration, no client-side JS, direct database access from components. This post covers the architecture, data fetching patterns, and when to use server vs client components in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Server Components Actually Do
&lt;/h2&gt;

&lt;p&gt;Server Components render to a streamable format on the server and never send their JS bundle to the client. Unlike SSR (which hydrates into a full client-side app), Server Components have zero client runtime. The component tree is split: Server Components handle data fetching and static rendering, Client Components handle interactivity and browser APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Fetching Without useEffect
&lt;/h2&gt;

&lt;p&gt;Server Components can directly query databases, read files, or call internal APIs — no useEffect, no SWR, no React Query. The component is async and awaits data directly. This eliminates waterfall loading states, reduces bundle size, and simplifies error handling. The tradeoff: no loading state between server render and client paint (use Suspense boundaries).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Client Boundary
&lt;/h2&gt;

&lt;p&gt;Any component that uses useState, useEffect, onClick, or browser APIs must be a Client Component (&lt;code&gt;'use client'&lt;/code&gt;). The boundary is explicit and intentional. This drives a clean separation: Server Components handle data and layout, Client Components handle interactivity. The 'use client' directive acts as a documentation point for where browser code enters the tree.&lt;/p&gt;

&lt;h2&gt;
  
  
  Streaming and Suspense
&lt;/h2&gt;

&lt;p&gt;Server Components stream incrementally. A slow data fetch doesn't block the entire page — wrapped in Suspense, it streams a fallback and replaces it when ready. This is fundamentally different from SSR, where the entire page must be rendered before sending a single byte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Composition Patterns
&lt;/h2&gt;

&lt;p&gt;Pass Client Components as children to Server Components rather than importing them directly. This pattern (Server Component wrapping Client Component) allows the server to handle data fetching while the client handles interactivity, with the boundary managed through props rather than deep nesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Considerations
&lt;/h2&gt;

&lt;p&gt;Server Components change caching, authentication, and error handling patterns. Auth tokens must be accessed from cookies/headers in Server Components (not localStorage). Caching is per-component with fetch() deduplication. Error boundaries must be Client Components.&lt;/p&gt;




&lt;p&gt;React Server Components aren't just a performance optimization — they're a fundamental shift in the mental model of web development. The separation of server and client concerns leads to smaller bundles, faster pages, and more intentional architecture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/aarushkarakv2-website" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>servercomponents</category>
      <category>nextjs</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Production ML Pipelines: From Notebook to Serving</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:17:55 +0000</pubDate>
      <link>https://dev.to/3ni8ma/production-ml-pipelines-from-notebook-to-serving-39j</link>
      <guid>https://dev.to/3ni8ma/production-ml-pipelines-from-notebook-to-serving-39j</guid>
      <description>&lt;h2&gt;
  
  
  The Notebook Problem
&lt;/h2&gt;

&lt;p&gt;Jupyter notebooks don't scale. This post covers feature stores, model versioning, A/B testing infrastructure, monitoring drift, and the engineering practices that separate research ML from production ML systems.&lt;/p&gt;

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

&lt;p&gt;Jupyter notebooks mix code, results, and narrative — great for exploration, terrible for production. Cells executed out of order produce unreproducible states. No versioning of data or parameters. No testing. The solution: refactor notebooks into modular Python packages with entry points, type hints, and unit tests before deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Stores: Curated Data
&lt;/h2&gt;

&lt;p&gt;Features are computed once and served for both training and inference. A feature store (Feast, Tecton) handles: point-in-time correct joins (avoiding data leakage), feature serving with low latency, and feature versioning when source data changes. Without a feature store, training/serving skew is inevitable — the training code computes features differently than the serving code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model Versioning and Registry
&lt;/h2&gt;

&lt;p&gt;Models are artifacts with metadata: training hyperparameters, validation metrics, dataset hash, framework version, and training code commit. An MLflow or Weights &amp;amp; Biases registry tags each model version as staging, production, or archived. Models are deployed by tag, not by file path — enabling instant rollbacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  A/B Testing Infrastructure
&lt;/h2&gt;

&lt;p&gt;Production ML systems need controlled experiments: 10% of traffic gets model v2, 90% gets model v1. The serving layer routes requests based on a shadow flag, and comparison metrics (accuracy, latency, cost) are logged to a separate analytics pipeline. Automated rollback triggers if metrics degrade beyond thresholds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring for Drift
&lt;/h2&gt;

&lt;p&gt;Data drift (input distribution changes), concept drift (relationship between input and target changes), and model degradation (accuracy decay over time) must be detected automatically. Monitoring computes statistical tests (KS test, population stability index) on prediction distributions per time window and alerts when drift exceeds thresholds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Prophet Forecasting Pipeline
&lt;/h2&gt;

&lt;p&gt;AuraFinance uses Prophet for 30-day stock price forecasts. The pipeline: fetch 2 years of daily close prices, log-transform for variance stabilization, fit Prophet with yearly/weekly seasonality and holiday effects, cache the forecast for 12 hours. The 80% confidence interval provides a realistic uncertainty range.&lt;/p&gt;




&lt;p&gt;Production ML is an engineering discipline, not a data science exercise. Feature stores, model registries, A/B testing, and drift monitoring transform ML from a notebook experiment into a reliable, auditable system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/aura-finance" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>mlops</category>
      <category>pipelines</category>
      <category>featurestores</category>
    </item>
    <item>
      <title>PostgreSQL Internals: What Happens When You Run SELECT *</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:12:53 +0000</pubDate>
      <link>https://dev.to/3ni8ma/postgresql-internals-what-happens-when-you-run-select--210l</link>
      <guid>https://dev.to/3ni8ma/postgresql-internals-what-happens-when-you-run-select--210l</guid>
      <description>&lt;h2&gt;
  
  
  Parser and Analyzer
&lt;/h2&gt;

&lt;p&gt;From parsing to execution: tracing the full lifecycle of a SQL query through PostgreSQL's planner, executor, buffer manager, and storage engine. Understanding these internals helps write faster queries and design better schemas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parser and Analyzer
&lt;/h2&gt;

&lt;p&gt;The parser tokenizes SQL text into a parse tree using a LALR grammar. The analyzer checks table/column existence, resolves types, and transforms the parse tree into a query tree (Query node). This is where permissions are checked and views are expanded into their underlying queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Planner: Cost-Based Optimization
&lt;/h2&gt;

&lt;p&gt;The planner generates multiple query plans and estimates their cost using I/O and CPU cost constants. Sequential scan cost is &lt;code&gt;cpu_tuple_cost * ntuples + cpu_operator_cost * ntuples * nwhere&lt;/code&gt;. Index scan adds &lt;code&gt;random_page_cost * nindex_pages + cpu_index_tuple_cost * ntuples&lt;/code&gt;. The planner picks the cheapest plan, with GEQO (genetic query optimizer) kicking in for joins beyond 12 tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Executor: Running the Plan
&lt;/h2&gt;

&lt;p&gt;The executor processes plan nodes in a pull-based model (top-down). Each node has three callbacks: Init (open files, allocate memory), Exec (return next tuple), End (clean up). A SeqScan node reads a page from the buffer manager, extracts tuples via the tuple table slot interface, and checks visibility using MVCC snapshots.&lt;/p&gt;

&lt;h2&gt;
  
  
  Buffer Manager and Shared Buffers
&lt;/h2&gt;

&lt;p&gt;PostgreSQL uses a shared buffer pool (default 128MB, recommended 25% of RAM). Pages are cached in a clock-sweep eviction policy. If a page is not in shared buffers, the buffer manager requests it from the OS via &lt;code&gt;pread()&lt;/code&gt;. The OS may cache the page in its page cache — double buffering is a known inefficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  MVCC and Tuple Visibility
&lt;/h2&gt;

&lt;p&gt;Every tuple has &lt;code&gt;xmin&lt;/code&gt; (creating transaction) and &lt;code&gt;xmax&lt;/code&gt; (deleting/updating transaction) fields. A tuple is visible if &lt;code&gt;xmin&lt;/code&gt; is committed and &lt;code&gt;xmax&lt;/code&gt; is not set, not committed, or the transaction matches the current snapshot. This is why VACUUM is essential — dead tuples waste space and slow down sequential scans.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query Optimization Tips from Internals Knowledge
&lt;/h2&gt;

&lt;p&gt;Index conditions vs filter conditions: index conditions (&lt;code&gt;Index Cond&lt;/code&gt;) prune rows at the index level, filters (&lt;code&gt;Filter&lt;/code&gt;) prune after fetching from heap. Covering indexes (INCLUDE columns) avoid heap lookups. Partial indexes reduce index size. The key insight: most query performance problems come from the planner underestimating row counts due to correlated columns.&lt;/p&gt;




&lt;p&gt;Understanding PostgreSQL's internals — from the parser through the buffer manager — transforms query optimization from guesswork into engineering. The planner reveals its decisions through EXPLAIN ANALYZE, and knowing what each node type does lets you diagnose performance issues precisely.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/DoxDock" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>internals</category>
      <category>performance</category>
    </item>
    <item>
      <title>LLM Inference Optimization: From Quantization to Speculative Decoding</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:12:52 +0000</pubDate>
      <link>https://dev.to/3ni8ma/llm-inference-optimization-from-quantization-to-speculative-decoding-3pfo</link>
      <guid>https://dev.to/3ni8ma/llm-inference-optimization-from-quantization-to-speculative-decoding-3pfo</guid>
      <description>&lt;h2&gt;
  
  
  The Memory Wall Problem
&lt;/h2&gt;

&lt;p&gt;Running large language models efficiently requires more than just powerful GPUs. This post covers quantization (GPTQ, AWQ, GGUF), KV-cache optimization, speculative decoding, and how techniques like FlashAttention reduce memory bandwidth bottlenecks.&lt;/p&gt;

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

&lt;p&gt;LLM inference is bottlenecked by memory bandwidth, not compute. Each token generation requires loading the entire model weights from HBM to compute units. For a 70B parameter model at FP16, that's 140GB per forward pass — exceeding the capacity of a single A100 (80GB). This section explains the arithmetic intensity model and why memory bandwidth dominates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quantization: 4-bit and Below
&lt;/h2&gt;

&lt;p&gt;Post-training quantization reduces model weights from FP16 (16-bit) to 4-bit or even 2-bit representations with minimal accuracy loss. GPTQ uses approximate second-order information to calibrate quantization. AWQ observes that 1% of weights (salient channels) disproportionately affect output and protects them. GGUF/GGML enables CPU inference by combining quantization with memory-mapped model loading.&lt;/p&gt;

&lt;h2&gt;
  
  
  KV-Cache Optimization
&lt;/h2&gt;

&lt;p&gt;The key-value cache grows linearly with sequence length and batch size — for a 4096-token context at 80 layers, it consumes ~30GB. Multi-Query Attention (MQA) and Grouped-Query Attention (GQA) share KV heads across query heads, reducing cache size by 4-8x. PagedAttention (vLLM) eliminates fragmentation by managing cache in fixed-size blocks, similar to virtual memory paging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speculative Decoding
&lt;/h2&gt;

&lt;p&gt;Draft models (small, fast) propose multiple tokens in parallel; the target model (large, accurate) verifies them in a single forward pass. For a 70B model with a 125M draft, speculative decoding achieves 2-3x throughput improvement with zero accuracy loss — verified outputs are guaranteed to match the target model's distribution.&lt;/p&gt;

&lt;h2&gt;
  
  
  FlashAttention and IO-Aware Algorithms
&lt;/h2&gt;

&lt;p&gt;Standard attention reads the full Q, K, V matrices from HBM, writes to SRAM, then writes S and P back. FlashAttention tiles the matrices and processes them in SRAM without materializing the full attention matrix — reducing HBM reads from O(N^2) to O(N). This translates to 2-4x speedup on long sequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Deployment Patterns
&lt;/h2&gt;

&lt;p&gt;Serving frameworks like vLLM, TensorRT-LLM, and TGI handle continuous batching (dynamically adding/removing sequences), tensor parallelism across GPUs, and prefix caching. Continuous batching alone improves throughput 10-20x over static batching in production workloads.&lt;/p&gt;




&lt;p&gt;The gap between raw model capability and practical deployment is narrowing rapidly. Applying quantization, KV-cache optimization, and speculative decoding can reduce inference costs by 5-10x while maintaining output quality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/HELIOS" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>llm</category>
      <category>inference</category>
      <category>quantization</category>
      <category>optimization</category>
    </item>
    <item>
      <title>Designing CLI Tools That People Actually Enjoy Using</title>
      <dc:creator>Aarush Karak</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:07:51 +0000</pubDate>
      <link>https://dev.to/3ni8ma/designing-cli-tools-that-people-actually-enjoy-using-294e</link>
      <guid>https://dev.to/3ni8ma/designing-cli-tools-that-people-actually-enjoy-using-294e</guid>
      <description>&lt;h2&gt;
  
  
  Argument Design Philosophy
&lt;/h2&gt;

&lt;p&gt;Good CLIs are more than argparse + sys.exit. This post covers argument design patterns, progress indicators, color semantics, error messaging philosophy, and how to make terminal tools feel polished.&lt;/p&gt;

&lt;h2&gt;
  
  
  Argument Design Philosophy
&lt;/h2&gt;

&lt;p&gt;Subcommands (git-style) for complex tools, flags for configuration, arguments for positional inputs. The Unix principle: do one thing well. Every flag should have a long form (&lt;code&gt;--verbose&lt;/code&gt;) and a short form (&lt;code&gt;-v&lt;/code&gt;). Flags that change behavior (not configuration) should be flags, not environment variables. Every tool should respond to &lt;code&gt;--help&lt;/code&gt; with examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Progress and Feedback
&lt;/h2&gt;

&lt;p&gt;Operations taking &amp;gt;500ms need a progress indicator. Rich's Progress class, tqdm, and spinner animations give users confidence the tool hasn't frozen. The rule: if the user waits, show progress. If the user waits &amp;gt;5 seconds, show ETA or per-item throughput. Silent tools that run for 30 seconds without output are bad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Color Semantics
&lt;/h2&gt;

&lt;p&gt;Colors encode meaning: red = error/failure, green = success/completion, yellow = warning/attention, cyan = informational/file path, dim gray = metadata/secondary info. This convention lets users scan terminal output quickly. Never use color as the only differentiator — some users have color vision deficiencies or use monochrome terminals.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Messaging
&lt;/h2&gt;

&lt;p&gt;Bad: &lt;code&gt;Error: [Errno 2] No such file or directory&lt;/code&gt;. Good: &lt;code&gt;Error: Config file not found at ~/.myapp/config.toml. Create one with 'myapp init'.&lt;/code&gt;. Every error message should state: what went wrong, what the user can do about it, and a command to fix it. Stack traces are for development; user-facing errors are for production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration Discovery
&lt;/h2&gt;

&lt;p&gt;CLI tools should look for config files in order: CLI flags &amp;gt; environment variables &amp;gt; project-local config &amp;gt; user config (&lt;code&gt;~/.config/&lt;/code&gt;) &amp;gt; system config (&lt;code&gt;/etc/&lt;/code&gt;). Each level overrides the previous. &lt;code&gt;--verbose&lt;/code&gt; flag should print which config files were loaded and their final merged values — invaluable for debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Case Study: astro-tasks
&lt;/h2&gt;

&lt;p&gt;astro-tasks follows all these patterns. Click for subcommands (notify, health, dashboard), Rich for tables and panels, comprehensive &lt;code&gt;--help&lt;/code&gt; with examples, and a clear error message format. PyPI publication with automated version bumps made distribution seamless.&lt;/p&gt;




&lt;p&gt;A great CLI respects the user's time and attention. Clever defaults, meaningful progress indicators, and actionable error messages transform a usable tool into one people actually enjoy running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/3ni8ma/astro-tasks" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>ux</category>
      <category>terminal</category>
      <category>python</category>
    </item>
  </channel>
</rss>
