<?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: Shubham</title>
    <description>The latest articles on DEV Community by Shubham (@shubham399).</description>
    <link>https://dev.to/shubham399</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%2F366471%2F5ee5ca23-114c-4498-86ed-33a9db44c8a9.png</url>
      <title>DEV Community: Shubham</title>
      <link>https://dev.to/shubham399</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shubham399"/>
    <language>en</language>
    <item>
      <title>What's All Am I Hosting? Full Infrastructure Breakdown</title>
      <dc:creator>Shubham</dc:creator>
      <pubDate>Sat, 04 Jul 2026 18:52:41 +0000</pubDate>
      <link>https://dev.to/shubham399/whats-all-am-i-hosting-full-infrastructure-breakdown-53b8</link>
      <guid>https://dev.to/shubham399/whats-all-am-i-hosting-full-infrastructure-breakdown-53b8</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Ff9ea98b1-39b2-4983-85cd-a1d67470ae45.png%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Ff9ea98b1-39b2-4983-85cd-a1d67470ae45.png%2Fpublic" width="1152" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every few months, someone asks me how I run my entire online presence for basically nothing. The short answer is: I don't pay for what I can get for free.&lt;/p&gt;

&lt;p&gt;The long answer is this post.&lt;/p&gt;

&lt;p&gt;My entire infrastructure   this site, APIs, email, monitoring, URL shortener, dev tools   runs on free-tier cloud services. Total cost: &lt;strong&gt;$0/month&lt;/strong&gt;. That's less than a single AWS load balancer costs for an hour.&lt;/p&gt;

&lt;p&gt;Here's exactly how it works, why I chose each piece, and what I'd do differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Philosophy: Free Tier First
&lt;/h2&gt;

&lt;p&gt;I have a simple rule: if a service has a generous free tier that covers my use case, I use it. If I outgrow it, I'll pay   but most of us never outgrow free tiers for personal projects.&lt;/p&gt;

&lt;p&gt;The second rule: own the critical paths. DNS is the backbone, so it's on Cloudflare (free, but best-in-class). The main site is on Vercel (free, seamless Next.js deployment). Everything else   databases, email, APIs, monitoring   is a managed service that solves exactly one problem well.&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS: Cloudflare (The Glue That Holds It All Together)
&lt;/h2&gt;

&lt;p&gt;Everything starts with DNS. Cloudflare runs &lt;strong&gt;chan.ns.cloudflare.com&lt;/strong&gt; and &lt;strong&gt;dave.ns.cloudflare.com&lt;/strong&gt; as my authoritative nameservers. Every subdomain in this post is a DNS record that Cloudflare serves for free.&lt;/p&gt;

&lt;p&gt;I use Cloudflare as a pure DNS provider   no CDN proxying on most records except a few redirects (cal, link, mail). The proxied records hide my origin IP and give me free SSL termination, but I keep most records direct because I want full control over the traffic path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Cloudflare over Route53 or self-hosted?&lt;/strong&gt; Cloudflare's free plan includes unlimited DNS queries, DNSSEC, easy API access, and their dashboard is fast. Route53 charges per query. Self-hosting DNS is unnecessary complexity. Free + best-in-class = no contest.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Main Site: Vercel
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;shubhkumar.in&lt;/strong&gt; is hosted on Vercel's free tier. The apex domain uses an A record to 216.198.79.1 (Vercel's anycast IP for apex domains   you can't use a CNAME at the root).&lt;/p&gt;

&lt;p&gt;Vercel's free tier includes 100GB bandwidth, 6000 build minutes, automatic SSL, and edge network distribution. For a Next.js site with ISR, this is more than enough. The site loads fast everywhere because Vercel serves it from their edge network.&lt;/p&gt;

&lt;p&gt;The www subdomain CNAMEs to the root   standard practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Vercel-Hosted Sites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cv.shubhkumar.in&lt;/strong&gt;   Resume site. Next.js, deploys from GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;news.shubhkumar.in&lt;/strong&gt;   Another Next.js site.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hosted Applications: The Free Tier Dream Team
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Render   API Server
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;api.shubhkumar.in&lt;/strong&gt; runs on Render's free tier. It handles contact forms, webhooks, and server-side endpoints the static site can't handle. Render gives 750 hours/month   plenty for a low-traffic personal API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Render over Railway or Fly.io?&lt;/strong&gt; Render has the most generous free tier for this use case. The deploy experience is smooth (Git push → deploy), and SSL is automatic.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Pages   Lightweight Pages
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;connect.shubhkumar.in&lt;/strong&gt; is a simple social link aggregator   Linktree-style but self-hosted. Single HTML page, zero cost, instant deploy from a GitHub repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Infrastructure: The Stuff That Runs in the Background
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tailscale   Private Network Bridge
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;tail.shubhkumar.in&lt;/strong&gt; points to my Tailscale node at &lt;strong&gt;100.115.133.19&lt;/strong&gt;. Tailscale creates a WireGuard mesh across all my devices   laptop, home server, cloud VMs. The DNS record lets me reach my home lab from anywhere using a proper subdomain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real magic:&lt;/strong&gt; Tailscale handles NAT traversal automatically. My home server is behind CGNAT (common with Indian ISPs), and Tailscale punches through without any port forwarding. Free tier: up to 100 devices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Databases   Managed, Never Self-Hosted
&lt;/h3&gt;

&lt;p&gt;I use managed databases exclusively. &lt;strong&gt;Supabase&lt;/strong&gt; (Postgres) for anything that needs relational queries and real-time subscriptions. &lt;strong&gt;MongoDB Atlas&lt;/strong&gt; for document storage when the schema is fluid. Both on free tiers or their cheapest paid plans   whichever covers the workload.&lt;/p&gt;

&lt;p&gt;Self-hosting a database is the fastest way to turn a weekend into an ops nightmare. Backups, replication, patches, disk space   all someone else's problem. The managed premium is worth every rupee.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fly.io   Lightweight Apps
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;track.shubhkumar.in&lt;/strong&gt; hosts WakaAPI (self-hosted WakaTime stats) on Fly.io. Free allowance covers the tiny resource usage   3 shared-CPU VMs with 256MB RAM, 3GB storage, 160GB outbound.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cal.com   Scheduling
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;cal.shubhkumar.in&lt;/strong&gt;   Cloudflare-proxied redirect to Cal.com. Self-hosting a calendar scheduler isn't worth my weekend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better Uptime   Monitoring
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;status.shubhkumar.in&lt;/strong&gt;   Free tier. Monitors all endpoints, notifies on Slack. 10 monitors with 3-minute checks and a public status page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools and Redirects
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dub.co   URL Shortener
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;go.shubhkumar.in&lt;/strong&gt; runs on Dub.co's free tier. Short, memorable links   &lt;em&gt;go.shubhkumar.in/github&lt;/em&gt;, etc. Open-source, great API, free tier includes custom domains and basic analytics.&lt;/p&gt;

&lt;p&gt;Used to run YOURLS on a VPS. Moving to Dub.co saved maintenance and gave better analytics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple Redirects
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;link.shubhkumar.in&lt;/strong&gt; and &lt;strong&gt;mail.shubhkumar.in&lt;/strong&gt; are Cloudflare-proxied redirects using 192.0.2.1 (Cloudflare's placeholder IP). No server needed   Cloudflare page rules handle the redirects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Email Infrastructure: The Hardest Part
&lt;/h2&gt;

&lt;p&gt;Email is the hardest thing on a personal domain. I run three services for different purposes because each solves a specific problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zoho Mail   Primary
&lt;/h3&gt;

&lt;p&gt;Primary email on Zoho's free plan   5 mailboxes with 5GB each, custom domain, IMAP/SMTP, calendar. The last remaining free tier for professional email on a custom domain after Outlook killed their free custom domain offering and Google Workspace charges $6/user/month.&lt;/p&gt;

&lt;p&gt;MX: mx.zoho.com (priority 10), mx2/3 as fallbacks. DMARC set to &lt;strong&gt;reject&lt;/strong&gt; with Cloudflare reporting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trade-off:&lt;/strong&gt; Zoho's spam filtering is decent but not Gmail-level. For free, acceptable.&lt;/p&gt;

&lt;h3&gt;
  
  
  SimpleLogin   Email Aliases
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;simple.shubhkumar.in&lt;/strong&gt;   Creates aliases that forward to my primary inbox. If a service sells my email, I delete the alias. Free tier: 15 aliases, PGP encryption, open-source.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resend   Transactional + Broadcast Emails
&lt;/h3&gt;

&lt;p&gt;I use &lt;strong&gt;Resend&lt;/strong&gt; for all outgoing emails   transactional notifications, broadcast newsletters, and contact form submissions. It handles everything through a single clean API with good deliverability out of the box.&lt;/p&gt;

&lt;p&gt;Resend's free tier includes 100 emails/day, which covers my low-volume needs. DKIM and SPF configured through forms.shubhkumar.in for proper authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security and Verification Records
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DMARC (reject)&lt;/strong&gt;   Strictest policy. Reports to Cloudflare's DMARC reporting. Caught email spoofing attempts at least twice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;BIMI&lt;/strong&gt;   Shows my logo next to authenticated emails. Mostly vanity but looks professional.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keybase&lt;/strong&gt;   Domain ownership proof.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Google Search Console&lt;/strong&gt;   Site ownership for search analytics.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Don't Use (And Why)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No Kubernetes.&lt;/strong&gt; Everything fits in docker-compose or managed platforms. K8s is operational overkill for one person.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No AWS.&lt;/strong&gt; Pricing model punishes hobbyists. One misconfigured resource = surprise bill. I use SES for email only when necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No self-hosted CI.&lt;/strong&gt; GitHub Actions is free for public repos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Databases:&lt;/strong&gt; Managed   Supabase (Postgres), MongoDB Atlas, etc. Free tiers + cheapest plans cover everything. Self-hosting a database is unnecessary ops overhead.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cost Breakdown
&lt;/h2&gt;

&lt;p&gt;Service&lt;/p&gt;

&lt;p&gt;Cost&lt;/p&gt;

&lt;p&gt;What It Runs&lt;/p&gt;

&lt;p&gt;Vercel&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;Main site (Next.js) + CV + News&lt;/p&gt;

&lt;p&gt;Cloudflare DNS&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;All DNS records, proxied redirects&lt;/p&gt;

&lt;p&gt;Render&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;API server&lt;/p&gt;

&lt;p&gt;GitHub Pages&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;Link aggregator&lt;/p&gt;

&lt;p&gt;Fly.io&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;WakaAPI instance&lt;/p&gt;

&lt;p&gt;Better Uptime&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;10 monitors, status page&lt;/p&gt;

&lt;p&gt;Dub.co&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;URL shortener&lt;/p&gt;

&lt;p&gt;Zoho Mail&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;Primary email, custom domain&lt;/p&gt;

&lt;p&gt;SimpleLogin&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;15 email aliases&lt;/p&gt;

&lt;p&gt;Resend&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;Transactional + broadcast emails&lt;/p&gt;

&lt;p&gt;Tailscale&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;Mesh VPN, 100 devices&lt;/p&gt;

&lt;p&gt;Supabase&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;Managed Postgres (free tier)&lt;/p&gt;

&lt;p&gt;MongoDB Atlas&lt;/p&gt;

&lt;p&gt;$0&lt;/p&gt;

&lt;p&gt;Managed MongoDB (free tier)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;$0/mo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;~15 services, one domain, full infra&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;You don't need to self-host everything.&lt;/strong&gt; Used to run my own email server, Git server, CI   huge time sink for zero benefit. Managed services let you focus on what matters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DNS TTL matters.&lt;/strong&gt; Low TTL (1–300s) on frequently changed records. High TTL (86400) on stable records for faster lookups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Email deliverability is a second job.&lt;/strong&gt; DKIM + SPF + DMARC + BIMI + reverse DNS + feedback loops takes a full day to set up. Get it right once, don't touch it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Free tiers are designed to hook you.&lt;/strong&gt; That's fine as long as you understand the migration cost before you're locked in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitoring is not optional.&lt;/strong&gt; Better Uptime caught three outages I wouldn't have noticed until someone emailed me.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Reality
&lt;/h2&gt;

&lt;p&gt;Running your own infrastructure is a trade-off   setup time and occasional debugging for complete control and zero ongoing cost. For me, it's worth it.&lt;/p&gt;

&lt;p&gt;But I also know when to stop. I don't self-host email. I don't run a Docker registry. I don't build custom dashboards. The services I chose handle those well enough that my time is better spent building on top of them.&lt;/p&gt;

</description>
      <category>infrastructure</category>
      <category>architecture</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Building My Personal Website From Scratch: Tech Stack, Architecture, and Lessons Learned</title>
      <dc:creator>Shubham</dc:creator>
      <pubDate>Sat, 27 Jun 2026 19:12:59 +0000</pubDate>
      <link>https://dev.to/shubham399/building-my-personal-website-from-scratch-tech-stack-architecture-and-lessons-learned-1h04</link>
      <guid>https://dev.to/shubham399/building-my-personal-website-from-scratch-tech-stack-architecture-and-lessons-learned-1h04</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fcefcefc9-a186-4b42-b0c7-481df84ee9eb.png%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fcefcefc9-a186-4b42-b0c7-481df84ee9eb.png%2Fpublic" width="1152" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a software engineer, a personal website is more than just an online resume it’s an open-ended canvas, a sandbox for testing new tech, and a reflection of how you approach software architecture.&lt;/p&gt;

&lt;p&gt;When I set out to build &lt;a href="https://shubhkumar.in" rel="noopener noreferrer"&gt;shubhkumar.in&lt;/a&gt;, I didn't want to just spin up a template or use a no-code builder. I wanted to build a production-grade, highly optimized, and scalable platform from scratch.&lt;/p&gt;

&lt;p&gt;Here is a look under the hood at the stack, the design decisions, the hosting setup, and the inevitable mistakes made along the way.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Tech Stack: Modular &amp;amp; Decoupled
&lt;/h3&gt;

&lt;p&gt;Instead of building a monolithic application, I opted for a decoupled frontend and backend architecture. This keeps the presentation layer lightweight while allowing the API to scale independently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Frontend:&lt;/strong&gt; &lt;strong&gt;Next.js &amp;amp; Tailwind CSS.&lt;/strong&gt; Next.js handles the user interface with excellent performance, while Tailwind CSS keeps the utility-first design clean, responsive, and highly maintainable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backend API:&lt;/strong&gt; &lt;strong&gt;Express.js (Node.js).&lt;/strong&gt; Hosted at &lt;code&gt;api.shubhkumar.in&lt;/code&gt;, this unopinionated framework handles dynamic requests and serves content efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Database &amp;amp; Distributed Caching:&lt;/strong&gt; &lt;strong&gt;MongoDB Atlas &amp;amp; Redis.&lt;/strong&gt; MongoDB Atlas acts as our fully managed cloud database layer. To slash latency and prevent unnecessary database queries, a cloud-managed Redis instance sits right in front of it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Design Decisions: Single Source of Truth &amp;amp; Multi-Tier Caching
&lt;/h3&gt;

&lt;p&gt;The core philosophy behind this project was &lt;strong&gt;performance, reusability, and absolute separation of concerns&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of letting the Next.js frontend query the database directly, everything routes through the dedicated Express API. The biggest architectural win here is that &lt;strong&gt;the API acts as a single source of truth for my entire digital footprint.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Beyond the main portfolio at &lt;code&gt;shubhkumar.in&lt;/code&gt;, I also host my dedicated CV at &lt;code&gt;cv.shubhkumar.in&lt;/code&gt;. Both frontends consume data from the exact same API endpoints. If I update a project description, add a new tech stack proficiency, or modify my work history, the change reflects universally across all subdomains.&lt;/p&gt;

&lt;p&gt;To deliver instantaneous, sub-100ms response times globally, the architecture leverages a &lt;strong&gt;two-tier aggressive caching model&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The API Tier (Redis):&lt;/strong&gt; When a request hits the Express backend, it checks the cloud Redis cache first. If it's a hit, it serves it instantly. If it's a miss, it pulls from MongoDB Atlas and hydrates Redis with an expiration TTL (Time-to-Live).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Frontend Tier (Next.js Data Cache):&lt;/strong&gt; Pages aren't just fetching live on every request. Next.js caches data at the framework layer using time-based revalidation (&lt;code&gt;next: { revalidate: ... }&lt;/code&gt;). This serves prerendered static pages from Vercel’s edge network while quietly updating the data in the background once the timer lapses.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Hosting &amp;amp; Deployment: The Cloud Setup
&lt;/h3&gt;

&lt;p&gt;For hosting, I wanted a fully managed, modern cloud setup that eliminates infrastructure maintenance overhead while providing global scalability.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Frontend Hosting (Vercel):&lt;/strong&gt; The Next.js frontend is deployed on Vercel, providing global CDN distribution and world-class optimization for Next.js assets out of the box.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backend Hosting (Render):&lt;/strong&gt; The Express.js API runs on Render, managing web environments smoothly with auto-deployments from Git and managed SSL setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Health &amp;amp; Diagnostics (Uptime Monitoring):&lt;/strong&gt; To ensure high availability across this distributed setup, I implemented a robust uptime monitoring layer that pings the frontend endpoints and the underlying API services, alerting me the second a bottleneck occurs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mistakes I Made (And How I Fixed Them)
&lt;/h3&gt;

&lt;p&gt;No project is built from scratch without a few roadblocks. Here are the major pitfalls I encountered:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The Double-Caching Sync Dilemma:&lt;/strong&gt; Layering Next.js revalidation over an aggressive Redis cache meant that content updates were trapped behind two separate timers. Modifying database records sometimes wouldn't show up on the live UI for quite a long time due to cache stacking.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*   _The Fix (and Current Plan):_ Right now, the site relies on short, balanced time-to-live intervals. However, the long-term solution is already in the works: building a unified dynamic webhook pipeline. When data changes, a hook will trigger an automatic `DEL` command to the Redis key and simultaneously ping a Next.js API route handler to call `revalidatePath()` or `revalidateTag()`, flushing both layers instantly.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Over-Engineering the Backend Initially:&lt;/strong&gt; I started treating my personal API like an enterprise microservices platform, worrying about premature optimization before the core features were even stable.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*   _The Fix:_ I stripped it back to a clean, modular Express architecture. YAGNI (You Aren't Gonna Need It) applies to personal portfolios just as much as production SaaS products.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Handling Cold Starts on Managed Hosting:&lt;/strong&gt; When the API instances go quiet, spin-up times on managed cloud infrastructure can sometimes introduce latency for the first visitor.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*   &lt;em&gt;The Fix:&lt;/em&gt; I streamlined database connection pools, minimized the deployment bundle, and utilized the uptime monitoring pings as a dual-purpose "heartbeat" to ensure the API container stays warm, active, and snappy.&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Final Thoughts&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Building &lt;a href="https://shubhkumar.in" rel="noopener noreferrer"&gt;shubhkumar.in&lt;/a&gt; from scratch wasn't the fastest way to put a portfolio online, but it was easily the most rewarding. It forced me to think through the entire lifecycle of an application from building a multi-tier cache architecture to managing production cloud deployments.&lt;/p&gt;

&lt;p&gt;The best part? Because it’s driven by a single-source-of-truth API, it can power any future side project or subdomain I decide to build down the road.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>performance</category>
    </item>
    <item>
      <title>Moving from 60s to 6s: Latency Optimization Lessons from Functional Programming</title>
      <dc:creator>Shubham</dc:creator>
      <pubDate>Wed, 24 Jun 2026 10:36:02 +0000</pubDate>
      <link>https://dev.to/shubham399/moving-from-60s-to-6s-latency-optimization-lessons-from-functional-programming-2l7i</link>
      <guid>https://dev.to/shubham399/moving-from-60s-to-6s-latency-optimization-lessons-from-functional-programming-2l7i</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fa3fd104f-0205-458c-8c04-f27b97208493.png%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fa3fd104f-0205-458c-8c04-f27b97208493.png%2Fpublic" width="1152" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The broader tech community often views functional programming (FP) as an elegant academic exercise great for type systems, formal reasoning, and compiler guarantees, but less relevant to the realities of high-throughput production systems.&lt;/p&gt;

&lt;p&gt;That assumption is wrong.&lt;/p&gt;

&lt;p&gt;While optimizing a large-scale distributed workflow engine, we used PureScript and Haskell to rethink a legacy execution model, reducing end-to-end latency from roughly 60 seconds to under 6 seconds a nearly 90% improvement.&lt;/p&gt;

&lt;p&gt;This wasn't achieved through additional hardware, bigger databases, or infrastructure tuning. Instead, the gains came from applying a few core functional programming principles: non-blocking asynchronous effects, explicit modeling of side effects, and treating workflows as composable data structures.&lt;/p&gt;

&lt;p&gt;This is the engineering story behind that transformation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottleneck: Polling-Based Workflow Execution
&lt;/h2&gt;

&lt;p&gt;The original system relied on a pull-based worker architecture.&lt;/p&gt;

&lt;p&gt;Each request flowed through multiple sequential stages, including validation, business rule evaluation, external service interactions, state transitions, and final reconciliation.&lt;/p&gt;

&lt;p&gt;The execution model was built around a database-backed work queue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A worker completed a step and persisted the updated state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The next worker periodically polled the database for pending work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once discovered, it executed the next stage and persisted the result.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The process repeated until completion.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While this approach provided durability and operational simplicity, it introduced significant latency.&lt;/p&gt;

&lt;p&gt;Every stage depended on a polling interval before the next stage could begin. Even relatively small delays compounded across multiple workflow stages.&lt;/p&gt;

&lt;p&gt;As the number of sequential steps increased, the majority of request time was spent waiting for the next polling cycle rather than performing useful work.&lt;/p&gt;

&lt;p&gt;The system wasn't compute-bound.&lt;/p&gt;

&lt;p&gt;It was wait-bound.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Strategy: Introducing a Fast Execution Path
&lt;/h2&gt;

&lt;p&gt;To eliminate unnecessary waiting, we split execution into two distinct paths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A Fast Path optimized for low-latency request processing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Durable Path optimized for reliability, retries, and recovery.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than routing every request through the durable workflow engine immediately, the system first attempts direct execution using PureScript's &lt;code&gt;Aff&lt;/code&gt; runtime.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Aff&lt;/code&gt; provides lightweight, non-blocking asynchronous execution with structured error handling and resource safety.&lt;/p&gt;

&lt;p&gt;A typical request now follows a path similar to:&lt;/p&gt;

&lt;p&gt;Request&lt;br&gt;&lt;br&gt;
→ Validation&lt;br&gt;&lt;br&gt;
→ Business Rules&lt;br&gt;&lt;br&gt;
→ External Service Call&lt;br&gt;&lt;br&gt;
→ State Update&lt;br&gt;&lt;br&gt;
→ Response&lt;/p&gt;

&lt;p&gt;If all operations succeed, the request completes immediately without entering the background workflow system.&lt;/p&gt;

&lt;p&gt;By avoiding unnecessary persistence and polling between every stage, latency dropped dramatically.&lt;/p&gt;

&lt;p&gt;In the common success case, requests now completed in under six seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reliability Challenge
&lt;/h2&gt;

&lt;p&gt;Fast paths are easy to build.&lt;/p&gt;

&lt;p&gt;Reliable fast paths are significantly harder.&lt;/p&gt;

&lt;p&gt;Any optimization that bypasses durable infrastructure risks losing execution state when failures occur.&lt;/p&gt;

&lt;p&gt;To preserve reliability guarantees, we needed a mechanism that could seamlessly transition between immediate execution and durable recovery without introducing duplicate side effects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modeling Workflows as Data
&lt;/h2&gt;

&lt;p&gt;The solution was to represent workflow operations as a custom DSL built using algebraic data types and interpreted through a Free Monad.&lt;/p&gt;

&lt;p&gt;Instead of executing side effects directly, workflow steps were first modeled as data.&lt;/p&gt;

&lt;p&gt;Operations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reading state&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing state&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calling external services&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Running parallel computations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating workflow progress&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;were represented as declarative instructions.&lt;/p&gt;

&lt;p&gt;This separation between workflow definition and execution enabled a powerful capability: deterministic replay.&lt;/p&gt;

&lt;p&gt;As execution progressed, the interpreter recorded the result of completed operations.&lt;/p&gt;

&lt;p&gt;If an error occurred during fast-path execution, the current workflow state could be persisted and handed off to the durable execution engine.&lt;/p&gt;

&lt;p&gt;When processing resumed later:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Previously completed operations were replayed from recorded results.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Successful work was not re-executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execution continued from the exact point of failure.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allowed the system to combine low-latency execution with strong reliability guarantees while avoiding duplicate side effects.&lt;/p&gt;

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

&lt;p&gt;The biggest lesson wasn't simply that the system became faster.&lt;/p&gt;

&lt;p&gt;It was that functional programming provided architectural tools that made an entirely different execution model possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't Poll When You Can Propagate
&lt;/h3&gt;

&lt;p&gt;Polling introduces latency even when no real work is being done.&lt;/p&gt;

&lt;p&gt;For multi-stage workflows, event-driven execution often produces substantial performance improvements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separate Workflow Definition from Execution
&lt;/h3&gt;

&lt;p&gt;Representing workflows as data creates opportunities for replay, testing, simulation, recovery, and optimization that are difficult to achieve when side effects are tightly coupled to business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types Enable Architectural Confidence
&lt;/h3&gt;

&lt;p&gt;Strong type systems make it possible to build complex execution and recovery mechanisms with far greater confidence.&lt;/p&gt;

&lt;p&gt;Many categories of invalid state transitions and workflow bugs can be eliminated before code ever reaches production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Reducing latency from 60 seconds to 6 seconds wasn't primarily a performance-tuning exercise.&lt;/p&gt;

&lt;p&gt;It was the result of changing how the system modeled work.&lt;/p&gt;

&lt;p&gt;Functional programming provided the abstractions needed to separate business logic from execution, build reliable recovery mechanisms, and optimize the common path without sacrificing correctness.&lt;/p&gt;

&lt;p&gt;The next time someone describes functional programming as purely academic, consider that some of its most powerful ideas aren't about writing cleaner code.&lt;/p&gt;

&lt;p&gt;They're about building systems that are both fast and resilient at scale.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>programming</category>
      <category>performance</category>
    </item>
    <item>
      <title>The Disconnected Edge: How We Solved In-Flight Data Sync at 35,000 Feet</title>
      <dc:creator>Shubham</dc:creator>
      <pubDate>Sun, 14 Jun 2026 01:55:15 +0000</pubDate>
      <link>https://dev.to/shubham399/the-disconnected-edge-how-we-solved-in-flight-data-sync-at-35000-feet-4baf</link>
      <guid>https://dev.to/shubham399/the-disconnected-edge-how-we-solved-in-flight-data-sync-at-35000-feet-4baf</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fb805ea06-69a6-46ed-8545-f24e8e98ae9e.png%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fb805ea06-69a6-46ed-8545-f24e8e98ae9e.png%2Fpublic" width="1344" height="768"&gt;&lt;/a&gt;When most engineers think about deploying a modern application, they imagine a familiar setup: cloud infrastructure, global CDNs, auto-scaling services, and near-constant internet connectivity.&lt;/p&gt;

&lt;p&gt;The architecture patterns are well understood. If something goes wrong, the application can usually reach another service, retry a request, or fetch fresh data from the cloud.&lt;/p&gt;

&lt;p&gt;But what happens when your application spends most of its life completely disconnected from the internet?&lt;/p&gt;

&lt;p&gt;That's the challenge we faced while building a next-generation in-flight entertainment (IFE) platform.&lt;/p&gt;

&lt;p&gt;And it forced us to rethink some of our most fundamental assumptions about distributed systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Reality of Running Software on an Aircraft
&lt;/h2&gt;

&lt;p&gt;Our platform ran on embedded edge devices installed onboard commercial aircraft.&lt;/p&gt;

&lt;p&gt;These devices powered the entire passenger experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Movies and TV shows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Games&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Digital publications&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;E-commerce catalogs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passenger analytics&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operational data collection&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike a typical web application, however, these systems couldn't rely on continuous connectivity.&lt;/p&gt;

&lt;p&gt;For most of their operational life, they were completely isolated from the internet.&lt;/p&gt;

&lt;p&gt;Yet every day brought new content, software updates, pricing changes, configuration updates, and analytics data that needed to move between a central backend and hundreds of aircraft spread around the world.&lt;/p&gt;

&lt;p&gt;Building the application wasn't the hard part.&lt;/p&gt;

&lt;p&gt;Keeping everything synchronized was.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Cloud-Native Assumptions Stop Working
&lt;/h2&gt;

&lt;p&gt;Modern software architecture often assumes the network is always available.&lt;/p&gt;

&lt;p&gt;Applications are designed around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Real-time APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Continuous synchronization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloud-hosted storage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Immediate access to backend services&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our environment broke every one of those assumptions.&lt;/p&gt;

&lt;p&gt;Aircraft devices regularly experienced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Extended periods with no connectivity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Short and unpredictable synchronization windows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limited compute resources&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restricted power budgets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;High reliability requirements&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A failed synchronization couldn't leave a device in a broken state. Passengers still expected the system to work regardless of whether it had connected to the backend recently.&lt;/p&gt;

&lt;p&gt;That changed our design philosophy completely.&lt;/p&gt;




&lt;h2&gt;
  
  
  Designing for Offline First
&lt;/h2&gt;

&lt;p&gt;Instead of treating connectivity loss as an exception, we treated it as the default operating mode.&lt;/p&gt;

&lt;p&gt;Every aircraft device maintained its own local copy of everything it needed to operate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Application assets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Media content&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configuration data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transaction queues&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Analytics events&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The backend remained the source of truth, but the aircraft could continue operating independently for days or even weeks if necessary.&lt;/p&gt;

&lt;p&gt;Connectivity became a bonus rather than a requirement.&lt;/p&gt;

&lt;p&gt;This single mindset shift influenced almost every architectural decision that followed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Synchronization Became the Product
&lt;/h2&gt;

&lt;p&gt;In many systems, synchronization is a background task.&lt;/p&gt;

&lt;p&gt;For us, synchronization became one of the most critical parts of the platform.&lt;/p&gt;

&lt;p&gt;The workflow was intentionally simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The backend generated update manifests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Devices checked for available updates whenever connectivity existed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only changed assets were downloaded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Downloaded content was verified.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updates were applied atomically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Analytics and operational data were uploaded back to the backend.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal wasn't speed.&lt;/p&gt;

&lt;p&gt;The goal was reliability.&lt;/p&gt;

&lt;p&gt;If a network connection dropped halfway through a transfer, the device needed to recover gracefully and continue from where it left off.&lt;/p&gt;

&lt;p&gt;No corruption. No inconsistent state. No manual intervention.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Challenge of Moving Large Media Libraries
&lt;/h2&gt;

&lt;p&gt;One of the biggest engineering challenges involved content distribution.&lt;/p&gt;

&lt;p&gt;A typical update might contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Video files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Images&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Application bundles&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configuration changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Re-downloading everything every time simply wasn't realistic.&lt;/p&gt;

&lt;p&gt;Bandwidth was limited, synchronization windows were unpredictable, and some assets were extremely large.&lt;/p&gt;

&lt;p&gt;To make transfers practical, we relied heavily on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Manifest-driven synchronization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Content hashing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incremental downloads&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compression&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delta updates where possible&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The principle was straightforward:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transfer only what changed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That simple rule dramatically reduced synchronization times and bandwidth usage across the fleet.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building for Unreliable Networks
&lt;/h2&gt;

&lt;p&gt;Connectivity quality varied enormously.&lt;/p&gt;

&lt;p&gt;Sometimes devices synchronized over stable networks.&lt;/p&gt;

&lt;p&gt;Other times they relied on slow, intermittent cellular connections.&lt;/p&gt;

&lt;p&gt;The synchronization system had to assume failure could happen at any point.&lt;/p&gt;

&lt;p&gt;To handle this, we built in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Retry queues&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Checkpointed downloads&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Idempotent operations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrity verification&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automatic recovery mechanisms&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the most important requirements was ensuring that a failed synchronization never damaged the existing system.&lt;/p&gt;

&lt;p&gt;If an update couldn't be completed successfully, the device simply continued operating from its last known-good state.&lt;/p&gt;

&lt;p&gt;Passengers never noticed the difference.&lt;/p&gt;




&lt;h2&gt;
  
  
  Observability Without Real-Time Access
&lt;/h2&gt;

&lt;p&gt;One of the more interesting challenges wasn't deployment.&lt;/p&gt;

&lt;p&gt;It was debugging.&lt;/p&gt;

&lt;p&gt;Most modern observability platforms assume engineers can access telemetry in real time.&lt;/p&gt;

&lt;p&gt;That wasn't possible for us.&lt;/p&gt;

&lt;p&gt;Aircraft devices spent long periods disconnected, making live monitoring ineffective.&lt;/p&gt;

&lt;p&gt;Instead, devices accumulated operational information locally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Structured logs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Health metrics&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Synchronization reports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Diagnostic data&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whenever connectivity became available, this information was uploaded and aggregated centrally.&lt;/p&gt;

&lt;p&gt;The result wasn't real-time observability.&lt;/p&gt;

&lt;p&gt;It was delayed observability.&lt;/p&gt;

&lt;p&gt;And that required a different mindset when diagnosing production issues.&lt;/p&gt;




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

&lt;p&gt;Building systems for disconnected environments teaches lessons that are easy to overlook in cloud-first architectures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connectivity Is a Feature, Not a Guarantee
&lt;/h3&gt;

&lt;p&gt;Many applications assume the network will always be available.&lt;/p&gt;

&lt;p&gt;We learned to assume the opposite.&lt;/p&gt;

&lt;p&gt;Systems designed to function without connectivity are often more resilient overall.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idempotency Is Non-Negotiable
&lt;/h3&gt;

&lt;p&gt;When networks are unreliable, retries become routine.&lt;/p&gt;

&lt;p&gt;Every operation must be safe to execute multiple times.&lt;/p&gt;

&lt;p&gt;Without idempotency, synchronization quickly becomes a source of inconsistency and failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local-First Architectures Are Surprisingly Powerful
&lt;/h3&gt;

&lt;p&gt;Giving edge devices autonomy reduces dependency on centralized infrastructure.&lt;/p&gt;

&lt;p&gt;It improves user experience and limits the blast radius of failures.&lt;/p&gt;

&lt;p&gt;In many cases, it produces a more robust system than one that depends heavily on constant connectivity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simplicity Wins
&lt;/h3&gt;

&lt;p&gt;The most reliable parts of our platform weren't the most sophisticated.&lt;/p&gt;

&lt;p&gt;They were the simplest.&lt;/p&gt;

&lt;p&gt;Clear manifests, atomic updates, strong validation, and predictable workflows consistently outperformed more complex approaches.&lt;/p&gt;

&lt;p&gt;Reliability often comes from reducing complexity rather than adding it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;A lot of modern engineering focuses on scaling cloud infrastructure.&lt;/p&gt;

&lt;p&gt;But some of the most interesting distributed systems problems exist far from the cloud at the edge, where connectivity is intermittent, resources are constrained, and reliability matters more than raw throughput.&lt;/p&gt;

&lt;p&gt;Building software for aircraft forced us to rethink assumptions about deployment, networking, observability, and synchronization.&lt;/p&gt;

&lt;p&gt;The result was a platform capable of operating independently for extended periods while staying synchronized with a centralized backend whenever connectivity became available.&lt;/p&gt;

&lt;p&gt;And while the environment was unique, the lessons weren't.&lt;/p&gt;

&lt;p&gt;Whether you're building for aircraft, ships, remote industrial sites, IoT devices, or any other disconnected environment, the same principle applies:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design for a world where the network isn't guaranteed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everything else becomes easier after that.&lt;/p&gt;

</description>
      <category>edgecomputing</category>
      <category>distributedsystems</category>
      <category>offlinefirst</category>
    </item>
    <item>
      <title>Turning Your AI Into an Adversarial Security Agent: The SKILLS.md Framework</title>
      <dc:creator>Shubham</dc:creator>
      <pubDate>Sun, 07 Jun 2026 09:18:06 +0000</pubDate>
      <link>https://dev.to/shubham399/turning-your-ai-into-an-adversarial-security-agent-the-skillsmd-framework-2058</link>
      <guid>https://dev.to/shubham399/turning-your-ai-into-an-adversarial-security-agent-the-skillsmd-framework-2058</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2F3f9a92b5-1a1a-4de4-ab07-e5b347d1b179.png%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2F3f9a92b5-1a1a-4de4-ab07-e5b347d1b179.png%2Fpublic"&gt;&lt;/a&gt;A continuation of: &lt;a href="https://www.shubhkumar.in/blogs/breaking-to-build-how-ctf-and-bug-bounty-hunting-rewires-system-design" rel="noopener noreferrer"&gt;&lt;em&gt;Breaking to Build: How CTF and Bug Bounty Hunting Rewires System Design&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my previous article, I explored how offensive security permanently changes the way engineers think about systems. Once you've spent enough time exploiting race conditions, bypassing authorization boundaries, abusing SSRF chains, and breaking assumptions hidden deep inside application logic, you stop viewing software as a collection of features.&lt;/p&gt;

&lt;p&gt;You start viewing it as an &lt;strong&gt;attack surface&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That shift fundamentally changes how you design production systems. The problem is that modern software development is no longer purely human-driven. Today, a massive percentage of engineering work happens alongside AI coding assistants. Tools now generate thousands of lines of code faster than most engineers can review them.&lt;/p&gt;

&lt;p&gt;And that introduces a brand new problem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI systems are optimized for one thing:&lt;/strong&gt; Generate code that works.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Attackers are optimized for something completely different:&lt;/strong&gt; Find code that breaks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That difference matters. A generated API endpoint might pass every functional test while still exposing a devastating BOLA (Broken Object Level Authorization) vulnerability. A generated webhook handler might function perfectly while allowing SSRF into your internal infrastructure. A generated payment workflow might appear correct while collapsing into a double-spend condition under concurrent execution.&lt;/p&gt;

&lt;p&gt;The code works. The architecture fails. And that is exactly where real-world vulnerabilities are born.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Missing Layer in AI-Assisted Development
&lt;/h2&gt;

&lt;p&gt;Most teams currently treat AI coding agents like extremely fast junior engineers. They give them instructions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;"Build this feature"&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;"Refactor this service"&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;"Create this migration"&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model responds by optimizing for correctness, readability, and implementation speed. Security is rarely treated as a first-class objective.&lt;/p&gt;

&lt;p&gt;Most AI systems are never explicitly taught to think like attackers. They are taught how software &lt;em&gt;should&lt;/em&gt; behave; they are not taught how software is &lt;em&gt;abused&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That distinction becomes increasingly dangerous as organizations move toward autonomous code generation, AI-assisted architecture, and agentic development workflows.&lt;/p&gt;

&lt;p&gt;The solution turns out to be surprisingly simple: instead of prompting for features alone, we inject a persistent security reasoning framework directly into the agent's operating context.&lt;/p&gt;

&lt;p&gt;That framework is &lt;strong&gt;SKILLS.md&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is SKILLS.md?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;SKILLS.md&lt;/code&gt; is a structured operational framework that teaches an AI agent how to evaluate software through an adversarial lens. It is not a prompt, a simple checklist, or another copy-paste of the OWASP Top 10. It is a behavioral framework that continuously pushes the model to ask &lt;strong&gt;"How would an attacker abuse this?"&lt;/strong&gt; &lt;em&gt;before&lt;/em&gt; it asks &lt;strong&gt;"How do I implement this?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The goal is to transplant the mindset developed through years of CTF competitions, bug bounty hunting, and incident response directly into the AI’s reasoning process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Traditional Security Checklists Fail
&lt;/h3&gt;

&lt;p&gt;Most security documentation focuses on known vulnerability categories (XSS, SQLi, CSRF, SSRF, IDOR). These are important, but attackers rarely think in categories. &lt;strong&gt;They think in assumptions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every vulnerability exists because somebody assumed something was true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;The frontend won't send invalid values.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Only authenticated users can reach this endpoint.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;This request executes once at a time.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Nobody can access that internal network.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bug bounty hunting teaches you something uncomfortable: assumptions are where systems fail. Security is often less about blocking payloads and more about eliminating dangerous assumptions. &lt;code&gt;SKILLS.md&lt;/code&gt; is built entirely around that philosophy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Evolution From Builder To Breaker
&lt;/h2&gt;

&lt;p&gt;Plaintext&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traditional Engineering:
Requirement ──&amp;gt; Implementation ──&amp;gt; Testing ──&amp;gt; Deployment

Security-Oriented Engineering:
Requirement ──&amp;gt; Implementation ──&amp;gt; Abuse Analysis ──&amp;gt; Boundary Verification ──&amp;gt; Concurrency Analysis ──&amp;gt; Deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first workflow asks: &lt;em&gt;Does this feature work?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The second asks: &lt;em&gt;What happens when somebody intentionally tries to break it?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SKILLS.md&lt;/code&gt; forces AI agents into the second mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Specifications: SKILLS.md
&lt;/h2&gt;

&lt;p&gt;Modern AI tools and tools like &lt;strong&gt;Claude Code&lt;/strong&gt; have evolved past static, single-file home directory configurations. They utilize the &lt;strong&gt;Agent Skills Standard&lt;/strong&gt;, which relies on a nested folder footprint (&lt;code&gt;skills/&amp;lt;skill-name&amp;gt;/SKILL.md&lt;/code&gt;) and mandatory &lt;strong&gt;YAML frontmatter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The frontmatter contains semantic metadata. When you start an AI session, the engine scans the &lt;code&gt;description&lt;/code&gt; block to automatically determine &lt;em&gt;when&lt;/em&gt; to pull this skill into context.&lt;/p&gt;

&lt;p&gt;Here is the production-ready implementation file.&lt;/p&gt;

&lt;p&gt;Markdown&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="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;secure&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Evaluates&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;software&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;architecture&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;through&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;an&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;adversarial&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;lens.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Automatically&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;invokes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;when&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;generating&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;APIs,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;designing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;features,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;reviewing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;managing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;authentication,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;state,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;boundaries."&lt;/span&gt;
&lt;span class="na"&gt;user-invocable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;# Security-First Architecture Skill&lt;/span&gt;

&lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="nv"&gt;*Axiom&lt;/span&gt;&lt;span class="s"&gt;:** Inputs malicious. Clients untrusted. Networks hostile. Dependencies may be compromised. Never trust; always verify at execution point.&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;## Domain Controls&lt;/span&gt;

&lt;span class="pi"&gt;|&lt;/span&gt; &lt;span class="c1"&gt;# | Domain | Attacks | Key Controls | Core Question |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt;---|--------|---------|-------------|---------------|&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 1 | **State / Race** | TOCTOU, double-spend, optimistic-lock loss | `SELECT FOR UPDATE`; distributed lock (Redis `SET NX PX`); validate ETag every write | Can same op succeed twice in parallel, or state change between check and act? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 2 | **AuthZ / BOLA** | IDOR, BOLA, mass assignment, GraphQL introspection | Ownership check at data layer, not route; allowlist binding (strong_params/Pydantic DTO); disable introspection in prod; tenant-scope every query | What changes if resource ID or any request field changes? Who verified ownership? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 3 | **SSRF** | Metadata endpoint, DNS rebind, redirect chain, `gopher://` | Resolve DNS → re-validate IP vs RFC-1918+169.254+fc00 denylist; allowlist domains; HTTPS-only via egress proxy; proxy follows redirects, not app code | Who controls final destination after DNS resolution and redirects? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 4 | **Path Traversal** | `../../`, URL-encode, null byte, Zip Slip, symlink | `realpath()`/`Path.resolve()` → verify under root; never concat user input to paths; use UUIDs as storage keys; validate archive entries before extract | Can user-controlled string, after normalization, escape storage boundary? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 5 | **Blast Radius** | Lateral movement, over-permissive IAM, credential reuse | Non-root containers, read-only rootfs, `--cap-drop ALL`; per-service least-privilege IAM; separate creds per env/service; mTLS between services | If this service is fully compromised, what else is reachable without new creds? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 6 | **Fail-Closed** | Broad catch-continue, feature-flag default-on, null bypass | Default DENY in every auth check, exception block, conditional; feature flags off for security features; `default: deny` in all security-relevant switches | What does system permit on unexpected error, null, or undefined in auth path? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 7 | **Secrets / Crypto** | Log leak, `alg:none` JWT, weak HMAC, IV reuse, timing oracle, weak PRNG | Secrets Manager + rotation; CSPRNG only; pin JWT alg server-side; RS256/ES256 cross-service; `timingSafeEqual`; AES-256-GCM unique nonces; ban MD5/SHA-1/DES/RC4 | Can credential be recovered, forged, or brute-forced from token, log, or build output? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 8 | **Supply Chain** | Typosquat, dep-confusion, `postinstall` RCE, unpinned deps | Exact-version pin + lockfile; verify signatures/hashes; audit `postinstall` scripts; private registry namespace; `npm audit`/`pip-audit`/`cargo audit` in CI | What third-party code executes in build/runtime that we don't own and audit? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 9 | **Event Integrity** | Replay, out-of-order, schema-invalid crash, webhook spoof | Idempotency keys (Redis TTL); strict schema → DLQ on malformed; HMAC-SHA256 webhook sig + 5-min timestamp window; sequence numbers for ordering | Can replaying/reordering an event corrupt state? Is every inbound event cryptographically authenticated? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 10 | **LLM / AI** | Prompt injection (direct/indirect), agentic tool abuse, secondary injection | Treat model output as untrusted input; explicit tool-auth gateway per user permission; strict output schema (JSON Schema/Pydantic); human-in-loop for irreversible actions; no ambient creds in agent env | What auth boundaries exist between model output and execution? Can injected content in retrieved data override system instructions? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 11 | **Injection** | SQLi, XSS, CMDi, SSTI, XXE, NoSQLi, ReDoS | Parameterized queries; `execFile([...])` not `exec(string)`; context-aware output encoding; disable XML external entities; reject `$`-prefix JSON keys; audit regexes for backtracking; never eval user input in templates | Does any user-controlled string reach an interpreter without structural separation? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 12 | **AuthN / Session / OAuth** | Credential stuffing, session fixation, missing server-side invalidation, redirect-URI wildcard, missing PKCE, token-in-URL | CSPRNG session tokens; rotate on login/priv-escalation; server-side invalidation on logout; `Secure;HttpOnly;SameSite=Strict`; Argon2id (64MB/3-iter) or bcrypt≥12; exact-match `redirect_uri`; PKCE for public clients; bind `state` to session; identical error messages + timing | Can attacker reuse, predict, fix, or intercept session/token/auth-code without knowing original secret? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 13 | **Log Exposure** | Credential leak, PII capture, log forgery via `\n\r`, stack-trace disclosure | Scrub tokens/JWTs/keys/PAN/SSN/email before every log write; allowlist loggable fields; sanitize `\n\r\033` in user input; disable verbose stack traces in prod responses | If every log line leaked, what sensitive data would be visible? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 14 | **Deserialization** | pickle/ObjectInputStream/`yaml.load`/Marshal RCE, gadget chains, DoS via nested structures | Never deserialize untrusted data with native formats; use JSON/Protobuf + schema validation; if unavoidable: allowlist filter + HMAC-sign payload; always `yaml.safe_load` | Does any code path deserialize attacker-influenced data with a class-instantiating deserializer? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 15 | **Rate Limits / DoS** | Credential stuffing, ReDoS, zip bomb, billion-laughs, large upload, unbounded pagination | Rate limits per-IP + per-user at gateway and app; tightest on auth/reset/OTP; cap body/upload size at ingress; GraphQL depth+complexity limits; timeouts on all external calls + queries; queue expensive ops; `limit ≤ 100` on pagination; return 429 + `Retry-After` | Can a single actor trigger resource consumption that degrades availability for others? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 16 | **HTTP Controls** | CORS credential theft, XSS via missing CSP, clickjacking, MIME-sniff bypass, SSL-strip | Exact-origin CORS allowlist (never reflect `Origin`, never `*` + credentials); HSTS `max-age=63072000;includeSubDomains;preload`; CSP allowlist `script-src`, no `unsafe-inline/eval`; `X-Content-Type-Options:nosniff`; `X-Frame-Options:DENY`; `Referrer-Policy:strict-origin-when-cross-origin`; `__Host-` cookie prefix | Can cross-origin page, framed page, or MIME-sniffed resource exploit browser trust in this origin? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 17 | **File Upload** | Zip Slip, polyglot exec, oversized upload, SVG XSS, archive bomb | UUID storage keys (never user filename); separate origin (S3 bucket/CDN subdomain) + `Content-Disposition:attachment`; validate by magic bytes not MIME; enforce size+count at ingress; reject SVG/HTML or sanitize with DOMPurify; cap archive extraction size + entry count | Can an uploaded file execute code, escape storage, or gain application-origin trust? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 18 | **Info Disclosure** | Stack traces, version headers, debug endpoints, username enum, timing leak | Opaque error IDs to clients, full detail server-side only; remove `Server`/`X-Powered-By`/`X-AspNet-Version`; disable debug/admin/introspection in prod (fail startup if debug=prod); identical error messages + response times; scan for exposed debug routes | Does any response, header, error, or timing difference reveal internal structure to unauthorized caller? |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; 19 | **Build Pipeline** | Compromised CI, over-permissive build IAM, unsigned images, secrets in logs, fork PR secret leak | Pin CI actions to commit SHAs; secrets only on protected branches; read-only source + write-only artifact IAM for build; sign images (cosign/Sigstore) + verify at deploy; OIDC ephemeral creds (no long-lived keys); branch protection: review + CI + signed commits required | Can compromised dependency update, CI job, or PR introduce malicious code reaching production without human review? |&lt;/span&gt;

&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="s"&gt;--&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="s"&gt;# Verification Protocol (run sequentially on every review/design)&lt;/span&gt;

&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="s"&gt;. **Trust Boundaries**   map all input sources (HTTP, queues, webhooks, files, env); strip all safety assumptions&lt;/span&gt;
&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="s"&gt;. **Concurrency**   find TOCTOU windows; verify DB-level locking on every state mutation&lt;/span&gt;
&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="s"&gt;. **AuthZ**   confirm ownership check at data-access layer, not route layer, on every request&lt;/span&gt;
&lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="s"&gt;. **Privileges**   least-privilege IAM, service accounts, container caps, DB permissions&lt;/span&gt;
&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="s"&gt;. **Blast Radius**   full compromise simulation: map reachable services/creds/data without new credentials&lt;/span&gt;
&lt;span class="err"&gt;6&lt;/span&gt;&lt;span class="s"&gt;. **Interpreter Paths**   trace user input to SQL/shell/template/XML/YAML/pickle; confirm structural separation&lt;/span&gt;
&lt;span class="err"&gt;7&lt;/span&gt;&lt;span class="s"&gt;. **Auth Surface**   session lifecycle (issue→rotate→invalidate), MFA, OAuth parameter binding, credential storage&lt;/span&gt;
&lt;span class="err"&gt;8&lt;/span&gt;&lt;span class="s"&gt;. **Log Audit**   confirm no secrets/PII/payment/raw bodies in any log path including error handlers and APM agents&lt;/span&gt;
&lt;span class="err"&gt;9&lt;/span&gt;&lt;span class="s"&gt;. **Rate Controls**   sensitive endpoints have per-user + per-IP limits; expensive ops queued with concurrency caps&lt;/span&gt;
&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="s"&gt;0. **HTTP Controls**   CORS allowlist, security headers, CSP, no verbose error leakage on all response paths&lt;/span&gt;
&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="s"&gt;1. **Upload &amp;amp; Deserialization**   files stored outside app origin with server-generated keys; no native deserializer on untrusted data&lt;/span&gt;
&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="s"&gt;2. **Build Pipeline**   CI secrets scoped, actions SHA-pinned, images signed and verified at deploy&lt;/span&gt;

&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s"&gt; **Target:** Code that behaves predictably when an adversary is actively attempting to shatter it.&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installation Guide
&lt;/h2&gt;

&lt;p&gt;To ensure your AI assistant picks up this framework without breaking file path scopes, use the explicit terminal setups below depending on your favorite environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Claude Code
&lt;/h3&gt;

&lt;p&gt;Claude Code evaluates configurations from your global home configuration space (&lt;code&gt;~/.claude&lt;/code&gt;) or local workspaces (&lt;code&gt;.claude&lt;/code&gt;).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Global Installation&lt;/strong&gt; &lt;em&gt;(Applies across all code repositories on your machine without altering git states)&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;Bash&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p ~/.claude/skills/security-review
# Save the Markdown block above into this file:
nano ~/.claude/skills/security-review/SKILL.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;**&lt;/span&gt;Project-Specific Installation&lt;span class="k"&gt;**&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;Committed directly into git to enforce security rules across the whole engineering team&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
  mkdir -p .claude/skills/security-review&lt;br&gt;
  nano .claude/skills/security-review/SKILL.md&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
### 2\. Cursor (and custom IDEs)

Cursor indexes markdown definitions gracefully via workspace indexing or dedicated custom instructions.

Bash

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
shell&lt;br&gt;
mkdir -p .cursor/skills/security-review&lt;br&gt;
nano .cursor/skills/security-review/SKILL.md&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
_(Alternatively, you can save it as a top-level_ `SKILLS.md` _file in your root workspace)._

### 3\. Orchestrated Agent Frameworks (CrewAI / LangGraph)

For autonomous multi-agent pipelines, pass the file directly as system background data inside your orchestration configuration:

YAML

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
yaml&lt;br&gt;
agent:&lt;br&gt;
  role: Adversarial Security Auditor&lt;br&gt;
  backstory: You analyze architectural code changes strictly through the lens of SKILLS.md rules.&lt;br&gt;
  instructions:&lt;br&gt;
    - Ingest the custom SKILLS.md baseline constraints.&lt;br&gt;
    - Check every generated code route against Concurrency and Trust Boundaries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
## How to Use the Framework

Once installed, you don’t need to repeatedly copy-paste security prompts. The framework leverages both passive and active execution behaviors.

### Method A: Automated Semantic Triggering (Passive Mode)

Because the custom frontmatter contains a deep `description` string, the AI continuously evaluates your inputs. If you type a standard prompt that crosses defensive boundaries, the engine auto-activates the skill behind the scenes.

*   **Your Prompt:** _"Write an endpoint that takes a user's uploaded image URL, downloads it, and processes metadata."_

*   **The AI's Internal Action:** The engine intercepts words like _URL_ and _downloads_. It auto-loads `security-review` from disk, catches the **SSRF / Deterministic Routing** rule, and adds domain validation code before outputting the feature.


### Method B: Manual Slash Invocation (Active Mode)

If you want to explicitly mandate an application review, call the skill directly via standard interface paths.

*   **In Claude Code:** Use the custom command shortcut directly inside your terminal session:

    Bash

    ```


    /security-review Review our new database migration file for potential data isolation vulnerabilities.


    ```


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
plaintext&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In Cursor Composer:&lt;/strong&gt; Force index mapping by targeting the file handle directly inside the chat bar:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Please build out our stripe payment callback router following the criteria defined in @SKILL.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real-World Transformations: Before and After
&lt;/h2&gt;

&lt;p&gt;When &lt;code&gt;SKILLS.md&lt;/code&gt; is active, the agent stops acting like a passive code generator and starts acting like an unyielding architecture reviewer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: Payment Balance Deduction
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Without SKILLS.md:&lt;/strong&gt; The user asks for a simple point redemption function. The AI generates a standard &lt;code&gt;SELECT balance&lt;/code&gt; followed by an &lt;code&gt;UPDATE balance&lt;/code&gt; sequence. It looks clean, passes unit tests, but immediately falls to a race condition exploit when a user executes parallel curl requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;With SKILLS.md:&lt;/strong&gt; The agent's internal reasoning detects a state change trigger. It forces the SQL generation to include row-level isolation via &lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt; or requires a strict &lt;code&gt;Idempotency-Key&lt;/code&gt; header transaction check.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: User-Configured Webhooks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Without SKILLS.md:&lt;/strong&gt; The user prompts the AI to build an outbound webhook engine so users can get alerts. The AI uses a simple Axios/Fetch call passing the target parameter. An attacker signs up, sets their webhook to &lt;code&gt;[http://169.254.169.254/latest/meta-data/](http://169.254.169.254/latest/meta-data/)&lt;/code&gt;, and extracts cloud infrastructure IAM keys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;With SKILLS.md:&lt;/strong&gt; The agent flags the user-controlled URL routing pattern. It refuses to output the code until it builds an accompanying domain allowlist check, wraps the execution in an isolated egress proxy, or isolates the protocol rules.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Bigger Shift
&lt;/h2&gt;

&lt;p&gt;Today, engineers review AI-generated code. Tomorrow, AI systems will review AI-generated code. Eventually, entire engineering workflows will become completely autonomous.&lt;/p&gt;

&lt;p&gt;When that happens, security can no longer exist as an afterthought or a final manual compliance checklist performed at the tail end of a sprint. It has to become a core property of the AI's internal reasoning loop.&lt;/p&gt;

&lt;p&gt;AI does not automatically inherit security instincts. It inherits whatever mental models we explicitly give it. If you train an AI to think only like an engineer, it will build systems. If you train it to think like an attacker, it will help you build &lt;strong&gt;resilient&lt;/strong&gt; systems.&lt;/p&gt;

&lt;p&gt;The future belongs to the teams that can do both. Secure software is not created by accident; it is forged when someone spends enough time thinking about how it breaks first.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>llm</category>
      <category>promptengineering</category>
    </item>
    <item>
      <title>Breaking to Build: How CTF and Bug Bounty Hunting Rewires System Design</title>
      <dc:creator>Shubham</dc:creator>
      <pubDate>Sun, 31 May 2026 18:50:37 +0000</pubDate>
      <link>https://dev.to/shubham399/breaking-to-build-how-ctf-and-bug-bounty-hunting-rewires-system-design-2j7c</link>
      <guid>https://dev.to/shubham399/breaking-to-build-how-ctf-and-bug-bounty-hunting-rewires-system-design-2j7c</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2F9824899b-3ed9-4d61-8e5a-d49568803653.png%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2F9824899b-3ed9-4d61-8e5a-d49568803653.png%2Fpublic" alt="feature image"&gt;&lt;/a&gt;As software engineers, we are trained to be creators. We stare at a product requirement document, map out the happy path, write the logic, pass the unit tests, and ship it. Our default mental model is constructive: &lt;em&gt;How do I make this system work?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But if you have ever spent a weekend hunting for bugs on a crowdsourced bounty platform or staying up until 3 AM playing a Capture The Flag (CTF) competition, your brain undergoes a permanent structural shift. You stop looking at code exclusively as an implementation of business requirements. Instead, you start looking at it as an attack surface.&lt;/p&gt;

&lt;p&gt;Playing on the offensive side of security completely changes the way I write code and architect distributed systems. The moment my fingers leave the keyboard after implementing a new feature, a second thought instantly kicks in: &lt;strong&gt;"If I were targeting this system, how would I break what I just wrote?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here are the core system design lessons that offensive security beats into your engineering instincts.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Eradicating the Myth of the "Trusted Database"
&lt;/h2&gt;

&lt;p&gt;A classic flaw in traditional software engineering is the reliance on implicit trust boundaries. Developers are naturally paranoid about direct user inputs (like a POST request body), but they tend to drop their guard once data is written to the database. They treat data returned from a &lt;code&gt;SELECT&lt;/code&gt; query as inherently "safe."&lt;/p&gt;

&lt;p&gt;An attacker who understands vulnerabilities like &lt;strong&gt;SSTI (Server-Side Template Injection)&lt;/strong&gt; or &lt;strong&gt;Stored XSS&lt;/strong&gt; knows exactly how to exploit this complacency. They will inject a payload into a benign-looking field (like a profile username or an address line), let it sit quietly in your database, and wait for your backend to fetch it later and drop it un-sanitized into a high-privilege processing sink or HTML rendering engine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Attacker Payload] ──► [Inbound Request] ──► [Database (Stored Plaintext)]
                                                    │
                                        Backend fetches data later
                                                    │
                                                    ▼
[Malicious Execution Sink] ◄── [No Validation] ◄── [App Read Layer]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CTF experience forces you to adopt a strict &lt;strong&gt;Zero-Trust Input/Reflection Policy&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Every data point entering a processing context-whether it came from an unauthenticated webhook, a secure API call, or was reflected out of your own PostgreSQL database-is treated as radioactive untrusted data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sanitization and structural typing must happen not just at the network perimeter, but at the &lt;em&gt;boundary of every execution sink&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Eliminating IDOR by Architecting Hard Boundaries
&lt;/h2&gt;

&lt;p&gt;Insecure Direct Object References (IDOR) routinely sit at the top of real-world bug bounty payouts because they are incredibly easy to exploit but devastating in execution. An IDOR happens when a system exposes a direct reference to an internal database record (like an incremental integer or a plain UUID) via an API endpoint, and fails to validate if the requesting user actually owns that resource.&lt;/p&gt;

&lt;p&gt;A typical developer might implement a endpoint like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /api/v1/organization/getDetails?orgId=5690&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To an engineer with a bug bounty mindset, seeing an &lt;code&gt;orgId&lt;/code&gt; or &lt;code&gt;userId&lt;/code&gt; exposed directly in a query parameter or a mutable request header instantly triggers a red flag. It shouts: &lt;em&gt;“Change this number, read someone else’s data.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To completely engineer past this vulnerability, you shift the source of truth entirely away from client-controlled variables. Instead of trusting the request parameters to tell you who the organization or user is, you pull those identity markers exclusively from a &lt;strong&gt;cryptographically signed session context&lt;/strong&gt; or an immutable JWT verified at the gateway level.&lt;/p&gt;

&lt;p&gt;If the client wants to see their organization details, they call:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /api/v1/organization/myDetails&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The backend looks up the authentication session token, extracts the immutable, verified &lt;code&gt;orgId&lt;/code&gt; bound to that active session token, and queries the database using that token. The user can manipulate the HTTP parameters all they want; they can never force an out-of-bounds state transition because they don't control the variables powering the query.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Anticipating SSRF and CSRF in Component Design
&lt;/h2&gt;

&lt;p&gt;When you have spent hours constructing complex payloads to bypass firewalls in an &lt;strong&gt;SSRF (Server-Side Request Forgery)&lt;/strong&gt; challenge, you design internal networking components differently.&lt;/p&gt;

&lt;p&gt;If your backend needs to support a webhook notification feature or pull an image from a user-supplied URL, a non-security background might just use a standard HTTP client library to fire off the request. But an offensive mindset immediately foresees the vulnerability: an attacker passing &lt;code&gt;http://127.0.0.1:8500/&lt;/code&gt; or an internal AWS metadata endpoint (&lt;code&gt;http://169.254.169.254/&lt;/code&gt;) to scan your internal VPC from the inside out.&lt;/p&gt;

&lt;p&gt;Knowing this, you build defensiveness directly into your infrastructure blueprints: isolating egress traffic for user-supplied URLs to sandboxed network zones, enforcing strict DNS resolution checks against private IP ranges, and implementing secure Cross-Site Request Forgery (CSRF) tokens on all state-changing endpoints from day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Verdict: Offensive Experience is a Defensive Superpower
&lt;/h2&gt;

&lt;p&gt;You can read every security checklist, memorize the OWASP Top 10, and mandate static analysis tools across your CI/CD pipeline-but nothing replaces the deep architectural paranoia gained by actively breaking systems.&lt;/p&gt;

&lt;p&gt;Playing CTFs and hunting bounties teaches you to read between the lines of your own source code. It transforms security from a tedious, compliance-driven box to check before a release into a continuous, active thread running through your entire system design process.&lt;/p&gt;

&lt;p&gt;When you learn how to think like a breaker, you become an infinitely better builder.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ctf</category>
      <category>bugbounty</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Demystifying the Trinity: Functor, Applicative, and Monad in PureScript</title>
      <dc:creator>Shubham</dc:creator>
      <pubDate>Sat, 30 May 2026 04:24:48 +0000</pubDate>
      <link>https://dev.to/shubham399/demystifying-the-trinity-functor-applicative-and-monad-in-purescript-30m9</link>
      <guid>https://dev.to/shubham399/demystifying-the-trinity-functor-applicative-and-monad-in-purescript-30m9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fb545b1ef-a366-4f45-ae19-d8165269457d.png%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fb545b1ef-a366-4f45-ae19-d8165269457d.png%2Fpublic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When diving into pure functional programming, you are immediately confronted with three abstract terms that sound more like advanced physics concepts than software engineering patterns: &lt;strong&gt;Functors&lt;/strong&gt;, &lt;strong&gt;Applicatives&lt;/strong&gt;, and &lt;strong&gt;Monads&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a long time, the internet has tried to explain them using metaphors like "burrito boxes" or "spaceships." Based on my experience and everyday usage, it is much better to look at them for what they truly are: &lt;strong&gt;elegant design patterns for managing data flow, context, and computation with mathematical certainty.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s break down this holy trinity of functional programming using clean, practical PureScript examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Concept: Values in a Context
&lt;/h2&gt;

&lt;p&gt;Before writing code, let’s establish a visual mental model. In PureScript, we often deal with values wrapped inside a &lt;strong&gt;context&lt;/strong&gt; (or container).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Maybe a&lt;/code&gt; represents a value of type &lt;code&gt;a&lt;/code&gt; that &lt;em&gt;might be missing&lt;/em&gt; (handling &lt;code&gt;null&lt;/code&gt; safely).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Either e a&lt;/code&gt; represents a computation that &lt;em&gt;might fail&lt;/em&gt; with an error of type &lt;code&gt;e&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Effect a&lt;/code&gt; represents a synchronous side-effect (like logging to the console or interacting with the DOM).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Trinity-Functor, Applicative, and Monad-are simply a progressive set of tools that allow us to manipulate these wrapped values without manually unwrapping and re-wrapping them at every single step.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Functor: Mapping over a Context
&lt;/h2&gt;

&lt;p&gt;The simplest abstraction is the &lt;strong&gt;Functor&lt;/strong&gt;. A Functor allows you to apply a normal, pure function to a value that is sitting inside a context.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Definition
&lt;/h3&gt;

&lt;p&gt;To be a Functor, a type constructor &lt;code&gt;f&lt;/code&gt; must implement the &lt;code&gt;map&lt;/code&gt; function (often written as the infix operator &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Code snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;Functor&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage Example
&lt;/h3&gt;

&lt;p&gt;Imagine you are processing a transaction payload where the payment amount might be missing (&lt;code&gt;Maybe Int&lt;/code&gt;). You want to convert this amount into cents (multiply by 100).&lt;/p&gt;

&lt;p&gt;Code snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Main where

import Prelude
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Effect.Console (logShow)

-- A pure function that knows nothing about contexts
toCents :: Int -&amp;gt; Int
toCents dollar = dollar * 100

main :: Effect Unit
main = do
  let dynamicAmount = Just 50  -- A value inside a context
  let missingAmount = Nothing  -- An empty context

  -- Using map (&amp;lt;$&amp;gt;) to apply the pure function inside the context
  logShow (toCents &amp;lt;$&amp;gt; dynamicAmount) -- Output: (Just 5000)
  logShow (toCents &amp;lt;$&amp;gt; missingAmount) -- Output: Nothing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Crucial Insight:&lt;/strong&gt; Notice how &lt;code&gt;toCents&lt;/code&gt; takes a raw &lt;code&gt;Int&lt;/code&gt;, not a &lt;code&gt;Maybe Int&lt;/code&gt;. The Functor instance for &lt;code&gt;Maybe&lt;/code&gt; automatically handles the plumbing. If it’s &lt;code&gt;Just&lt;/code&gt;, it applies the function. If it’s &lt;code&gt;Nothing&lt;/code&gt;, it short-circuits safely.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Applicative: Function and Value Both in Contexts
&lt;/h2&gt;

&lt;p&gt;What happens if the function &lt;em&gt;itself&lt;/em&gt; is trapped inside a context? Or what if you want to apply a pure function that takes &lt;em&gt;multiple&lt;/em&gt; arguments to multiple wrapped values? This is where Functor falls short, and &lt;strong&gt;Applicative&lt;/strong&gt; steps in.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Definition
&lt;/h3&gt;

&lt;p&gt;An Applicative Functor extends Functor with two main functions: &lt;code&gt;pure&lt;/code&gt; (to lift a raw value into a context) and &lt;code&gt;apply&lt;/code&gt; (written as &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Code snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;Functor&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="kt"&gt;Applicative&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;pure&lt;/span&gt;  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
  &lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage Example
&lt;/h3&gt;

&lt;p&gt;Suppose we are building a user profile record from an API response. We have a pure data constructor &lt;code&gt;createUser&lt;/code&gt; that takes a &lt;code&gt;String&lt;/code&gt; (Name) and an &lt;code&gt;Int&lt;/code&gt; (User ID). However, both pieces of data are fetched independently and arrive wrapped in a &lt;code&gt;Maybe&lt;/code&gt; context.&lt;/p&gt;

&lt;p&gt;Code snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type User = { name :: String, id :: Int }

createUser :: String -&amp;gt; Int -&amp;gt; User
createUser name id = { name: name, id: id }

main :: Effect Unit
main = do
  let maybeName = Just "Alice"
  let maybeId   = Just 1024

  -- Functor + Applicative in harmony:
  -- 1. `createUser &amp;lt;$&amp;gt; maybeName` maps the first argument, returning: Maybe (Int -&amp;gt; User)
  -- 2. We use `&amp;lt;*&amp;gt;` to apply the remaining wrapped Int argument.
  let maybeUser = createUser &amp;lt;$&amp;gt; maybeName &amp;lt;*&amp;gt; maybeId

  logShow maybeUser 
  -- Output: (Just { name: "Alice", id: 1024 })

  -- If any piece is missing, the whole thing safely results in Nothing
  let partialUser = createUser &amp;lt;$&amp;gt; Nothing &amp;lt;*&amp;gt; maybeId
  logShow partialUser 
  -- Output: Nothing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Crucial Insight:&lt;/strong&gt; Applicatives allow you to run independent computations in isolation. The evaluation of &lt;code&gt;maybeId&lt;/code&gt; does not depend on the result of &lt;code&gt;maybeName&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Monad: Dependent Chaining (The Heavy Lifter)
&lt;/h2&gt;

&lt;p&gt;Finally, we reach the &lt;strong&gt;Monad&lt;/strong&gt;. While Applicatives handle independent wrapped values, Monads are designed to handle &lt;strong&gt;dependent sequential computations&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Use a Monad when the output of one context-wrapped computation determines what the &lt;em&gt;next&lt;/em&gt; context-wrapped computation should look like.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Definition
&lt;/h3&gt;

&lt;p&gt;A Monad extends Applicative by introducing &lt;code&gt;bind&lt;/code&gt; (written as &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Code snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;Applicative&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="kt"&gt;Monad&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you tried to use regular &lt;code&gt;map&lt;/code&gt; with a function that returns a wrapped value (i.e., &lt;code&gt;a -&amp;gt; m b&lt;/code&gt;), you would end up with a messy nested context: &lt;code&gt;m (m b)&lt;/code&gt;. The Monad’s job is to apply the function &lt;em&gt;and automatically flatten&lt;/em&gt; the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage Example (PureScript &lt;code&gt;do&lt;/code&gt; notation)
&lt;/h3&gt;

&lt;p&gt;PureScript provides syntactic sugar called &lt;code&gt;do&lt;/code&gt; notation, which makes working with Monads look like imperative code while preserving pure functional guarantees under the hood.&lt;/p&gt;

&lt;p&gt;Let's look at a typical multi-step verification sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Validate a user ID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If valid, look up their wallet balance (which could fail).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If they have enough funds, process the transaction.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Code snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Data.Maybe (Maybe(..))

-- Simulating dependent lookups
validateUser :: Int -&amp;gt; Maybe String
validateUser id = if id == 777 then Just "VIP_User" else Nothing

getWalletBalance :: String -&amp;gt; Maybe Int
getWalletBalance username = if username == "VIP_User" then Just 500 else Nothing

-- Monadic Chaining using `do` notation
processPayment :: Int -&amp;gt; Maybe String
processPayment userId = do
  username &amp;lt;- validateUser userId         -- Extracts string out of Maybe
  balance  &amp;lt;- getWalletBalance username   -- Dependent on previous username
  if balance &amp;gt; 100
    then Just "Payment Successful!"
    else Nothing

main :: Effect Unit
main = do
  logShow (processPayment 777) -- Output: (Just "Payment Successful!")
  logShow (processPayment 123) -- Output: Nothing (Fails safely at step 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Crucial Insight:&lt;/strong&gt; If &lt;code&gt;validateUser&lt;/code&gt; returns &lt;code&gt;Nothing&lt;/code&gt;, the Monad stops evaluating the rest of the block immediately. We get bulletproof error propagation without writing a single nested &lt;code&gt;if-else&lt;/code&gt; or &lt;code&gt;try-catch&lt;/code&gt; block.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary: Choosing Your Tool
&lt;/h2&gt;

&lt;p&gt;In my day-to-day workflow, I pick the right tool for the job by asking a simple question about what I am trying to combine:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstraction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you have&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you want to apply&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code pattern&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Value in a context (&lt;code&gt;f a&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;A pure function (&lt;code&gt;a -&amp;gt; b&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;f &amp;lt;$&amp;gt; x&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applicative&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Values in contexts (&lt;code&gt;f a&lt;/code&gt;, &lt;code&gt;f b&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;A pure multi-arg function&lt;/p&gt;

&lt;p&gt;&lt;code&gt;f &amp;lt;$&amp;gt; x &amp;lt;*&amp;gt; y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monad&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Value in a context (&lt;code&gt;m a&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;A function returning a context (&lt;code&gt;a -&amp;gt; m b&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;x &amp;gt;&amp;gt;= \v -&amp;gt; ...&lt;/code&gt; or &lt;code&gt;do&lt;/code&gt; blocks&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Adopting these typeclasses fundamentally shifts how you reason about software architecture.&lt;/p&gt;

&lt;p&gt;Before using this framework, handling multi-step asynchronous or conditional logic meant writing deeply nested error-handling logic. By leveraging &lt;strong&gt;Functor&lt;/strong&gt;, &lt;strong&gt;Applicative&lt;/strong&gt;, and &lt;strong&gt;Monad&lt;/strong&gt;, we compose complex architectures out of small, highly reusable, and predictable building blocks. It makes systems dramatically easier to refactor, impossible to crash with unexpected null pointers, and exceptionally clean to maintain.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>programming</category>
      <category>typesystems</category>
      <category>purescript</category>
    </item>
    <item>
      <title>AI Is Making Senior Engineers 10x Faster - And 10x More Exhausted</title>
      <dc:creator>Shubham</dc:creator>
      <pubDate>Thu, 28 May 2026 10:01:24 +0000</pubDate>
      <link>https://dev.to/shubham399/ai-is-making-senior-engineers-10x-faster-and-10x-more-exhausted-329e</link>
      <guid>https://dev.to/shubham399/ai-is-making-senior-engineers-10x-faster-and-10x-more-exhausted-329e</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fc2aff1ec-2f4e-464d-b328-e8d2d6c00223.png%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlLmNeOP7HXG0OqaG97wimw%2F95a7ced4-fd82-4716-a6d0-b434f9e2b1f7%2Fc2aff1ec-2f4e-464d-b328-e8d2d6c00223.png%2Fpublic" alt="ai-senior" width="1152" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When AI coding tools first appeared, I thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Nice. Less boilerplate.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now it feels like I’m managing a team of infinitely fast junior engineers that never sleep, constantly hallucinate, and submit pull requests every 30 seconds.&lt;/p&gt;

&lt;p&gt;As a senior engineer, AI has dramatically increased my productivity.&lt;/p&gt;

&lt;p&gt;It has also dramatically increased my cognitive load.&lt;/p&gt;

&lt;p&gt;Both things are true at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Good Part: AI Removes the Annoying Work
&lt;/h2&gt;

&lt;p&gt;There’s no denying it anymore.&lt;/p&gt;

&lt;p&gt;LLMs are insanely useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Writing repetitive code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generating tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactoring old logic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explaining unfamiliar codebases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing SQL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generating migration scripts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Producing documentation nobody wanted to write&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Things that used to take 2 hours now take 15 minutes.&lt;/p&gt;

&lt;p&gt;I can scaffold APIs instantly.&lt;br&gt;&lt;br&gt;
I can debug faster.&lt;br&gt;&lt;br&gt;
I can prototype ideas without context-switching for half a day.&lt;/p&gt;

&lt;p&gt;AI gives senior engineers leverage.&lt;/p&gt;

&lt;p&gt;And leverage compounds fast.&lt;/p&gt;

&lt;p&gt;The productivity jump is real.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bad Part: Senior Engineers Became Human Validators
&lt;/h2&gt;

&lt;p&gt;Here’s the problem nobody talks about enough:&lt;/p&gt;

&lt;p&gt;AI shifted senior engineering from “building systems” to “constantly validating generated output.”&lt;/p&gt;

&lt;p&gt;Earlier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Juniors wrote code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Seniors reviewed architecture and edge cases&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;AI writes massive amounts of code instantly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Seniors review ALL of it&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everywhere.&lt;/p&gt;

&lt;p&gt;All the time.&lt;/p&gt;

&lt;p&gt;And unlike juniors, AI has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Infinite confidence&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No memory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No accountability&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No understanding of business context&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It can generate code that &lt;em&gt;looks&lt;/em&gt; perfect while quietly introducing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;race conditions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;security issues&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;hidden performance problems&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;broken abstractions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;fake APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;impossible edge-case handling&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scary part is that the code often looks clean.&lt;/p&gt;

&lt;p&gt;Very clean.&lt;/p&gt;

&lt;p&gt;Sometimes cleaner than human-written code.&lt;/p&gt;

&lt;p&gt;Which makes spotting mistakes even harder.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Increased Output, But Also Increased Noise
&lt;/h2&gt;

&lt;p&gt;One senior engineer can now produce the output of an entire small team.&lt;/p&gt;

&lt;p&gt;Sounds amazing, right?&lt;/p&gt;

&lt;p&gt;Except now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;PR sizes explode&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Architecture decisions happen too quickly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;People ship generated code they barely understand&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Teams confuse “velocity” with “quality”&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bottleneck is no longer writing code.&lt;/p&gt;

&lt;p&gt;The bottleneck is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;understanding systems&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;validating correctness&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;maintaining consistency&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;keeping complexity under control&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI accelerated code generation much faster than it accelerated engineering judgment.&lt;/p&gt;

&lt;p&gt;And that gap is becoming painful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context Engineering Is Becoming More Important Than Coding
&lt;/h2&gt;

&lt;p&gt;The best engineers I know today are not the people writing the most code.&lt;/p&gt;

&lt;p&gt;They are the people giving AI the best context.&lt;/p&gt;

&lt;p&gt;A weak prompt creates chaos.&lt;/p&gt;

&lt;p&gt;A strong prompt creates leverage.&lt;/p&gt;

&lt;p&gt;Senior engineers are now spending more time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;designing workflows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;defining constraints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;writing repository instructions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;creating architecture guardrails&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;building agent tooling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;managing AI behavior&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are slowly moving from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“software engineers”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“system directors for machine-generated software.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds futuristic.&lt;/p&gt;

&lt;p&gt;But honestly, it mostly feels like more responsibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Burnout Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;AI creates a weird kind of exhaustion.&lt;/p&gt;

&lt;p&gt;Not physical exhaustion.&lt;/p&gt;

&lt;p&gt;Cognitive exhaustion.&lt;/p&gt;

&lt;p&gt;You are constantly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;verifying outputs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;re-checking assumptions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reviewing generated logic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;correcting hallucinations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;re-explaining context&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;fighting subtle inconsistencies&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It feels like supervising an incredibly fast intern that learns nothing between conversations.&lt;/p&gt;

&lt;p&gt;And because the output is instant, expectations change instantly too.&lt;/p&gt;

&lt;p&gt;Management sees:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Tasks finish faster.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Senior engineers feel:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’m mentally reviewing 5x more moving pieces than before.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That mismatch is dangerous.&lt;/p&gt;

&lt;h2&gt;
  
  
  Junior Engineers and the Experience Gap
&lt;/h2&gt;

&lt;p&gt;Another thing that worries me:&lt;/p&gt;

&lt;p&gt;Junior engineers can now generate advanced-looking systems without fully understanding them.&lt;/p&gt;

&lt;p&gt;That’s powerful.&lt;/p&gt;

&lt;p&gt;But also risky.&lt;/p&gt;

&lt;p&gt;Earlier, painful debugging built intuition.&lt;/p&gt;

&lt;p&gt;Now AI often bypasses the struggle phase completely.&lt;/p&gt;

&lt;p&gt;Which means senior engineers increasingly become:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;teachers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;validators&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;architecture reviewers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;production safety nets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The gap between “can generate code” and “can engineer systems” is becoming massive.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reality Nobody Wants to Admit
&lt;/h2&gt;

&lt;p&gt;AI is not replacing senior engineers.&lt;/p&gt;

&lt;p&gt;It’s making strong senior engineers more valuable.&lt;/p&gt;

&lt;p&gt;Because somebody still needs to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;understand distributed systems&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;identify bad abstractions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reason about scale&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;evaluate trade-offs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;catch subtle failures&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;make architectural decisions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI can generate solutions.&lt;/p&gt;

&lt;p&gt;It still cannot reliably judge consequences.&lt;/p&gt;

&lt;p&gt;And consequences are where senior engineering lives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I genuinely love using AI.&lt;/p&gt;

&lt;p&gt;I use it every day.&lt;/p&gt;

&lt;p&gt;I would never go back.&lt;/p&gt;

&lt;p&gt;But AI didn’t reduce the importance of senior engineering.&lt;/p&gt;

&lt;p&gt;It amplified it.&lt;/p&gt;

&lt;p&gt;The industry thinks AI is automating software development.&lt;/p&gt;

&lt;p&gt;What it’s actually doing is increasing the demand for engineers who can think critically under complexity.&lt;/p&gt;

&lt;p&gt;AI removed a lot of typing.&lt;/p&gt;

&lt;p&gt;Unfortunately, it also created an endless stream of things that now require human judgment.&lt;/p&gt;

&lt;p&gt;And human judgment remains the most expensive part of software engineering.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>career</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
