<?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: Aditya Agarwal</title>
    <description>The latest articles on DEV Community by Aditya Agarwal (@adioof).</description>
    <link>https://dev.to/adioof</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%2F2760047%2F17358ceb-daca-46e9-9a88-1904b8402d3f.jpg</url>
      <title>DEV Community: Aditya Agarwal</title>
      <link>https://dev.to/adioof</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adioof"/>
    <language>en</language>
    <item>
      <title>Server Actions blur the client-server line and juniors are paying for it</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Wed, 22 Jul 2026 10:11:59 +0000</pubDate>
      <link>https://dev.to/adioof/server-actions-blur-the-client-server-line-and-juniors-are-paying-for-it-4plc</link>
      <guid>https://dev.to/adioof/server-actions-blur-the-client-server-line-and-juniors-are-paying-for-it-4plc</guid>
      <description>&lt;p&gt;Nowadays, a &lt;code&gt;'use server'&lt;/code&gt; directive is one of the most dangerous lines in a Next.js app you could possibly write.&lt;/p&gt;

&lt;p&gt;The frontend dev who wrote it didn't realize they'd just published a public API endpoint, one that skips every check the rest of the app relies on. But no worries, that kind of miscommunication happens all the time in software development!&lt;/p&gt;

&lt;h2&gt;
  
  
  The line we all quietly stopped drawing
&lt;/h2&gt;

&lt;p&gt;A wall stood in the past separating Frontend from Backend, with all the scary security work done on the Backend side.&lt;/p&gt;

&lt;p&gt;Authentication checks, input validation, rate limiting - while the wall may have been unsightly, it made it clear where the threat model lived.&lt;/p&gt;

&lt;p&gt;Server Actions deleted the wall. The official Next.js docs now caution that "when a Server Action is created and exported, it is reachable via a direct POST request, not just through your application's UI."&lt;/p&gt;

&lt;p&gt;I suggest you read that one more time. Your cute little form handler becomes an open endpoint as soon as it is created.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Some frontend framework code is backend code"
&lt;/h2&gt;

&lt;p&gt;Security researcher Sascha B. was blunt in his May 2026 analysis. If the RSC parser is slack on payload shape, "every component author who ever wrote a Server Action wrote, by accident, an unauthenticated RPC endpoint with no input validation."&lt;/p&gt;

&lt;p&gt;The abstraction served as a cover for the endpoint, yet the endpoint was always there.&lt;/p&gt;

&lt;p&gt;Sascha went on to explain that previously, the frontend/backend split between trusted and untrusted code was based on different threat models. The code was separated into clients and servers. With Server Actions the threat model was not on either side of the network but layered into the client component graph.&lt;/p&gt;

&lt;p&gt;In July 2026, Penligent, an AI security company, rephrased the sentence as, "It's not a frontend-calling backend security model; it's some frontend framework code that is backend code."&lt;/p&gt;

&lt;p&gt;Now, the employee who was brought in to design beautiful buttons has to protect and maintain an RPC layer. But no one expected that when they joined the team.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CVEs aren't hypothetical
&lt;/h2&gt;

&lt;p&gt;This is not just a general feeling.&lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;CVE-2025-55182&lt;/strong&gt; (CVSS 10.0) let attackers get unauthenticated remote code execution by exploiting how React decoded payloads sent to Server Function endpoints. A perfect 10, disclosed December 2025 by Lachlan Davidson.&lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;CVE-2025-66478&lt;/strong&gt; was prototype pollution. &lt;/p&gt;

&lt;p&gt;→ On July 21, 2026 (originally scheduled for July 20), Next.js shipped scheduled security patches (v16.2.11 and v15.5.21) for more of them. CVE-2026-64641 was a DoS via crafted requests burning CPU. CVE-2026-64645 was straight-up server-side request forgery.&lt;/p&gt;

&lt;p&gt;The pattern yells at you. A serialization protocol so permissive you didn't realize you were using it, hidden behind code that resembles UI glue.&lt;/p&gt;

&lt;p&gt;Recorded Future essentially pointed out a harsh reality by mentioning that: "some percentage of Next.js developers using Server Actions are unaware that they're invoking a custom serialization protocol... The risk is invisible until it's exploited."&lt;/p&gt;

&lt;h2&gt;
  
  
  This is a design flaw, not a skill issue
&lt;/h2&gt;

&lt;p&gt;It is a common and simple reaction to blame the less experienced person for the mistake. We might say "Well, they should have double-checked and validated all the inputs before shipping it."&lt;/p&gt;

&lt;p&gt;No, the responsibility lies with the abstraction if it is so easy that you may inadvertently expose an unauthenticated endpoint.&lt;/p&gt;

&lt;p&gt;Well-thought-out design should lead users to the safest options by default. In the case of Server Actions, unfortunately, it made risky choices appear unexciting.&lt;/p&gt;

&lt;p&gt;Penligent's recommendation is the following. Do not pass database objects, ORM entities, session objects, or raw API responses directly to Client Components.&lt;/p&gt;

&lt;p&gt;That's real, useful guidance. It's also backend threat-modeling knowledge that most frontend devs were never trained on, now mandatory to avoid leaking secrets.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually do about it
&lt;/h2&gt;

&lt;p&gt;At my startup, we use a Next.js monorepo, and I am not getting rid of Server Actions because they are actually enjoyable to work on.&lt;/p&gt;

&lt;p&gt;However, we approach each action as if it were a public endpoint. Do an auth check right at the beginning. Validate the payload before doing anything else. Expect a direct POST, because it is.&lt;/p&gt;

&lt;p&gt;The mental model that made everything clear: the frontend doesn't exist. There are UI code and endpoint code, and Server Actions are endpoints in a pretty frock.&lt;/p&gt;

&lt;p&gt;Convenience is fantastic, except when it becomes the vulnerability. 🔥&lt;/p&gt;

&lt;p&gt;Are we expecting individuals without the necessary backend training to take over backend responsibilities and show surprise when things don't turn out well?&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>frontend</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The keystroke-counting RTO metric is a confession, not a policy</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Tue, 21 Jul 2026 10:24:10 +0000</pubDate>
      <link>https://dev.to/adioof/the-keystroke-counting-rto-metric-is-a-confession-not-a-policy-g01</link>
      <guid>https://dev.to/adioof/the-keystroke-counting-rto-metric-is-a-confession-not-a-policy-g01</guid>
      <description>&lt;p&gt;A company has recently made a public announcement to admit that, intentionally, they are unable to quantify the work done by engineering. And guess what?&lt;/p&gt;

&lt;p&gt;The GMO Internet Group discontinued remote work after observing that hourly typing volume had decreased.&lt;/p&gt;

&lt;h2&gt;
  
  
  The contradiction that writes itself
&lt;/h2&gt;

&lt;p&gt;Here's the kicker that's supposed to be funny before it gets uncomfortably real. The exact industry that is encouraging developers to use Copilot is also evaluating them based on the quantity of their typing.&lt;/p&gt;

&lt;p&gt;Copilot is designed to minimize your typing efforts. That's all you need to know.&lt;/p&gt;

&lt;p&gt;Therefore, the request is to utilize the AI that codes for you while generating many keystrokes, or we will assume that you are not working hard enough. Two objectives are conflicting.&lt;/p&gt;

&lt;p&gt;Yuuki Yamashita, an AWS Community Builder, hit the nail on the head in his breakdown from July 15, 2026, when he said that a company "demanding AI adoption while grading people on typing volume is optimizing for two contradictory metrics at once."&lt;/p&gt;

&lt;p&gt;Unfortunately, you are not able to possess both of these.&lt;/p&gt;

&lt;h2&gt;
  
  
  A keystroke counter measures the wrong engineer
&lt;/h2&gt;

&lt;p&gt;Some of the best pieces of code I have written have involved me writing no code for the first half-hour. Just thinking. Staring into space. Drawing a few pics on a whiteboard. Deleting more than I wrote.&lt;/p&gt;

&lt;p&gt;Yamashita expressed this more aptly than I ever could, by saying that "a keystroke counter cannot distinguish between an engineer typing furiously to fix a self-inflicted bug and an engineer staring at a whiteboard for an hour before writing the ten lines that make the whole system simpler."&lt;/p&gt;

&lt;p&gt;Read that twice. The metric rewards the person who created the mess and punishes the person who prevented it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Presence is what you measure when output defeats you
&lt;/h2&gt;

&lt;p&gt;This is not related to GMO. 78% of employers are using ActivTrak, Teramind, or Sapience Analytics type of software to monitor mouse movements, app flicking, and keystroke speed.&lt;/p&gt;

&lt;p&gt;That hasn't been management at all. It has been a confession.&lt;/p&gt;

&lt;p&gt;I will never forget what Cory Doctorow declared in September 2024 "Every accusation is a confession. When your boss tells you that he thinks that you can't be trusted to do a good job without total, constant surveillance, he's really saying, I only bother to do my CEO job when I'm afraid of getting fired."&lt;/p&gt;

&lt;p&gt;The act of surveillance reveals more about the person watching than the one being watched.&lt;/p&gt;

&lt;h2&gt;
  
  
  The theater has a body count
&lt;/h2&gt;

&lt;p&gt;When being there is used as a measure, that's what people will strive for. Not performance.&lt;/p&gt;

&lt;p&gt;In May 2024, Wells Fargo terminated more than a dozen employees for using "mouse jigglers" to falsify activity, according to FINRA disclosures. But everyone learned the wrong lesson. The employees didn't create the game. The metric did.&lt;/p&gt;

&lt;p&gt;In August 2024, Denise Prudhomme, an employee of Wells Fargo, passed away at her desk in an office in Tempe, Arizona.&lt;/p&gt;

&lt;p&gt;The electronic system counted her as an attendee. However, she remained lifeless at her workstation for four days until an actual person realized.&lt;/p&gt;

&lt;p&gt;This is the actual measurement of "presence." A badge swipe. Not a human. Not the output of the work. Not if anyone is breathing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The receipts say it doesn't even work
&lt;/h2&gt;

&lt;p&gt;If the surveillance was effective, you could have a debate about the trade-offs. But it isn't.&lt;/p&gt;

&lt;p&gt;A study conducted in 2024 by Yuye Ding and Mark Ma from the University of Pittsburgh examined S&amp;amp;P 500 firms which had strict RTO mandates. The results showed no statistically significant improvement in financial performance. Productivity either.&lt;/p&gt;

&lt;p&gt;What it did produce:&lt;/p&gt;

&lt;p&gt;→ 14% higher departure rate among senior employees&lt;br&gt;
→ 23% longer time-to-fill for open roles&lt;/p&gt;

&lt;p&gt;Your most talented employees are the first to leave and their positions remain vacant for extended periods, all because of a measure that ultimately doesn't influence the target it's supposed to safeguard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually think
&lt;/h2&gt;

&lt;p&gt;Assessing results can be challenging. It demands a sense of aesthetics, understanding of the situation, and openness to evaluating the quality of work rather than the quantity.&lt;/p&gt;

&lt;p&gt;Tracking the number of keystrokes is a simple task. All you need is a spreadsheet program and a lack of trust in your colleagues.&lt;/p&gt;

&lt;p&gt;If leaders choose the easy option, it indicates that they lack the ability to take on the difficult one. That's the bottom line.&lt;/p&gt;

&lt;p&gt;If you need a keystroke counter to distinguish good work from bad work, the problem was already there!&lt;/p&gt;

&lt;p&gt;My question is, have any of the monitoring metrics your company has embraced actually improved the quality of the work, or did it simply improve how highly skilled people get at gaming the metric?&lt;/p&gt;

</description>
      <category>career</category>
      <category>remote</category>
      <category>culture</category>
      <category>opinion</category>
    </item>
    <item>
      <title>SQLite runs more production than the modern data stack wants you to believe</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Tue, 21 Jul 2026 07:10:39 +0000</pubDate>
      <link>https://dev.to/adioof/sqlite-runs-more-production-than-the-modern-data-stack-wants-you-to-believe-37f8</link>
      <guid>https://dev.to/adioof/sqlite-runs-more-production-than-the-modern-data-stack-wants-you-to-believe-37f8</guid>
      <description>&lt;p&gt;One &lt;code&gt;ANALYZE&lt;/code&gt; command resulted in a 100x query speedup for one person. There was no need to restart the server, reconfigure the network, or receive an alert at 3am.&lt;/p&gt;

&lt;p&gt;That's the Julia Evans post about running SQLite in production that linked in my brain with a chat I had with Richard Schneeman five years ago and I couldn't shake it loose. It's one of those times where you read something, or have a conversation, and it feels like a missing half you didn't know you needed has finally slipped into place.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack we all pretend we need
&lt;/h2&gt;

&lt;p&gt;Many teams opt to use managed Postgres even before experiencing load from a single user. After that, they implement a connection pooler, followed by a read replica, and then a caching layer to mask the introduced latency of the other stuff they bolted on to go fast.&lt;/p&gt;

&lt;p&gt;This represents a full stack you would normally have to create, maintain, and monitor on your own.&lt;/p&gt;

&lt;p&gt;Here's the tricky truth. The amount of work most teams have is reading-heavy. Just reading. Many readings.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers are almost rude
&lt;/h2&gt;

&lt;p&gt;As of February 2026, local SQLite p50 latency is approximately 0.01ms. Turso's Embedded Replica has a latency of about 0.02ms.&lt;/p&gt;

&lt;p&gt;When you have your Postgres database in the same region, the latency can be as low as 1 to 5ms. However, if you are using a managed Postgres like Neon, the latency might range from 3 to 10ms.&lt;/p&gt;

&lt;p&gt;For read-heavy workloads, it is 100x to 1,000x faster. Not because SQLite is magical, but because it eliminated the network. 🌐&lt;/p&gt;

&lt;p&gt;Ben Johnson, who built Litestream and is an engineer at Fly.io, put it most starkly: "When you put your data right next to your application, you can see per-query latency drop to microseconds."&lt;/p&gt;

&lt;p&gt;Exactly. Minimizing unnecessary network calls is crucial for optimal performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  People are actually shipping this
&lt;/h2&gt;

&lt;p&gt;This is not a toy project. Expensify processes billions of transactions on an embedded SQLite architecture called Bedrock.&lt;/p&gt;

&lt;p&gt;They completely removed the network layer. There was no need to monitor PgBouncer.&lt;/p&gt;

&lt;p&gt;Forward Email manages millions of emails as of July 2026, using a database-per-user SQLite setup. There is one database per tenant ensuring complete isolation and avoiding any issues with noisy neighbors.&lt;/p&gt;

&lt;p&gt;PropFirm Key grew to a size where it was serving 50,000 daily visitors from one 47MB SQLite file on a single EC2 large instance.&lt;/p&gt;

&lt;p&gt;Also, in July 2026, a stress test was conducted on a Node.js social network which was running on better-sqlite3. It was able to manage 50,000 users and one million posts all stored in a single 343MB &lt;code&gt;.db&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;With fifty thousand users under your belt, imagine sharing a file that small with a friend via email.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch nobody's hiding
&lt;/h2&gt;

&lt;p&gt;SQLite doesn't replace Postgres in all scenarios. Applications that involve frequent writing, high concurrency, and multiple writers are better off with a full database server. And that's perfectly okay.&lt;/p&gt;

&lt;p&gt;However, the exciting news is that it is closing the gap with that too. Taking SQLite, Turso's CEO Glauber Costa forked it into libsql and included native replication, embedded replicas, and vector search.&lt;/p&gt;

&lt;p&gt;The argument against replication based on the resource limitations is slowly disappearing, as the previous tradeoffs are becoming less relevant.&lt;/p&gt;

&lt;p&gt;Here's my opinion:&lt;/p&gt;

&lt;p&gt;→ Operational simplicity is a feature, not a compromise.&lt;br&gt;
→ Every layer you add is a layer you get paged for.&lt;br&gt;
→ Most apps are read-heavy and single-node-shaped, whether we admit it or not.&lt;br&gt;
→ "Scales to millions" is meaningless if you have thousands.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that stings
&lt;/h2&gt;

&lt;p&gt;We tend to seek a sense of security in complexity. Distributed systems give an impression of importance and reliability. On the other hand, a single file seems like something you'd do back in college! 😅&lt;/p&gt;

&lt;p&gt;However, serious is something that is functional, cost-efficient, and does not disrupt your sleep. For instance, a 47MB file that consistently serves 50,000 daily is more serious than a five-service data stack that serves a demo.&lt;/p&gt;

&lt;p&gt;I'm not suggesting you get rid of your database immediately. But try to pause and question yourself if you really need to use a heavy stack the next time. Maybe you're implementing a solution for a problem you don't have.&lt;/p&gt;

&lt;p&gt;The standard setting should be justified for how intricate it is. At present, the majority of defaults are not.&lt;/p&gt;

&lt;p&gt;So my question to you is this: If you had to choose managed Postgres or an embedded SQLite file for your next read-heavy project, it's not really about latency, is it?&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>softwareengineering</category>
      <category>opinion</category>
      <category>programming</category>
    </item>
    <item>
      <title>Vanilla CSS quietly caught up and Tailwind fans haven't noticed.</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Mon, 20 Jul 2026 10:23:48 +0000</pubDate>
      <link>https://dev.to/adioof/vanilla-css-quietly-caught-up-and-tailwind-fans-havent-noticed-imp</link>
      <guid>https://dev.to/adioof/vanilla-css-quietly-caught-up-and-tailwind-fans-havent-noticed-imp</guid>
      <description>&lt;p&gt;Last month I removed Tailwind from a side project. And you know what? Nothing broke.&lt;/p&gt;

&lt;p&gt;That was more unexpected than I had anticipated. The build step I had been holding onto for years was actually unnecessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  The platform grew up while we weren't looking
&lt;/h2&gt;

&lt;p&gt;Something nobody really celebrated the release of, Vanilla CSS just went ahead and added the things that many of us were needing libraries to grab for us.&lt;/p&gt;

&lt;p&gt;By the end of 2024, native CSS nesting was supported by all the major browsers. This means that you could use the code &lt;code&gt;.card { .title { ... } }&lt;/code&gt; without the need for PostCSS, Sass, or any other preprocessor.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;:has()&lt;/code&gt; parent selector achieved approximately 94-98% cross-browser support (Baseline: Widely Available). You want to style a container based on its contents. No JavaScript required, no class-toggling gymnastics.&lt;/p&gt;

&lt;p&gt;What about &lt;code&gt;@layer&lt;/code&gt;? It eliminated the specificity wars. You decide which styles have higher precedence in the cascade, so you don't have to resort to &lt;code&gt;!important&lt;/code&gt; like Tailwind's overrides might have led you to believe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Utility classes solved a problem that's already fixed
&lt;/h2&gt;

&lt;p&gt;Tailwind was necessary. The CSS cascade was a footgun, nesting required a preprocessor, and scoping was a disaster.&lt;/p&gt;

&lt;p&gt;All of those pain points have a native solution today. The abstraction was no longer necessary.&lt;/p&gt;

&lt;p&gt;This became evident thanks to a popular developer forum post in July 2026. A user took an entire Tailwind dashboard and re-implemented it in plain CSS. It functioned.&lt;/p&gt;

&lt;p&gt;There's also an AI angle that supports this. A January 2026 JavaScript in Plain English writeup asked Claude to build something in modern vanilla CSS. The result: "It worked. Perfectly. First try. And the output was cleaner than the Tailwind equivalent."&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers aren't kind either
&lt;/h2&gt;

&lt;p&gt;Tailwind version 4 was released in January 2025. It included "Oxide," which is a Rust rewrite from the ground up. It had HMR that was less than a millisecond with a 10-14x improvement from v3. This was engineering at its finest. 👏&lt;/p&gt;

&lt;p&gt;But a March 2026 Leaper.dev benchmark on an M3 MacBook Pro summed up the catch perfectly: "vanilla CSS with no processing step still wins, there's simply nothing to compile."&lt;/p&gt;

&lt;p&gt;Nothing can be faster than not having to run anything.&lt;/p&gt;

&lt;p&gt;The bundle sizes tell the same story. In one landing page benchmark:&lt;/p&gt;

&lt;p&gt;→ Tailwind: 14.78 KB total (8.67 KB HTML + 6.10 KB CSS)&lt;br&gt;
→ Vanilla: 8.45 KB total (6.28 KB HTML + 2.16 KB CSS)&lt;/p&gt;

&lt;p&gt;That's a Tailwind bundle that is 75% heavier, for a landing page! The utility classes swell your HTML, and the generated CSS swells on top.&lt;/p&gt;

&lt;h2&gt;
  
  
  Someone's already proving it at scale
&lt;/h2&gt;

&lt;p&gt;If you believe this rule only applies to small projects, consider 37signals. They applied this philosophy to three products they shipped: Campfire, Writeboard, and Backpack.&lt;/p&gt;

&lt;p&gt;Almost 14,000 lines of vanilla CSS spread out over 105 files. No build tools.&lt;/p&gt;

&lt;p&gt;This was not a quick project done by a single developer over a weekend. This was an official company delivering actual products, and they decided not to use a compilation step in their CSS process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who should actually care
&lt;/h2&gt;

&lt;p&gt;I'm not saying tomorrow you should rip Tailwind out of a 50-person codebase. If your team has muscle memory, shared conventions, and a working design system, the switching cost is real.&lt;/p&gt;

&lt;p&gt;However, the majority of us are not that team. We are individual developers and small startups who have always included a build step automatically.&lt;/p&gt;

&lt;p&gt;Here's my take:&lt;/p&gt;

&lt;p&gt;→ Solo project or small site? You probably don't need the toolchain anymore.&lt;br&gt;
→ Big team with an entrenched system? Stay put, the ergonomics still pay off.&lt;br&gt;
→ Starting fresh in 2026? Try native first before you reach for the abstraction.&lt;/p&gt;

&lt;p&gt;It's not that Tailwind is a bad tool. It's that the problem it solved for us initially was temporary, and most of us never stopped to re-evaluate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;We create tools to address specific issues we're facing. But sometimes, even after the problem has been solved, or no longer exists, we continue using the same tools.&lt;/p&gt;

&lt;p&gt;And that's when problems can arise. Interestingly, Vanilla CSS eventually "caught up".&lt;/p&gt;

&lt;p&gt;By the time the CSS pain points felt worth fixing, native CSS had already added the features to solve them, so a lot of the workaround code we relied on was no longer necessary.&lt;/p&gt;

&lt;p&gt;Most modern browser layout issues had a habit of solving themselves if you just gave them a little time.&lt;/p&gt;

&lt;p&gt;Have you had the chance to use native CSS since nesting and &lt;code&gt;:has()&lt;/code&gt; shipped, or are you still advocating for a build step because that's what you're used to?&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>opinion</category>
    </item>
    <item>
      <title>Your NAT gateway is a $30k landmine and nobody warns juniors</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Mon, 20 Jul 2026 07:04:28 +0000</pubDate>
      <link>https://dev.to/adioof/your-nat-gateway-is-a-30k-landmine-and-nobody-warns-juniors-2l4a</link>
      <guid>https://dev.to/adioof/your-nat-gateway-is-a-30k-landmine-and-nobody-warns-juniors-2l4a</guid>
      <description>&lt;p&gt;You spend time optimizing a function to be 40 milliseconds faster, but then realize your cloud bill is so high that it's eating up all your savings.&lt;/p&gt;

&lt;p&gt;I wish someone had told me over a cup of coffee, "&lt;strong&gt;you lose money on the network.&lt;/strong&gt;" (Here's the coffee chat I wish I'd had.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The $30k hallway tax
&lt;/h2&gt;

&lt;p&gt;I heard about a startup that received a warning. They were about 48 hours away from a $30,000 AWS invoice.&lt;/p&gt;

&lt;p&gt;It's not from a computer. Not from a GPU farm running all night.&lt;/p&gt;

&lt;p&gt;From a worker fetching millions of small JSON files out of S3. Innocent. Boring. Bankrupting.&lt;/p&gt;

&lt;p&gt;It wasn't S3 that caused the issue. The real culprit was the NAT gateway that acted as a mediator between their private subnet and the internet. Each byte accessed by the worker had to go through this gateway, which charges based on the amount of data used.&lt;/p&gt;

&lt;p&gt;Accessing S3 from within a VPC gives the illusion of locality. But it's not the case unless you explicitly make it so. Send the traffic through a NAT gateway and Amazon counts the packets to the bit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why juniors never see it coming
&lt;/h2&gt;

&lt;p&gt;Computational cost can be expensive. When you start using a high-performance machine, you immediately notice the cost involved.&lt;/p&gt;

&lt;p&gt;You only pay a tiny amount for each gigabyte transferred, but when you're dealing with millions of small files, these costs can quickly add up.&lt;/p&gt;

&lt;p&gt;Here's the trap nobody flags:&lt;/p&gt;

&lt;p&gt;→ Small files are worse than big ones. Overhead per request stacks up.&lt;br&gt;
→ NAT gateway pricing is per-GB &lt;strong&gt;processed&lt;/strong&gt;, on top of the per-hour charge.&lt;br&gt;
→ Your code looks fine. The architecture is the bug.&lt;br&gt;
→ The bill lands weeks later, long after the deploy that caused it.&lt;/p&gt;

&lt;p&gt;The real kicker is that you send it on a Monday, you get billed at the end of the month, and by that time, you have already forgotten which loop you sent.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix is embarrassingly cheap
&lt;/h2&gt;

&lt;p&gt;The startup didn't rewrite their application. They simply introduced a VPC endpoint for S3.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;gateway VPC endpoint&lt;/strong&gt; allows connectivity from within your VPC to the S3 service. This means it enables you to route traffic to S3 through the VPC's private subnets rather than routing the traffic through the internet. This also means you can use VPC security controls and configurations that you've applied within the VPC to secure the traffic bound for S3.&lt;/p&gt;

&lt;p&gt;That was the only routing configuration that prevented a bill in the five figures.&lt;/p&gt;

&lt;p&gt;The lesson generalizes. Before you scale any worker that moves data, ask a dumb question:&lt;/p&gt;

&lt;p&gt;→ Where does this traffic physically go?&lt;br&gt;
→ Does it cross a NAT gateway, a region boundary, or the open internet?&lt;br&gt;
→ Am I paying rent for every hop?&lt;/p&gt;

&lt;p&gt;Traffic within the same region and the same availability zone (AZ), as well as traffic that is endpoint-routed, are relatively inexpensive or even free. On the other hand, traffic that goes across AZs, regions, or is NAT (Network Address Translation) routed, can lead to costs that slowly drain a startup's budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network cost is a performance axis
&lt;/h2&gt;

&lt;p&gt;Performance is how fast something runs and how much work it's able to do. When it comes to computers or networks, performance is measured by the time it takes to complete tasks (latency) and the amount of work that can be done in a certain amount of time (throughput). The faster a computer system responds to a user's actions or a network delivers data, the better its performance.&lt;/p&gt;

&lt;p&gt;And here's a third aspect that often gets overlooked: the cost per operation.&lt;/p&gt;

&lt;p&gt;An application that needs to access a million files in object storage "quickly" can put a huge strain on a network or system if not carefully engineered. A great chunk of the benefit of object storage is lost if network latency means a connection needs to be re-established for each file.&lt;/p&gt;

&lt;p&gt;I've gotten so used to it that every arrow between two boxes is a question: who foots the bill for this wire, and what's the cost per byte?&lt;/p&gt;

&lt;p&gt;Writing quick and dirty code for a poorly managed company is just a more sophisticated way of failing. 🙃&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;The cloud is marketed as if information can magically move from place to place. But reality is, it moves slowly, and you have to pay for every bit of transfer, and the cost accumulates regardless of your awareness.&lt;/p&gt;

&lt;p&gt;Understand the journey of your bytes before you resize the component transporting them. A VPC endpoint is cheaper than a lunch. But a NAT gateway will blow your budget.&lt;/p&gt;

&lt;p&gt;I have a question for you: &lt;strong&gt;What is the stupidest cloud bill you ever paid, and what was it for?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>cost</category>
      <category>architecture</category>
      <category>devops</category>
    </item>
    <item>
      <title>The monolith won. Most teams just haven't admitted it yet.</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Fri, 17 Jul 2026 10:23:35 +0000</pubDate>
      <link>https://dev.to/adioof/the-monolith-won-most-teams-just-havent-admitted-it-yet-2ib0</link>
      <guid>https://dev.to/adioof/the-monolith-won-most-teams-just-havent-admitted-it-yet-2ib0</guid>
      <description>&lt;p&gt;Last month, a team removed their microservices. The latency dropped from 800ms to 12ms.&lt;/p&gt;

&lt;p&gt;No typo there - it simply means your data doesn't have to travel across the network to talk to another service.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bill nobody warned you about
&lt;/h2&gt;

&lt;p&gt;Microservices architecture was portrayed as a solution to all problems; limitless scalability, separate deployments, and teams that don't interfere with each other.&lt;/p&gt;

&lt;p&gt;What they actually provided was a bill charging for leaving the platform.&lt;/p&gt;

&lt;p&gt;Whenever Service A communicates with Service B, you are charged for that data transfer. AWS bills $0.09/GB for inter-regional data transfer.&lt;/p&gt;

&lt;p&gt;The painful truth is what DHH highlighted, that AWS basically takes &lt;strong&gt;40% off the top&lt;/strong&gt;. This means they rob you of 40 cents from every dollar you give them, without any remorse. 💸&lt;/p&gt;

&lt;h2&gt;
  
  
  Amazon literally proved the point
&lt;/h2&gt;

&lt;p&gt;Amazon put it out there.&lt;/p&gt;

&lt;p&gt;The case study from the Prime Video Video Quality Analysis team was released in March 2023, but it went viral in May 2023. Their over-the-top serverless architecture using all AWS Step Functions and Lambda ran into a hard scaling wall when they reached &lt;strong&gt;5%&lt;/strong&gt; of their projected load.&lt;/p&gt;

&lt;p&gt;Why, you ask? It's because their architecture was continuously reading and writing video frames to S3, over the network.&lt;/p&gt;

&lt;p&gt;Therefore, they accomplished something that seemed impossible. They condensed it into a monolith and allowed the data to be processed in-memory instead of being transferred electronically.&lt;/p&gt;

&lt;p&gt;The Outcome:&lt;/p&gt;

&lt;p&gt;→ Infrastructure costs dropped over &lt;strong&gt;90%&lt;/strong&gt;&lt;br&gt;
→ The scaling limit vanished&lt;br&gt;
→ The "primitive" architecture won&lt;/p&gt;

&lt;p&gt;If the cloud provider you use starts sharing a document on how to exit its platform, it's probably a good time to rethink your plans.&lt;/p&gt;

&lt;h2&gt;
  
  
  "But microservices scale!"
&lt;/h2&gt;

&lt;p&gt;They do. Let me tell you about Shopify.&lt;/p&gt;

&lt;p&gt;The main monolithic application contains 2.8 million lines of code and has seen over 500,000 commits. It processes 32 million requests per minute and executes 11 million MySQL queries per second on Black Friday.&lt;/p&gt;

&lt;p&gt;I can't believe it, that's a monolith. It is not a distributed mesh made up of 47 services that are kept together by hope and YAML.&lt;/p&gt;

&lt;p&gt;They maintain cleanliness using a tool called Packwerk which guarantees domain boundaries within the codebase. Who knew you could write clean code without sending every function call over a network.&lt;/p&gt;

&lt;p&gt;For most of us, the scale argument was an excuse. The reality is you're not Netflix. Your side project doesn't need service discovery.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real cost is your sprint
&lt;/h2&gt;

&lt;p&gt;While money is an obvious form of tax, the sanity of your team is the hidden one.&lt;/p&gt;

&lt;p&gt;I recently read a post by a developer who complained that their team spent 80% of their sprint capacity on a 14-microservice migration. And it wasn't spent on implementing new features. It was spent on writing YAML.&lt;/p&gt;

&lt;p&gt;80% of engineering time is spent babysitting config and debugging why Service C can't talk to Service F.&lt;/p&gt;

&lt;p&gt;This is the reality we tend to leave out of the architecture diagram. Introducing a new service boundary means there will be new points of failure, a new deployment pipeline to set up, and new logs to search through when troubleshooting in the middle of the night.&lt;/p&gt;

&lt;p&gt;One well-designed service can manage the majority of workloads effectively. Introducing the distributed version only increases potential complexity and challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we keep doing it anyway
&lt;/h2&gt;

&lt;p&gt;To be honest, we're doing a lot of resume-driven development here.&lt;/p&gt;

&lt;p&gt;Having "Migrated to microservices" on your LinkedIn profile may seem impressive. While "Kept the monolith simple and shipped features" doesn't sound as good, despite the fact that it's more challenging and more intelligent in many cases.&lt;/p&gt;

&lt;p&gt;We tend to choose complicated solutions because we think it's the right way to progress, or it's what solid engineering looks like. However, half a year down the line you end up in a situation where you're spending 3.2 million dollars a year, questioning how you got there, just like 37signals did.&lt;/p&gt;

&lt;p&gt;Instead of using the cloud, they decided to purchase $600,000 worth of Dell servers. They reduced costs to approximately $360k per year and estimated $10 million in savings over five years. They managed everything using an open-source tool called Kamal. 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;The monolith was victorious. Many teams have not confessed this yet, because doing so would also mean admitting that the last two years of migration work was largely for nothing.&lt;/p&gt;

&lt;p&gt;Begin with a single service. Define boundaries in your code, not in your network. Consider microservices only if a single computer is truly insufficient for your load (95% of us can do a lot on one machine).&lt;/p&gt;

&lt;p&gt;Can you imagine the tiniest, stupidest design that could still get your product out the door before the end of the quarter?&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>architecture</category>
      <category>cloud</category>
      <category>cost</category>
    </item>
    <item>
      <title>The most expensive outages return HTTP 200</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Thu, 16 Jul 2026 10:15:46 +0000</pubDate>
      <link>https://dev.to/adioof/the-most-expensive-outages-return-http-200-k8d</link>
      <guid>https://dev.to/adioof/the-most-expensive-outages-return-http-200-k8d</guid>
      <description>&lt;p&gt;A 500 is an unexpected jolt from your sleep, while a 200 silently drains your savings.&lt;/p&gt;

&lt;p&gt;That's the bug you never get trained for. All is functioning. Every output is pristine. And your cloud bill just tripled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Downtime is the easy mode
&lt;/h2&gt;

&lt;p&gt;You are immediately alerted when a service is down. Pagers start beeping loudly. Dashboards show red alerts. Customers mention you in tweets.&lt;/p&gt;

&lt;p&gt;An entire ecosystem exists for this. Uptime monitors, error budgets, on-call rotations. We excel at discovering anything that becomes broken.&lt;/p&gt;

&lt;p&gt;What kind of bug causes everything to work as usual, but the cost suddenly triples?&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug that returns 200
&lt;/h2&gt;

&lt;p&gt;That liteLLM prompt cache invalidation incident on July 13, 2026. It's really the stuff of nightmares.&lt;/p&gt;

&lt;p&gt;In theory, prefix-based prompt caching seems easy. If you reuse the same prefix, the generator can serve the remainder at a lower cost from the cache. But, the moment you mutter a different prefix, you pay the full high price.&lt;/p&gt;

&lt;p&gt;The catch here is that the cache keys are based on the exact sequence of the message. If you move a line, reorder a cue, the prefix doesn't match and cache is a miss. 💸&lt;/p&gt;

&lt;p&gt;An essential system message is moved by someone. Or a few roles are reordered in the request payload. The responses are perfect. The latency hardly changes. Almost every test is successful.&lt;/p&gt;

&lt;p&gt;And the cache quietly stops working for you. Now, every call costs you the complete token amount. You don't get alerted because nothing is wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why correctness monitoring misses it
&lt;/h2&gt;

&lt;p&gt;All of our testing efforts are geared towards answering one single question - &lt;strong&gt;Did you get the right output?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We should not ask that question for cost bugs. The result is always right here. That's the pitfall.&lt;/p&gt;

&lt;p&gt;Consider what our assertions are actually testing:&lt;/p&gt;

&lt;p&gt;→ Did we get a 200? Yes.&lt;br&gt;
→ Is the response shape valid? Yes.&lt;br&gt;
→ Does the content match expectations? Yes.&lt;br&gt;
→ Did it cost what it should have? ...nobody asked.&lt;/p&gt;

&lt;p&gt;Cost is handled as an accounting exercise rather than an engineering indicator. It's contained in a monthly PDF that somebody from finance department goes through, instead of a test failing a pull request.&lt;/p&gt;

&lt;p&gt;This gap is where the money drains out. An unnoticed expense leak can go on for weeks before somebody looks at the bill and says "hey, what's this."&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost is a correctness property
&lt;/h2&gt;

&lt;p&gt;Here's the way I like to put it. If a code change triples your spend for identical output, that's a bug.&lt;/p&gt;

&lt;p&gt;A regressive step, not a "cost optimization opportunity." This should be as obvious and annoying as a broken test.&lt;/p&gt;

&lt;p&gt;At our startup, we began treating cost in the same way you treat latency. It's something you insist on, something that causes a build to crash. The cache hit rate isn't a metric that's good to have - it's a commitment.&lt;/p&gt;

&lt;p&gt;Even simple changes can lead to unexpected consequences. It could be a rearranged payload, a retry mechanism that bypasses caching, or a logging modification that increases the size of each call.&lt;/p&gt;

&lt;p&gt;A 500 error exposes and publicly embarrasses you, so it's no wonder that we do everything we can to eliminate those. On the other hand, a 200 response that fails silently and costs you income is a private embarrassment, potentially months down the road, and more easily ignored.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;Instead of cheering for the green dashboard, remember that green simply indicates that there have been no crashes, but not that nothing has failed. In fact, the most costly failure may be up and running at the moment, happily serving 200s, and slowly leaking you tokens that are not cached.&lt;/p&gt;

&lt;p&gt;What was the most costly "It's fine" bug you've encountered, and how long did it persist before it was discovered? 👀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>observability</category>
      <category>cloud</category>
      <category>cost</category>
    </item>
    <item>
      <title>uv is amazing and that's exactly what should scare Python devs</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Wed, 15 Jul 2026 10:24:20 +0000</pubDate>
      <link>https://dev.to/adioof/uv-is-amazing-and-thats-exactly-what-should-scare-python-devs-lp2</link>
      <guid>https://dev.to/adioof/uv-is-amazing-and-thats-exactly-what-should-scare-python-devs-lp2</guid>
      <description>&lt;p&gt;uv is genuinely the best thing to happen to Python tooling in a decade. That's exactly why I'm nervous.&lt;/p&gt;

&lt;p&gt;A Rust tool, funded by venture capital, has recently become the underlying technology for Python installations used by millions of people.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually happened here
&lt;/h2&gt;

&lt;p&gt;Astral unleashed uv from its cage in February of the year 2024 of the lord. Charlie Marsh's outfit had shipped a package manager written in Rust that was, well, fast in the way that made pip feel broken.&lt;/p&gt;

&lt;p&gt;We mean it's 10-100 times quicker than pip. If your cache isn't 'hot', creating a virtual environment is 80-115 times faster than earlier. 🏎️&lt;/p&gt;

&lt;p&gt;It just consumes all of them. uv can replace pip, pip-tools, pipx, poetry, pyenv, and virtualenv as a drop-in.&lt;/p&gt;

&lt;p&gt;Six tools! Just one binary! Come February 2026, it was achieving over 126M monthly downloads.&lt;/p&gt;

&lt;p&gt;This is not adoption, it's a takeover.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that should make you pause
&lt;/h2&gt;

&lt;p&gt;I've noticed a timeline that people haven't been piecing together.&lt;/p&gt;

&lt;p&gt;→ April 2023: Astral raises a $4 million seed round led by Accel.&lt;br&gt;
→ February 2024: uv ships, free and fast, and the ecosystem stampedes toward it.&lt;br&gt;
→ August 2025: Astral announces pyx, a private PyPI-style registry for organizations.&lt;br&gt;
→ March 19, 2026: OpenAI acquires Astral and folds the team into its Codex group.&lt;/p&gt;

&lt;p&gt;See how that works? An open-source tool dominates the ecosystem, followed by a commercial registry, then the entire project is acquired by a corporate entity with vastly distinct intentions.&lt;/p&gt;

&lt;p&gt;In other words, Thibault Sottiaux - the person responsible for Codex, OpenAI's famed deep learning system that can translate natural language into code - sees value in what the Astral development environment is doing, because it matches the principles behind Codex.&lt;/p&gt;

&lt;p&gt;The idea being sold here is not that people are passionate about Python packaging. It's that this technology speeds up the implementation of the goals &lt;em&gt;they&lt;/em&gt; have. Python's internal mechanisms are now a component in some other organization's AI strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is a governance problem, not a tooling win
&lt;/h2&gt;

&lt;p&gt;I want to make something clear. The engineering is absolutely fantastic, and the people who have built uv are geniuses.&lt;/p&gt;

&lt;p&gt;The rapid development that attracted us all was only possible because the investors were expecting a profit.&lt;/p&gt;

&lt;p&gt;Venture capitalists do not provide financial support for a complimentary package manager because they are kind-hearted people. They do so because having control over the entry point to a programming language can bring them substantial returns in the future.&lt;/p&gt;

&lt;p&gt;The seed round is like putting a down payment on a house. pyx is the first clue as to where that money comes from. And the acquisition is the exit.&lt;/p&gt;

&lt;p&gt;There is nothing wrong with any of those steps. They are simply inevitable consequences of centralizing the vital infrastructure of a language within a corporate entity that has to make money from somewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "it's open source" doesn't fully save us
&lt;/h2&gt;

&lt;p&gt;That's correct. uv is an open-source project. If necessary, you have the freedom to create a fork of it.&lt;/p&gt;

&lt;p&gt;Let's be real though, it's not you after 6 pm or your team when there's a sprint deadline, who forks a Rust codebase this deep.&lt;/p&gt;

&lt;p&gt;The license itself is not the most powerful aspect. What really matters is the strategic plan, the progress so far, and the 126 million monthly downloads from a single organization.&lt;/p&gt;

&lt;p&gt;A fork is an escape route out of a burning building, but it only saves the few people brave enough to actually use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm actually telling my team
&lt;/h2&gt;

&lt;p&gt;I'm not about to tear uv out. It's far too fantastic and to say otherwise would be untruthful.&lt;/p&gt;

&lt;p&gt;However, I treat it as a vendor, not a given, so we must ensure that our lockfiles are portable and that our builds are unexciting enough to be replaced.&lt;/p&gt;

&lt;p&gt;→ Don't wire uv-only features into the core of your build.&lt;br&gt;
→ Keep a mental note of the pip/poetry escape path.&lt;br&gt;
→ Watch pyx pricing like it's a roommate who just got a raise.&lt;/p&gt;

&lt;p&gt;The moral of the story is not to stay away from good things but to be aware when a good thing starts carrying the weight of an entire system. 🧯&lt;/p&gt;

&lt;p&gt;For three decades, Python managed without having a single corporate proprietor. The truly frightening part is how little time it took for us to abandon the old jalopy simply because the flashy newcomer was faster.&lt;/p&gt;

&lt;p&gt;My question to you is this: If pyx announced it would begin to charge for use tomorrow, or Codex modified uv's strategy without announcing it and made it clear that the platform was going in a direction you were not comfortable with, how soon would you and your team exit?&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>devtools</category>
      <category>discuss</category>
    </item>
    <item>
      <title>On-call is unpaid overtime and we normalized it</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Mon, 13 Jul 2026 10:11:52 +0000</pubDate>
      <link>https://dev.to/adioof/on-call-is-unpaid-overtime-and-we-normalized-it-1h3d</link>
      <guid>https://dev.to/adioof/on-call-is-unpaid-overtime-and-we-normalized-it-1h3d</guid>
      <description>&lt;p&gt;Your pager buzzes you awake in the dead of night, an alert in one of your systems demands your attention. You manage to identify the issue and apply a fix in twelve minutes flat.&lt;/p&gt;

&lt;p&gt;We as a society have chosen to accept this as a standard behavior, we've even assigned a positive term to it - ownership.&lt;/p&gt;

&lt;h2&gt;
  
  
  The word "ownership" is doing a lot of work
&lt;/h2&gt;

&lt;p&gt;As we enter the middle of 2026, a debate is heating up about whether on-call is unpaid overtime or merely a salary premium. I believe it's all in how you frame it.&lt;/p&gt;

&lt;p&gt;Being on-call with a pager constantly isn't a responsibility. It's a job. And calling it "taking ownership" washes that job of work into an attribute of one's character.&lt;/p&gt;

&lt;p&gt;You're not exhausted because you didn't get enough sleep. You're exhausted because you invest so much energy into what you do. Catch my drift?&lt;/p&gt;

&lt;h2&gt;
  
  
  The law was basically written to let this happen
&lt;/h2&gt;

&lt;p&gt;Here's the part they don't tell you during the standup meeting. According to FLSA Section 13(a)(1) and 13(a)(17), software engineers who make at least $684 a week are not eligible for overtime pay and minimum wage protections.&lt;/p&gt;

&lt;p&gt;That equals $35,568 a year. If you exceed that threshold, any additional time you put in at the office comes without compensation. Hooray! 🎉&lt;/p&gt;

&lt;p&gt;It becomes more defined. The Department of Labor actually classifies standby as "engaged to wait" (paid) and "waiting to be engaged" (not paid).&lt;/p&gt;

&lt;p&gt;Since you can answer from anywhere with a laptop, your on-call is equivalent to "waiting to be engaged." The very part about on-call that sucks, being able to be reached from anywhere, is the part that isn't compensated.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "$150k is your hazard pay" defense
&lt;/h2&gt;

&lt;p&gt;The most common response from the industry is that you are already being compensated for this with your higher salary. In an October 2025 commentary, tech blog ThatSoftwareDude wrote that the salary premium "isn't just for your technical skills, it's hazard pay for being perpetually on standby."&lt;/p&gt;

&lt;p&gt;They continued: "Businesses realize this truth, although they may not admit it openly." I must say, I find this statement to be quite accurate.&lt;/p&gt;

&lt;p&gt;But notice what "hazard pay baked in" really means. It means uncapped, unmeasured, and invisible. You can't audit a number nobody wrote down.&lt;/p&gt;

&lt;p&gt;Now, let's put this into perspective with actual numbers that people are familiar with. For example, Incident.io reported in February 2026 that flat payments ranging from $200 to $500 per week just for being on-call are typical. In a Rootly report from November 2025, the range is between $500 and $1,200 per month.&lt;/p&gt;

&lt;p&gt;According to The Pragmatic Engineer's research, with stricter labor laws in Europe, companies are willing to pay around €1,000 per week for your availability, with per-incident hourly rates on top of that. The work didn't change, just the willingness to pay for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pager is now the reason people quit
&lt;/h2&gt;

&lt;p&gt;Kit Merker, COO of Nobl9 said it best, "People used to quit managers, now they quit on-call rotations." He referenced explicit mandates like being required to stay within 15 minutes of your computer at all times.&lt;/p&gt;

&lt;p&gt;Having only fifteen minutes of freedom isn't something that can be considered a job benefit; it's more like being monitored electronically with a Slack integration.&lt;/p&gt;

&lt;p&gt;According to the guidance in The Google SRE Workbook, a sustainable shift should include 2 to 3 incidents that an engineer can take action on. If there are more than that, the engineer can easily experience burnout.&lt;/p&gt;

&lt;p&gt;Now imagine the developer forum threads in which devs on-call page ops for anything. Most rotations exceed that limit, not because the systems are difficult, but because it costs the dev nothing to page someone and costs the op a night's sleep.&lt;/p&gt;

&lt;h2&gt;
  
  
  Money doesn't actually fix the peace-of-mind part
&lt;/h2&gt;

&lt;p&gt;Here's the catch I can't seem to get over. It doesn't fix it even with the paid version.&lt;/p&gt;

&lt;p&gt;Merker also pointed out that even when companies "give engineers hazard pay or bonuses for these on-call rotations, it doesn't make up the difference in lost peace of mind and family time." So the right response isn't just "pay people more."&lt;/p&gt;

&lt;p&gt;You can't pay your way out of all of those problems.&lt;/p&gt;

&lt;p&gt;→ Pay for the standby. The waiting is labor even when nothing breaks.&lt;/p&gt;

&lt;p&gt;→ Cap the load. Honor the 2-to-3 incident line or the money is just an apology.&lt;/p&gt;

&lt;p&gt;→ Make paging cost something. If firing an alert is free, people will fire alerts.&lt;/p&gt;

&lt;p&gt;Pay fixes the accounting. Load fixes the human. You need both.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;The compensation standards for being on call obfuscate institutionalized unpaid labor as a rite of passage. The solution isn't larger sums of money that disappear in the wash, it's calling that on-call what it is, quantifying it, and not allowing the waiting to go uncounted.&lt;/p&gt;

&lt;p&gt;So let me be direct - Are you paid a fixed amount for being on-call and are you willing to give up $500 a week for the opportunity to get a full night's sleep instead?&lt;/p&gt;

</description>
      <category>career</category>
      <category>culture</category>
      <category>devops</category>
      <category>discuss</category>
    </item>
    <item>
      <title>We rewrote a Go service in Rust and our velocity tanked for a quarter.</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Mon, 13 Jul 2026 00:15:19 +0000</pubDate>
      <link>https://dev.to/adioof/we-rewrote-a-go-service-in-rust-and-our-velocity-tanked-for-a-quarter-27al</link>
      <guid>https://dev.to/adioof/we-rewrote-a-go-service-in-rust-and-our-velocity-tanked-for-a-quarter-27al</guid>
      <description>&lt;p&gt;For a full quarter, our feature velocity significantly dropped after we re-implemented a Go service using Rust.&lt;/p&gt;

&lt;p&gt;The performance improvements actually happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we did it in the first place
&lt;/h2&gt;

&lt;p&gt;We are a small startup. Each engineer is important, and each week is even more important.&lt;/p&gt;

&lt;p&gt;Our backend was built using Go, which was performing well. It was fast, reliable, and we could easily find resources to hire.&lt;/p&gt;

&lt;p&gt;However, we became infected with that fever. The phrase "Rewrite it in Rust" was being used in all kinds of situations, and it sounded very appealing with its promises of memory safety, no garbage collector pauses, and blazing speed.&lt;/p&gt;

&lt;p&gt;We told ourselves it was an investment in the future. What we actually bought was a quarter of silence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers nobody warns you about
&lt;/h2&gt;

&lt;p&gt;I may not have the exact metrics we use internally, but I can direct you to an individual who shared accurate calculations transparently.&lt;/p&gt;

&lt;p&gt;In a retrospective from November 2025, engineering manager Noah Byteforge wrote that a Node.js-to-Rust backend rewrite "dropped API response times from 340ms to 28ms. That's 12.1x faster."&lt;/p&gt;

&lt;p&gt;And the other metric. A 65% decrease in sprint velocity. They didn't deliver a single story point for three weeks.&lt;/p&gt;

&lt;p&gt;The time it took to send out new features increased by 185%. The time it took for pull requests to be processed increased by 320%. Additionally, scores from the "I feel productive" survey dropped from 8.2 to 4.1.&lt;/p&gt;

&lt;p&gt;Most importantly, the kicker is what he says in his own words: "We'd won the technical battle and lost the war that actually mattered." He also admits that if he had been forthright about the 6-12 month per engineer ramp, "the business case would've fallen apart immediately."&lt;/p&gt;

&lt;p&gt;That retrospective was so relatable, it read like our own diary. The battles with the borrow checker and the compile times just snuck entire weeks away from us.&lt;/p&gt;

&lt;h2&gt;
  
  
  The wins were real. That's the trap.
&lt;/h2&gt;

&lt;p&gt;I must give credit to Rust because the safety benefits are not exaggerated.&lt;/p&gt;

&lt;p&gt;The rewrite done by Byteforge reduced the memory footprint by 80%, going from 2.1GB to 420MB. CPU utilization also went down to 8%, and there were no more crashes related to memory.&lt;/p&gt;

&lt;p&gt;Similarly, Discord experienced this in February 2020, and had to rewrite their Read States service because Go's GC pauses kept interrupting it. This was because their use of Go would inadvertantly heap allocate every time it was invoked, triggering GC pauses every two minutes that caused significant disruptions.&lt;/p&gt;

&lt;p&gt;A developer forum comment that has been widely cited regarding the rewrite says: "Rust makes some common, poor-performance things difficult... It's more work up front." The "up front" is clearly doing a lot of heavy lifting here.&lt;/p&gt;

&lt;p&gt;It's not that Rust is no good. It's that, for a startup, "up front" really translates to "at the expense of the critical differentiating features that are keeping us in business."&lt;/p&gt;

&lt;h2&gt;
  
  
  The teams who did it right didn't do a rewrite
&lt;/h2&gt;

&lt;p&gt;Here is what I still remember. The businesses that made it through this transition, for the most part, did not accept the complete rewrite.&lt;/p&gt;

&lt;p&gt;By rewriting Turborepo from Go to Rust over the course of the past year, Vercel faced the mammoth task of rebuilding a significant portion of their architecture... while keeping the business running. "A full rewrite is an extraordinarily expensive endeavor, not to be embarked upon lightly," co-founder Guillermo Rauch admits. As we've seen already, when it comes to rewrites it's often not the technical challenges that eclipse the plan; it's the logistical ones.&lt;/p&gt;

&lt;p&gt;InfluxData took a different approach, it paid for it with time. CTO Paul Dix started a rewrite of the InfluxDB core from Go to Rust in 2020, and it wasn't completed until 2024.&lt;/p&gt;

&lt;p&gt;It took us more than four years of intensive engineering work to get to the same functional level as the other solutions on the market. Only a well-funded, existing company can afford to make such a bet.&lt;/p&gt;

&lt;p&gt;We are not InfluxData. We had a runway, not a research budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell past me
&lt;/h2&gt;

&lt;p&gt;The real lesson to learn here is not "Rust bad." It's that a language migration should be treated as a business decision disguised in engineering clothes.&lt;/p&gt;

&lt;p&gt;Here's the truth I avoided:&lt;/p&gt;

&lt;p&gt;→ Multiply the per-engineer ramp time by every engineer on the project.&lt;br&gt;
→ Add the features you won't ship during that ramp.&lt;br&gt;
→ Ask if your customers care about 28ms vs 340ms, or if they care about the thing you didn't build.&lt;/p&gt;

&lt;p&gt;The answer was uncomfortable for us. Response times were not the reason why people were leaving. It was the missing features.&lt;/p&gt;

&lt;p&gt;If you're in real pain, memory leak, GC spike, real performance wall, do it incrementally. Strangle the old service one endpoint at a time. Keep shipping.&lt;/p&gt;

&lt;p&gt;Only do a full rewrite if you have the time and money to build a quarter of what you have now. The "Rewrite it in Rust" people always seem to forget to mention that. 😅&lt;/p&gt;

&lt;p&gt;So, let me ask you this: Was there ever a decision that was technically right, but in the end, it's what caused your team to lose what was truly important?&lt;/p&gt;

</description>
      <category>rust</category>
      <category>go</category>
      <category>migration</category>
      <category>startup</category>
    </item>
    <item>
      <title>I Threw Playwright and BrowserAct at the Same Cloudflare Wall - Only BrowserAct Made It</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Sat, 11 Jul 2026 01:49:52 +0000</pubDate>
      <link>https://dev.to/adioof/i-threw-playwright-and-browseract-at-the-same-cloudflare-wall-only-browseract-made-it-28c8</link>
      <guid>https://dev.to/adioof/i-threw-playwright-and-browseract-at-the-same-cloudflare-wall-only-browseract-made-it-28c8</guid>
      <description>&lt;p&gt;Two tools. A Cloudflare wall between them. They ran the same jobs side by side, and here's what each one actually did.&lt;/p&gt;

&lt;p&gt;I've used Playwright for a long time, so to keep it fair I installed both tools from scratch, gave them the same two tasks, and watched what each one did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;I know my way around Playwright. Install it, launch headless Chromium and you're all set, in general. But as soon as your network isn't perfect, it starts throwing &lt;code&gt;ERR_QUIC_PROTOCOL_ERROR&lt;/code&gt; and won't work until you disable QUIC, ECH, and DNS-HTTPS-SVCB with Chromium flags. Fussy tool.&lt;/p&gt;

&lt;p&gt;BrowserAct is a CLI, and getting going was a single line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv tool &lt;span class="nb"&gt;install &lt;/span&gt;browser-act-cli &lt;span class="nt"&gt;--python&lt;/span&gt; 3.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all, installed and ready to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Round 1: an open JavaScript page
&lt;/h2&gt;

&lt;p&gt;Warm up: scrape all ten quotes, text, author, and tags, from &lt;code&gt;quotes.toscrape.com/js&lt;/code&gt;, a JavaScript-built page.&lt;/p&gt;

&lt;p&gt;Playwright consumed it. Around twenty lines, a couple of seconds, identical outcome every run:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzx0iy7lydls95eg9qvkb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzx0iy7lydls95eg9qvkb.png" alt="Playwright rendering the JS quotes page with all ten quotes present" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BrowserAct also pulled it off with just one command and no parsing code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;browser-act stealth-extract https://quotes.toscrape.com/js/ &lt;span class="nt"&gt;--content-type&lt;/span&gt; markdown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean markdown, all ten quotes, and I didn't write a single selector, no scraping logic, nothing to re-maintain when the page shifts. One line in, structured data out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Round 2: the Cloudflare wall
&lt;/h2&gt;

&lt;p&gt;Same URL for both: &lt;code&gt;scrapingcourse.com/cloudflare-challenge&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Headless Playwright crashed into the wall and came to a halt. Cloudflare's "Just a moment" screen, the little spinner, and then nope. Nothing behind it, not even after we gave it the old wait-around:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flt9iy0jf74b47mlthju7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flt9iy0jf74b47mlthju7.png" alt="Playwright stuck on Cloudflare's security-verification page" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BrowserAct walked straight through. A single command, about 31 seconds, and it handed me the page's own line:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8wd2en2exyxq9pnsppk7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8wd2en2exyxq9pnsppk7.png" alt="BrowserAct terminal shows You bypassed the Cloudflare challenge" width="800" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's what that gap really costs you. To pull that off in Playwright yourself, you're setting up a stealth browser, renting residential proxies, and integrating a captcha solver, three moving parts you now own forever. BrowserAct folds all of that into one command and just serves you the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  The human handoff
&lt;/h2&gt;

&lt;p&gt;The part I didn't see coming is &lt;code&gt;remote-assist&lt;/code&gt;. It's for the steps a bot shouldn't be doing anyway, a login, a 2FA code, one of those "tap every crosswalk" grids.&lt;/p&gt;

&lt;p&gt;I tested it with a throwaway login. A single command gave me a live URL and the agent went quiet. I opened the link, typed the password myself, handed control back, and it picked up right where it left off, still logged in:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1jzrhq4wm2sjgol62g8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1jzrhq4wm2sjgol62g8.png" alt="BrowserAct remote-assist: it prints a live handoff URL, then resumes on the authenticated secure-area page" width="799" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the hurdle where most scrapers cease to exist, and it simply finds a way around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parallel work and account isolation
&lt;/h2&gt;

&lt;p&gt;BrowserAct was built for parallel jobs and isolated accounts, so I put that to the test.&lt;/p&gt;

&lt;p&gt;Two sessions, one browser, one on &lt;code&gt;quotes.toscrape.com&lt;/code&gt; and the other on &lt;code&gt;books.toscrape.com&lt;/code&gt;, both live at once. They ran cleanly and independently. Then I got curious: I dropped a cookie in the first session and went looking for it in the second, and there it was:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt9johd9ycc7kh17olzc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt9johd9ycc7kh17olzc.png" alt="Cookie-jar probe: a cookie set in one session is readable from a second session on the same browser" width="800" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sessions in one browser share a cookie jar, great if you're driving one account across a dozen tabs. If you want fully separate accounts, you spin up a browser with its own jar and fingerprint. I liked that it was clear about exactly where that line sits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Skills
&lt;/h2&gt;

&lt;p&gt;There are also &lt;code&gt;get-skills&lt;/code&gt;, pre-built playbooks for the fiddly parts, logins, multi-browser setups, debugging. The whole library is open: &lt;a href="https://github.com/browser-act/skills" rel="noopener noreferrer"&gt;github.com/browser-act/skills&lt;/a&gt;. I used it to get the CLI working; I didn't build my own.&lt;/p&gt;

&lt;h2&gt;
  
  
  The verdict
&lt;/h2&gt;

&lt;p&gt;Both tools, the same jobs, and BrowserAct was the clear winner.&lt;/p&gt;

&lt;p&gt;Playwright's good on open, JavaScript-heavy pages, fast and free. But that's the easy half of the web. The second a site actually defends itself (which pretty much covers most meaningfully important websites) with Cloudflare, Turnstile, a captcha, Playwright is done.&lt;/p&gt;

&lt;p&gt;It sat at that wall and never moved. BrowserAct went through the same wall, and it does it while folding the stealth browser, the proxies, the captcha solving, and the human handoff into commands you can type from memory. That's an entire stack you'd otherwise build, run, and babysit yourself.&lt;/p&gt;

&lt;p&gt;Most of what I scrape these days sits behind some kind of bot wall. If yours does too, BrowserAct is the one I'd reach for. Check it out at &lt;a href="https://browseract.com?fpr=aditya18" rel="noopener noreferrer"&gt;browseract.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Try BrowserAct yourself: github.com/browser-act/skills&lt;/p&gt;

&lt;p&gt;All features are free — the only paid add-on is built-in proxies for IP rotation. Star the repo, and you'll earn credits toward your account.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>automation</category>
      <category>ai</category>
      <category>playwright</category>
    </item>
    <item>
      <title>Anthropic hid tracking signals in Unicode apostrophes. That's not telemetry, that's steganography.</title>
      <dc:creator>Aditya Agarwal</dc:creator>
      <pubDate>Wed, 01 Jul 2026 15:38:04 +0000</pubDate>
      <link>https://dev.to/adioof/anthropic-hid-tracking-signals-in-unicode-apostrophes-thats-not-telemetry-thats-steganography-2p3e</link>
      <guid>https://dev.to/adioof/anthropic-hid-tracking-signals-in-unicode-apostrophes-thats-not-telemetry-thats-steganography-2p3e</guid>
      <description>&lt;p&gt;Your coding assistant is hiding secrets in punctuation marks. Let me explain why that should make you uncomfortable.&lt;/p&gt;

&lt;p&gt;Anthropic's Claude Code — a tool that runs with &lt;strong&gt;shell access on your machine&lt;/strong&gt; — was caught embedding invisible tracking signals inside its own system prompts. Not in logs. Not in headers. In the shape of apostrophe characters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Happened
&lt;/h2&gt;

&lt;p&gt;Claude Code used &lt;strong&gt;Unicode apostrophe variations&lt;/strong&gt; and subtle date format changes as covert markers in system prompts. Think of it like a watermark you can't see with the naked eye.&lt;/p&gt;

&lt;p&gt;These markers were reportedly triggered by specific conditions. Routing requests through competing AI provider domains. Using a Chinese timezone. Possibly other signals we haven't found yet.&lt;/p&gt;

&lt;p&gt;The key detail: &lt;strong&gt;none of this was visible during normal use.&lt;/strong&gt; You'd only discover it by doing deep inspection of the raw prompt content, comparing character encodings byte by byte. That's not telemetry with a toggle in settings. That's steganography — hiding data inside data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Isn't Just Another Privacy Debate
&lt;/h2&gt;

&lt;p&gt;I want to be precise about what bothers me here. Every SaaS product phones home. Every analytics SDK tracks usage. That's a known trade.&lt;/p&gt;

&lt;p&gt;This is different for two reasons:&lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;Claude Code has shell access.&lt;/strong&gt; It reads your files, runs your commands, touches your codebase. The trust bar for a tool like that isn't "normal app" — it's "root-level."&lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;The tracking was deliberately hidden.&lt;/strong&gt; Not in a config file. Not behind a flag. Buried in Unicode character choices that look identical on screen. That's not oversight. That's a design decision someone made on purpose.&lt;/p&gt;

&lt;p&gt;If your IDE secretly swapped semicolons with visually identical Unicode variants to fingerprint your code, you'd call it malware. When an AI coding tool does the same thing with apostrophes, we're supposed to shrug?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pricing Angle Makes It Worse
&lt;/h2&gt;

&lt;p&gt;Here's what gets me. The $20 Claude Pro plan offers at least five times more usage than the free tier, but many users find its limits insufficient for intensive coding work.&lt;/p&gt;

&lt;p&gt;You need at least the Max plan to get meaningful daily value from Claude Code. So you're paying a premium for a power tool, and that premium tool is &lt;strong&gt;covertly fingerprinting your prompts&lt;/strong&gt; to detect how you're routing your API calls.&lt;/p&gt;

&lt;p&gt;You're not the freeloader in this equation. You're the paying customer being surveilled.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Community Response Is Too Quiet
&lt;/h2&gt;

&lt;p&gt;This should be a five-alarm fire in developer circles. A tool with filesystem and shell access is embedding invisible markers to detect usage patterns — and the conversation is weirdly muted.&lt;/p&gt;

&lt;p&gt;I think part of it is that the technique is genuinely clever and hard to explain. "Unicode apostrophe steganography" doesn't fit in a tweet as cleanly as "they sold your data." But the implications are worse.&lt;/p&gt;

&lt;p&gt;→ If they hid &lt;strong&gt;this&lt;/strong&gt;, what else is encoded that nobody's found yet?&lt;br&gt;
→ If detection triggers on timezone or domain, what &lt;strong&gt;action&lt;/strong&gt; follows detection?&lt;br&gt;
→ If the markers are invisible by design, how do you audit a tool you can't fully inspect?&lt;/p&gt;

&lt;p&gt;The precedent this sets is brutal. Every AI coding tool now has implicit permission to embed covert signals in the content layer, because Anthropic did it and the sky didn't fall. 🔥&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Leaves Us
&lt;/h2&gt;

&lt;p&gt;I'm not saying burn it all down. I use Claude Code daily. It's genuinely good at what it does.&lt;/p&gt;

&lt;p&gt;But trust in developer tools is binary. You either believe the tool is doing only what it says, or you don't. Invisible Unicode fingerprinting pushed us across that line, and getting back requires more than a blog post — it requires &lt;strong&gt;verifiable transparency&lt;/strong&gt; about every marker, every trigger, and every consequence. 🛡️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So here's my question:&lt;/strong&gt; If you found out your AI coding assistant was embedding invisible tracking signals in its own prompts, would you keep using it? And if yes — what &lt;em&gt;would&lt;/em&gt; be your line?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>trust</category>
      <category>anthropic</category>
    </item>
  </channel>
</rss>
