# Harshith Sunku > Software engineer who builds across the stack — CPU registers to UI, cloud, and AI. Happiest close to the metal. Deep dives on how things actually work. Personal site and technical blog of Harshith Sunku (Staff Engineer). Build anything, anywhere. From CPU registers to UI, cloud, and AI. Happiest close to the metal. Deep dives on how things actually work, at every layer — boot, kernels, networks, databases, the web, and AI — plus open-source projects from a bootloader to AI agent courses. Every post and project is also available as clean Markdown: drop the trailing slash and add `.md` (for example https://harshith.in/blog/.md). The links below point at those Markdown versions; each one names its HTML page on a `URL:` line. ## About - [About Harshith Sunku](https://harshith.in/about/): background, what I build, and how to get in touch - [Portrait of Harshith Sunku](https://harshith.in/harshith-sunku.jpg) - [GitHub](https://github.com/harshithsunku) - [LinkedIn](https://linkedin.com/in/harshithsunku) - [X](https://x.com/harshithsunku) ## Series - [Behind This Site](https://harshith.in/series/behind-this-site/): How this blog actually runs: the static build, the free hosting, the search index, the CI pipeline — every moving part, with real configs and real costs. - [The Homelab](https://harshith.in/series/homelab/): The lab exists to learn on. Every post is the same shape: a real problem I hit, what I tried, what actually worked, and what it taught me — Proxmox and ZFS, a fleet of bare-metal misfits, an AI coworker, and the small devices that keep it all recoverable. ## Projects - [SimpleSoftwareBasedTCPIPStack](https://harshith.in/projects/simple-software-based-tcp-ip-stack.md): A software TCP/IP stack built entirely in C — Ethernet framing, ARP resolution, IP routing, and TCP state machine via Linux TAP devices. Validates by fetching real HTTP content over the custom stack. - [ProxKey](https://harshith.in/projects/proxkey.md): Self-hosted SSH key manager for Proxmox — distributes public keys to LXC containers and QEMU VMs via the Proxmox API and pct/qm guest exec, with zero prior SSH access to the guest. Create a container, SSH in immediately. - [Learn Jev end to end](https://harshith.in/projects/learn-jev-end-to-end.md): A free, hands-on course on building AI agents with a fast brain and a slow brain — 12 short notebooks and 13 real use cases that put Jev, a decision model, inside an LLM agent loop. One API key; the whole course runs for under $0.20. - [PerfLens](https://harshith.in/projects/perflens.md): Remote Linux perf profiling with a real-time web UI. Drop a dependency-free agent on any ARM or x86 device, point it at a PID, and watch flame graphs, function tables, and line-level annotated source update live in the browser. - [mcp-gtags-server](https://harshith.in/projects/mcp-gtags-server.md): Indexed code navigation for AI coding agents — replaces full-tree grep scans with GNU Global (gtags) lookups over the Model Context Protocol. ~100× faster per query on kernel-scale codebases, with radically less context noise. - [callsight](https://harshith.in/projects/callsight.md): Exact per-call timing for the C/C++ code you choose — and zero cost for the code you don't. One config file picks what gets instrumented at compile time; everything else emits no hook at all. No source changes. - [Build Your First AI Agent](https://harshith.in/projects/build-your-first-ai-agent.md): A twelve-notebook course that builds an AI agent from scratch — a hand-rolled ~35-line agent loop, then RAG, MCP, structured outputs, memory, multi-agent orchestration, and evals layered on top. Works with any OpenAI-compatible provider. - [SimpleRealModeBootLoader](https://harshith.in/projects/simple-real-mode-bootloader.md): A minimalistic 16-bit real mode bootloader in x86 Assembly. Demonstrates BIOS interrupt interface, segment:offset addressing, disk sector loading via INT 0x13, and protected mode transition. - [SimpleMultiThreadedOS](https://harshith.in/projects/simple-multithreaded-os.md): An educational multithreaded OS in C demonstrating cooperative and preemptive scheduling, buddy allocator memory management, and message-queue IPC — built to expose the mechanics production kernels abstract away. - [ThreadSafeCLogger](https://harshith.in/projects/thread-safe-c-logger.md): A high-performance thread-safe logging library for C. Per-thread SPSC ring buffers drained by a background logger thread — zero mutex contention on the write path. 15× throughput improvement over naive mutex approach. - [ESP32-MQTT-WOL](https://harshith.in/projects/esp32-mqtt-wol.md): ESP32-based Wake-on-LAN trigger over MQTT. Sits on the LAN, subscribes to MQTT topics, and broadcasts WoL magic packets — built on ESP-IDF with FreeRTOS, lwIP, QoS 1, and hardware watchdog. - [GenericCShellParserLib](https://harshith.in/projects/generic-c-shell-parser-lib.md): A drop-in CLI parser library for C projects. Built-in commands (show, config, debug, clear) plus a registration API for custom commands. Supports tab completion and history via readline integration. - [GenericDLLLibrary](https://harshith.in/projects/generic-dll-library.md): A generic doubly linked list library for C with an integrated "glued type" pattern — one list implementation that any user-defined struct can join without casts or per-type code. - [GenericEmbeddableDoublyLinkedList](https://harshith.in/projects/generic-embeddable-doubly-linked-list.md): A memory-efficient intrusive doubly linked list library for C. Embedded directly in user-defined data structures — no separate allocation per node, O(1) insert/delete, and type-safe macros. - [LLM API Proxy](https://harshith.in/projects/llm-api-proxy.md): A unified proxy for OpenAI, Anthropic, Google Gemini, and Perplexity APIs. Single endpoint routes to the correct provider based on model name — swap providers without changing client code. ## Blog - [An AI Coworker in an LXC Container](https://harshith.in/blog/an-ai-coworker-in-an-lxc.md): A dedicated container on my Proxmox host runs a coding agent that writes, reviews, and ships changes to this site — through the same git-push pipeline I use. The interesting engineering isn't the model; it's the guardrails around it. - [Who's Allowed to Talk to What: Identity and Access in the Homelab](https://harshith.in/blog/homelab-identity-and-access.md): VLANs decide which networks can talk. They say nothing about which people can. Part 5 of the homelab series: a central identity service in its own VM, Tailscale as the front door, and why the break-glass path matters more than the lock. - [The Fleet: Six Machines, and What the Hypervisor Can't Do](https://harshith.in/blog/the-fleet-why-bare-metal-earns-its-keep.md): The plan was to consolidate everything onto one Proxmox box. Then a perf tool needed real PMU counters, a firmware flash needed a real serial port, and testing on ARM meant a phone running a custom kernel. Meet the fleet — and what each machine taught me. - [Waking the Lab: an ESP32, MQTT, and 102 Bytes](https://harshith.in/blog/waking-the-lab-esp32-mqtt-wol.md): Wake-on-LAN only works from inside the LAN — so I put a $5 ESP32 on the LAN. It subscribes to an MQTT topic and broadcasts magic packets on demand. The build, the failure modes, and what a hardware watchdog is really for. - [My Homelab: One Proxmox Box, ZFS Pools, and a Properly Segmented Network](https://harshith.in/blog/homelab-proxmox-zfs-lxc.md): The lab started as services sprawled across whatever machine was awake — until one bad upgrade took them all down at once. This is what that failure taught me: one Proxmox host, ZFS snapshots as the undo button, and a network segmented by trust. - [How This Blog Runs for $0 a Month](https://harshith.in/blog/how-this-blog-runs-for-0.md): No VPS, no database, no CMS bill. This site is a git repo that compiles to static files — search index, social cards, and fonts included — and Cloudflare Pages serves it for free. Here's the whole pipeline, with the actual configs. - [How LLM Inference Actually Runs: Tokens, KV Cache, and Why It's Memory-Bound](https://harshith.in/blog/how-llm-inference-works.md): A language model generates one token at a time, and each token re-reads gigabytes of weights and a growing cache. Understanding the KV cache and the memory-bandwidth wall explains latency, context limits, and every serving optimization from the last two years. - [Reading Flame Graphs: Where Your CPU Time Actually Goes](https://harshith.in/blog/flame-graphs-and-perf.md): A flame graph turns thousands of stack samples into one picture where width is time and the widest boxes are your problem. How sampling profilers work, how to read the graph in ten seconds, and the traps — inlining, wait time, broken stacks — that mislead beginners. - [mmap vs read(): When Mapping a File Actually Wins](https://harshith.in/blog/mmap-vs-read-large-files.md): mmap is sold as the fast way to read files, but it loses as often as it wins. The deciding factor is page faults versus syscalls — and whether you touch the data once or many times. - [Anatomy of a Context Switch: What the Kernel Does Between Two Threads](https://harshith.in/blog/context-switch-anatomy.md): A context switch looks free until you profile a thread-heavy workload and watch it vanish into the kernel. Here is everything the scheduler actually does to swap one thread for another. - [Floating Point: Why 0.1 + 0.2 Isn't 0.3](https://harshith.in/blog/floating-point-explained.md): Every language prints 0.30000000000000004 and every newcomer files a bug report. It's not a bug — it's binary fractions doing exactly what the IEEE 754 standard says. Here's the why, and what to do about it. - [Bloom Filters: Probably Present, Definitely Useful](https://harshith.in/blog/bloom-filters.md): A Bloom filter answers 'have I seen this before?' using a fraction of the memory a real set would need — by allowing one specific kind of wrong answer. It's the data structure behind databases skipping disk reads they don't need. - [Git Internals: Your Repo Is a Content-Addressed Database](https://harshith.in/blog/git-internals.md): Git feels like a pile of special commands until you see the data model underneath: four object types in a key-value store keyed by hash. Learn the model and every confusing command suddenly makes sense. - [eBPF: Running Your Code in the Kernel Without a Module](https://harshith.in/blog/ebpf-explained.md): For decades, changing kernel behavior meant writing a kernel module and risking a panic. eBPF lets you load sandboxed programs into a running kernel safely — and it's quietly become the backbone of modern observability and networking. - [What a Container Actually Is: Namespaces and cgroups](https://harshith.in/blog/what-is-a-container.md): A container isn't a lightweight VM — there's no guest kernel, no virtual hardware. It's just a normal Linux process wearing two kernel features as a disguise. Strip away Docker and the magic is surprisingly small. - [Interrupts: How Hardware Taps the Kernel on the Shoulder](https://harshith.in/blog/interrupts-top-and-bottom-halves.md): A packet arrives, a key is pressed, a timer fires — and the CPU drops everything, mid-instruction-stream, to run kernel code. How interrupts work, why handlers are split in half, and how NAPI killed the interrupt storm. - [Journaling Filesystems: How ext4 Survives a Crash](https://harshith.in/blog/journaling-filesystems.md): Pull the power mid-write and a naive filesystem corrupts. A journal is the write-ahead log that lets ext4 come back consistent — by promising to do work before actually doing it. - [False Sharing: The Cache Line That Kills Your Parallelism](https://harshith.in/blog/false-sharing.md): You split work across eight threads with zero shared state, and it runs slower than one thread. The culprit is false sharing — independent variables that happen to live on the same cache line, fighting over it. - [How malloc Works: Arenas, Bins, and Fragmentation](https://harshith.in/blog/how-malloc-works.md): malloc looks like one function, but underneath it's a memory allocator juggling free lists, size classes, and the kernel. Knowing how it works explains fragmentation, allocator contention, and why your RSS never goes down. - [The TLS 1.3 Handshake: What Those Milliseconds Buy](https://harshith.in/blog/tls-handshake-mechanics.md): One round trip now negotiates keys, proves identity, and encrypts everything after the first message. What actually happens in a TLS 1.3 handshake, why it's structurally safer than 1.2, and where the remaining sharp edges live. - [Hash Tables: The Real Cost of a Collision](https://harshith.in/blog/hash-table-collisions.md): Hash tables promise O(1) lookups, and then a benchmark shows them losing to a plain array. The gap between the textbook and reality is collisions, cache misses, and the resize you forgot about. - [HTTP/2 Multiplexing: One Connection, Many Streams](https://harshith.in/blog/http2-multiplexing.md): HTTP/1.1 made you choose between head-of-line blocking and opening a pile of connections. HTTP/2 fixes it by carrying many independent streams over a single connection — and then TCP reintroduces the very problem it solved. - [Why Distributed Consensus Needs a Quorum](https://harshith.in/blog/quorum-and-consensus.md): Replicate data across five machines and you'd think any one of them could answer. But to stay consistent through failures, a majority has to agree on every decision. Here's the arithmetic behind quorums. - [Stack Canaries: How the Compiler Catches a Buffer Overflow](https://harshith.in/blog/stack-canaries.md): A classic stack smash overwrites the return address and hijacks execution. Stack canaries are the cheap, clever defense your compiler inserts automatically — and understanding them explains a whole class of exploits. - [Raft: Consensus You Can Actually Trace](https://harshith.in/blog/raft-in-practice.md): Raft won because you can hold the whole protocol in your head: terms, a leader, and one log-matching rule. The mechanics of election and replication — and the operational corners (fsync, membership changes, pre-vote) where deployments actually bleed. - [How a Compiler Turns Your Loop Into SIMD](https://harshith.in/blog/how-compilers-autovectorize.md): Modern CPUs can add eight numbers in one instruction, and your compiler will rewrite plain loops to use them — but only if you don't accidentally forbid it. Here's what auto-vectorization needs to fire. - [Memory Barriers: What volatile Won't Do For You](https://harshith.in/blog/memory-barriers-and-volatile.md): C's volatile keyword is the most misunderstood tool in concurrent programming. It stops the compiler from caching a value — but it does nothing about the reordering that actually breaks your lock-free code. - [B-Trees vs LSM-Trees: The Storage Engine Tradeoff](https://harshith.in/blog/btree-vs-lsm-tree.md): Every database picks one of two ways to put data on disk. The choice between B-trees and LSM-trees is really a choice about whether you optimize for reads or writes — and you can't have both for free. - [TCP Slow Start: Why Your First Megabyte Is Always Slow](https://harshith.in/blog/tcp-slow-start.md): A fresh TCP connection doesn't blast data at line rate — it tiptoes. Slow start is the reason a cold connection feels sluggish, and understanding it explains half of web performance. - [From ASCII to Unicode: Why Text Is Harder Than You Think](https://harshith.in/blog/character-encodings-history.md): Text feels like a solved problem until an emoji breaks your database, a filename won't delete, or 'MÜLLER' and 'müller' won't compare equal. The layered history of character encoding explains every mojibake bug you'll ever hit. - [Logical Clocks: Ordering Events When 'Now' Doesn't Exist](https://harshith.in/blog/logical-clocks.md): Wall clocks on different machines disagree by milliseconds — eternity for a fast system. Lamport's insight: you don't need time, you need causality. Lamport clocks, vector clocks, and the hybrid compromise running inside your database. - [An AI Agent Is Just a Loop and a Capability Table](https://harshith.in/blog/building-an-agent-loop.md): Strip the frameworks away and an LLM agent is about 35 lines: call the model, if it asks for a tool run the tool and feed the result back, repeat until it stops. I built one from scratch to prove it — and the systems concepts underneath are all familiar. - [epoll: The Syscall Under Every Event Loop](https://harshith.in/blog/epoll-and-event-loops.md): nginx, Node, Redis, and every async runtime you use sit on one Linux primitive. Why select died at scale, how epoll inverts the cost model, the level- vs edge-triggered trap, and the thundering herd that took years to fix. - [MVCC: How Databases Let Readers and Writers Ignore Each Other](https://harshith.in/blog/mvcc-how-databases-time-travel.md): Postgres never updates a row — it writes a new version and lets old transactions keep seeing the old one. Multiversion concurrency is why reads don't block writes, why VACUUM exists, and why 'the database is bloated' is a real sentence. - [SQL Indexes Under the Hood: Why Your Query Ignores Yours](https://harshith.in/blog/sql-indexes-under-the-hood.md): An index is a sorted structure with physical properties, not a magic 'go faster' flag. Leftmost prefixes, covering indexes, selectivity, and the honest reasons the planner chose a sequential scan over the index you lovingly created. - [Regex Engines: The NFA/Backtracking Split That Explains ReDoS](https://harshith.in/blog/how-regex-engines-work.md): The same pattern runs in microseconds in Go and hangs for years in JavaScript, on the same input. The reason is a fork in engine design made in the 1970s — automata vs backtracking — and it's why one regex took Cloudflare's edge offline. - [Deadlocks: The Four Conditions and the One Fix That Works](https://harshith.in/blog/deadlocks-in-practice.md): Every deadlock requires four conditions to hold simultaneously, and every practical cure breaks exactly one of them. Why lock ordering is the fix that survives contact with real codebases, and how to find the cycle when it happens anyway. - [MCP: Giving AI Agents a Universal Tool Port](https://harshith.in/blog/model-context-protocol-explained.md): Before the Model Context Protocol, every agent-to-tool integration was bespoke M×N glue. MCP is the USB-C of agent tooling: a standard client-server protocol so any model can discover and call any capability. What it is, and why it's a systems standard, not an AI one. - [The Homelab Networking Stack: Reverse Proxies, VLANs, and Trust](https://harshith.in/blog/self-hosting-networking-stack.md): Exposing one service teaches you TLS. Exposing ten teaches you reverse proxies, DNS, network segmentation, and the uncomfortable truth that your smart bulbs are on the same wire as your NAS. A field guide to the plumbing. - [Zero-Copy I/O: Stop Paying to Move Bytes You Never Touch](https://harshith.in/blog/zero-copy-io.md): A naive file-to-socket server copies every byte four times and crosses the kernel boundary twice per chunk. sendfile collapses it to zero user-space copies — and the lineage from there (splice, MSG_ZEROCOPY, io_uring) is the story of modern fast I/O. - [The VFS: How 'Everything Is a File' Actually Works](https://harshith.in/blog/vfs-everything-is-a-file.md): The same read() works on ext4 files, /proc fictions, sockets, and pipes because Linux routes every file operation through one dispatch layer. The VFS is the kernel's biggest interface — and its object model is worth stealing. - [How Linux Decides What Runs Next: CFS to EEVDF](https://harshith.in/blog/cfs-and-eevdf-scheduling.md): For 15 years Linux picked the next task with a red-black tree of virtual runtimes. In 6.6 that changed for the first time since 2007. What fairness actually means, how nice values work, and why latency-sensitive tasks forced a redesign. - [What -O2 Actually Does: A Tour of Compiler Optimizations](https://harshith.in/blog/how-compilers-optimize.md): The gap between -O0 and -O2 is often 10x, and it's not magic — it's a pipeline of individually simple transformations over an intermediate representation. SSA, inlining, the passes that matter, and why your careful micro-optimization was already done for you. - [Tokenizers: Why an LLM Can't Count the R's in Strawberry](https://harshith.in/blog/tokenizers-explained.md): Before a language model sees your text, a tokenizer chops it into subword pieces from a fixed vocabulary — and that boundary explains the model's weirdest failures: bad arithmetic, the strawberry problem, why code indentation matters, and why some languages cost 3x more. - [Longest Prefix Match: How Routers Decide in Nanoseconds](https://harshith.in/blog/longest-prefix-match.md): A core router matches each packet against ~1M CIDR prefixes and must pick the most specific — billions of times per second. The data structures behind that (tries, TCAM, poptrie lineage) and why 'most specific wins' shapes everything from BGP hijacks to your homelab VPN. - [Write-Ahead Logging: The Only Trick Durability Has](https://harshith.in/blog/write-ahead-logging.md): Every database, filesystem, and message broker converges on the same move: append the intention to a sequential log, fsync, then update the real structures whenever. WAL is one idea wearing a dozen names — and its failure modes repeat too. - [Anatomy of a System Call: What read() Really Costs](https://harshith.in/blog/anatomy-of-a-syscall.md): A function call costs ~2ns. A syscall costs ~100ns before doing any work — and that's after decades of optimization plus a Spectre-era tax. Where the time goes, why vDSO exists, and what that means for API design. - [Hash Functions: What Makes a Good One (and Why Yours Isn't)](https://harshith.in/blog/hash-functions-non-crypto.md): Between 'sum the bytes' and SHA-256 lies the workhorse category: non-cryptographic hashes. What avalanche means, how hash quality turns into hash-table throughput, and why every language runtime switched to seeded hashing. - [NAT and conntrack: The Stateful Lie Your Router Tells](https://harshith.in/blog/nat-and-conntrack.md): NAT rewrites addresses; connection tracking is the memory that makes the rewrite reversible. Together they're why the internet survived IPv4 exhaustion — and why your idle SSH session dies, your table overflows, and P2P needs hole-punching. - [ARP: The Protocol That Glues IP to Ethernet](https://harshith.in/blog/arp-and-the-last-hop.md): Every packet's last hop is decided not by routing but by a 1982 protocol with no authentication, a cache with quirks, and failure modes — gratuitous ARP, proxy ARP, spoofing — that explain a shocking fraction of 'the network is weird' tickets. - [Unix Signals: The API Everyone Uses and Nobody Uses Safely](https://harshith.in/blog/unix-signals-sharp-edges.md): Signals interrupt your program between any two instructions and run your handler in the wreckage. Why almost everything is illegal inside a handler, what async-signal-safe really means, and the self-pipe/signalfd escape hatches. - [Arena Allocators: Free Everything at Once](https://harshith.in/blog/arena-allocators.md): The fastest malloc is a pointer bump; the fastest free is resetting one offset. Arenas trade individual deallocation for speed, locality, and the death of use-after-free within a lifetime — a trade half your workloads should take. - [Wake-on-LAN: How 102 Bytes Turn On a Sleeping PC](https://harshith.in/blog/wake-on-lan-magic-packets.md): A powered-off machine has no OS, no IP stack, no running software — yet a single crafted broadcast frame boots it. How the NIC stays half-awake watching for its own MAC, why WoL is a layer-2 trick, and the homelab plumbing to make it reliable. - [Rate Limiting: Token Buckets, Burst Math, and the 429 You Deserve](https://harshith.in/blog/rate-limiting-algorithms.md): Fixed windows let 2x through at the boundary, token buckets are three lines of arithmetic, and the distributed version is a consistency problem wearing an ops costume. The algorithms, their failure modes, and what to return when you say no. - [How the Kernel Allocates Memory: Buddy and Slab](https://harshith.in/blog/buddy-and-slab-allocators.md): malloc has a supplier: the kernel's own allocators. The buddy system deals in power-of-two page blocks and fights fragmentation with math; the slab layer turns pages into typed object caches. Between them, every allocation on your machine. - [What the Linker Actually Does](https://harshith.in/blog/what-the-linker-does.md): Half of all confusing C build errors — undefined reference, multiple definition, static initialization order — are linker concepts wearing compiler costumes. Symbols, relocations, and the archive rule that surprises everyone. - [Function Pointers to Vtables: Polymorphism Without the Keyword](https://harshith.in/blog/function-pointers-and-vtables.md): C++ virtual calls, Linux file_operations, and Go interfaces are the same machine code: load a pointer, call through it. What a vtable really is, what an indirect call costs, and how devirtualization claws it back. - [RTOS vs Bare Metal: When a Microcontroller Needs a Scheduler](https://harshith.in/blog/rtos-vs-bare-metal.md): A superloop is the right architecture more often than embedded tutorials admit — until the day it isn't, and you need preemption, priorities, and blocking. What FreeRTOS actually buys you on an ESP32, and what it costs. - [Big-O in Practice: When the Constant Factor Eats the Asymptote](https://harshith.in/blog/big-o-in-practice.md): Binary search loses to linear scan on small arrays. Hash maps lose to sorted vectors. Big-O tells you how algorithms scale, not which one is faster — and on modern hardware the gap between those two questions is enormous. - [HTTP Caching: The Distributed System You Already Deployed](https://harshith.in/blog/http-caching-contract.md): Between your server and each user sit browser caches, CDN tiers, and shared proxies you don't operate — all obeying Cache-Control headers you may have set by accident. The freshness/validation model, and the headers that cause incidents. - [Struct Padding: The Bytes You're Paying For but Not Using](https://harshith.in/blog/struct-padding-and-alignment.md): Reorder three fields and a struct shrinks from 24 bytes to 16 — a 33% memory cut with zero code changes. Where padding comes from, how to see it with pahole, and when packing is a trap. - [Undefined Behavior: The Compiler Is Not Your Friend Here](https://harshith.in/blog/undefined-behavior-is-not-a-value.md): UB doesn't mean 'returns garbage' — it means the optimizer may assume it never happens and reason backwards from that. How signed overflow checks get deleted, why time-travel is real, and the sanitizer workflow that catches it. - [SSD Internals: Why Your Disk Is a Small Computer That Lies](https://harshith.in/blog/ssd-internals.md): Flash can't overwrite in place, erases in giant blocks, and wears out per cell — so every SSD runs a translation layer that remaps, garbage-collects, and levels wear behind your back. Write amplification, TRIM, and the cliff at 90% full, explained. - [Two's Complement: Why -1 Is All Ones](https://harshith.in/blog/twos-complement.md): Signed integers could have been encoded a dozen ways. Hardware settled on two's complement because it makes the adder ignorant of sign — one circuit for everything. The same choice explains INT_MIN, sign extension bugs, and why abs() can return a negative number. - [From ./a.out to main(): What exec Actually Does](https://harshith.in/blog/what-happens-when-you-run-a-program.md): Between pressing enter and your first line of code, the kernel parses an ELF file, maps segments, loads an interpreter you didn't know existed, and that interpreter relocates half your program. A tour of the machinery under ./a.out. - [Spinlocks vs Mutexes: When Burning CPU Is the Right Call](https://harshith.in/blog/spinlocks-vs-mutexes.md): One lock burns CPU while it waits; the other pays a syscall to sleep. The right choice depends on hold time versus context-switch cost — and the best answer, futexes and adaptive locks, is 'both, in that order'. - [DNS Resolution: Every Hop Between You and an IP Address](https://harshith.in/blog/dns-resolution-path.md): A 'simple' name lookup traverses your language runtime, nsswitch, a stub resolver, a recursive resolver, and up to three tiers of authoritative servers — with caches at every layer that disagree. Map the path once and DNS bugs become findable. - [Load Balancer Internals: L4 vs L7 and the Algorithms Between](https://harshith.in/blog/load-balancer-internals.md): A 'load balancer' is anywhere from a NAT rewrite to a full HTTP proxy with retry logic — and the algorithm matters less than people think while the health checking matters more. The mechanics, from ECMP and Maglev down to power-of-two-choices. - [Message Queues: At-Least-Once Is the Only Honest Promise](https://harshith.in/blog/message-queue-delivery-semantics.md): Every queue advertises delivery guarantees; every distributed-systems engineer eventually learns the ack-crash window makes duplicates inevitable. Why exactly-once is really exactly-once *processing*, and the idempotency patterns that make it true. - [RAID: What It Protects, What It Doesn't, and the URE Math](https://harshith.in/blog/raid-what-it-does-and-doesnt.md): RAID levels are three ideas — stripe, mirror, parity — composed. The interesting parts are the failure math: why RAID 5 rebuilds fail at modern disk sizes, what the write hole is, and why RAID is not backup, mathematically. - [ASLR: Security by Shuffling the Address Space](https://harshith.in/blog/aslr-mechanics.md): Every exploit needs an address; ASLR's bet is that the attacker shouldn't know any. How Linux randomizes stack, heap, and libraries, why PIE took years to become default, and the leak-one-pointer reality that keeps ASLR a speed bump, not a wall. - [Branch Prediction: Why Sorted Data Runs Faster](https://harshith.in/blog/branch-prediction-and-pipelines.md): The same loop over the same data runs 5x faster when the array is sorted. The instructions are identical. The difference is a gambler inside your CPU that's either winning or losing. - [From Power Button to Kernel: How a PC Boots](https://harshith.in/blog/how-a-pc-boots.md): At reset, an x86 CPU wakes up pretending it's 1978 — 16-bit mode, 1 MB address space. Everything after that is bootstrapping: firmware, boot sector or EFI application, protected mode, and finally a kernel. I wrote a bootloader to learn the path; here's the map. - [How Query Planners Think: Costs, Cardinality, and Lies](https://harshith.in/blog/query-planner-thinking.md): SQL says what, the planner decides how — by estimating row counts through a chain of guesses and picking the cheapest of thousands of plans. When the estimate is wrong by 1000x, so is the plan. Reading EXPLAIN is learning to audit those guesses. - [Intrusive Lists: How the Kernel Does Data Structures](https://harshith.in/blog/intrusive-lists.md): The Linux kernel's list_head puts the container inside the object instead of the object inside the container — one implementation, zero allocations, and a container_of macro that looks illegal but isn't. I built a library around the pattern; here's why it wins. - [Arrays vs Linked Lists: The Benchmark Textbooks Don't Run](https://harshith.in/blog/arrays-vs-linked-lists.md): The textbook says linked lists win at insertion, O(1) vs O(n). Run the benchmark and the array wins insertion-heavy workloads too — often by 10x. The memory hierarchy voted, and it didn't vote for pointers. - [Ring Buffers: The Data Structure at Every Fast Boundary](https://harshith.in/blog/ring-buffers.md): NIC queues, io_uring, audio pipelines, logging, SPSC channels — wherever a fast producer meets a consumer on a budget, there's a fixed array with two indices. The design decisions that matter: power-of-two sizing, the full/empty problem, and who waits. - [Virtual Memory: The Lie Every Process Believes](https://harshith.in/blog/virtual-memory-basics.md): Every process thinks it has a private, contiguous address space starting at zero. None of them do. Virtual memory is the translation layer that makes the lie hold — and it's why fork, mmap, and swap can exist at all. - [What Your Language's sort() Actually Runs](https://harshith.in/blog/how-sorting-actually-works.md): Nobody ships textbook quicksort. Python runs Timsort, C++ runs introsort, and both are layered hybrids built around one insight: real-world data isn't random, and worst cases must be impossible. - [Buffer Pools: Why Databases Don't Trust Your OS](https://harshith.in/blog/buffer-pools-and-database-pages.md): Databases read disk through fixed-size pages cached in a buffer pool they manage themselves — duplicating what the kernel's page cache already does. The reasons why (eviction control, WAL ordering, O_DIRECT) are a masterclass in when to bypass the OS. - [CPU Caches: The Memory Hierarchy Your Code Lives In](https://harshith.in/blog/cpu-caches-explained.md): DRAM is ~100ns away; your CPU can do ~400 arithmetic operations in that time. Caches exist to hide that gap, and whether they succeed is decided by how your code lays out and walks its data. - [Page Tables and the TLB: The Cost of Every Address](https://harshith.in/blog/page-tables-and-the-tlb.md): Every pointer dereference triggers a virtual-to-physical translation through a four-level radix tree. The only reason your machine isn't 5x slower is a tiny cache called the TLB — and when it misses, you feel it. - [Why 0.1 + 0.2 ≠ 0.3, and Why It's Worse Than You Think](https://harshith.in/blog/floating-point-determinism.md): Everyone knows floating point is 'imprecise.' Fewer know that the same expression can give different results on different machines, that summation order changes your answer, and why associativity — the thing algebra promised you — is a lie in float. - [MQTT: Why the IoT World Runs on a 1999 Protocol](https://harshith.in/blog/mqtt-protocol-internals.md): MQTT moves a temperature reading in about 30 bytes over a connection that survives flaky cellular links and sleepy microcontrollers. The publish/subscribe model, the three QoS levels, and the retained-message and last-will tricks that make it click. - [QUIC and HTTP/3: Rebuilding TCP in Userspace, on Purpose](https://harshith.in/blog/quic-and-http3.md): HTTP/2 fixed application-layer head-of-line blocking and exposed the transport-layer version underneath. QUIC's answer: reimplement reliability per-stream over UDP, encrypt the transport headers, and make connections survive IP changes. - [fork() and Copy-on-Write: Duplicating a Process for Free](https://harshith.in/blog/fork-and-copy-on-write.md): fork clones a 10 GB process in under a millisecond by copying nothing — just page tables, marked read-only. The first write to any page pays the real cost. Elegant, and the source of Redis's most famous operational trap. - [Buffer Overflows: From strcpy to Shell, and the Mitigations That Ended It](https://harshith.in/blog/how-buffer-overflows-work.md): A single unbounded copy can hand an attacker your instruction pointer. The classic stack smash, then the 25-year arms race — stack canaries, NX, ASLR — that turned a reliable exploit into a hard research problem. - [Consistent Hashing: Surviving the Resize](https://harshith.in/blog/consistent-hashing.md): hash(key) % N reshuffles nearly everything when N changes — a cache stampede with a math degree. Consistent hashing moves only 1/N of keys per node change, and virtual nodes fix the balance problem the elegant version hides. - [UTF-8: The Encoding That Won by Being Clever](https://harshith.in/blog/utf8-by-design.md): UTF-8 was sketched on a placemat in 1992 and now carries ~98% of the web. It won because of five design properties — self-synchronization, ASCII compatibility, sort-order preservation — that no committee would have dared require. - [Error Handling in C: In Defense of goto cleanup](https://harshith.in/blog/goto-cleanup-error-handling-c.md): C has no destructors, no defer, no exceptions — just early returns that leak and nested ifs that march off the screen. The kernel settled this decades ago: goto-based cleanup is the correct idiom, and it's more disciplined than its reputation. - [The TCP State Machine: Where Connections Actually Live](https://harshith.in/blog/tcp-state-machine.md): Eleven states, two of which cause most production incidents. Implementing TCP taught me the state diagram isn't trivia — TIME_WAIT port exhaustion, SYN backlogs, and orphaned FIN_WAIT_2 are all right there in the RFC 793 figure. - [Recursion Is Just a Stack You Didn't Write](https://harshith.in/blog/recursion-and-the-stack.md): Every recursive call is a frame pushed onto the call stack — return address, saved registers, locals. See the frame layout once and stack overflows, tail calls, and the recursion-to-iteration transformation all become mechanical. ## Optional - [Full text of every post and project](https://harshith.in/llms-full.txt) - [RSS feed](https://harshith.in/rss.xml) - [Sitemap](https://harshith.in/sitemap-index.xml)