惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
S
Secure Thoughts
月光博客
月光博客
美团技术团队
雷峰网
雷峰网
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
News and Events Feed by Topic
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Forbes - Security
Forbes - Security
W
WeLiveSecurity
P
Proofpoint News Feed
阮一峰的网络日志
阮一峰的网络日志
爱范儿
爱范儿
G
GRAHAM CLULEY
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AI
AI
Last Week in AI
Last Week in AI
Google Online Security Blog
Google Online Security Blog
Schneier on Security
Schneier on Security
云风的 BLOG
云风的 BLOG
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Recent Announcements
Recent Announcements
Webroot Blog
Webroot Blog
T
Tor Project blog
Cisco Talos Blog
Cisco Talos Blog
N
News and Events Feed by Topic
罗磊的独立博客
The Register - Security
The Register - Security
Blog — PlanetScale
Blog — PlanetScale
T
Threat Research - Cisco Blogs
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
人人都是产品经理
人人都是产品经理
T
The Exploit Database - CXSecurity.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
B
Blog
腾讯CDC
Microsoft Azure Blog
Microsoft Azure Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Engineering at Meta
Engineering at Meta
Latest news
Latest news
IT之家
IT之家
D
DataBreaches.Net
博客园 - 司徒正美
N
Netflix TechBlog - Medium
V
V2EX
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Dart on the Backend: The Illusion of Cloud-Ready Performance
Alex KH · 2026-06-22 · via DEV Community

TL;DR: > * The Goal: Wanted to cut down the baseline memory footprint (80MB idle) of our Node.js microservices.

  • The Plan: Migrated an OAuth2 service to Dart using Claude Code, drawn in by promises of AOT compilation and "cloud-ready" performance.
  • The Reality: Dart VM keeps memory allocated after peak loads by design (optimized for Flutter's 60fps, not K8s). Under heavy CPU throttling, RPS dropped by 2x compared to Node.js.
  • The Lesson: AI tools make mechanical code migration free, but the cost of an unverified runtime hypothesis remains brutally high. Moved to Go.

If you are looking at Dart as a backend alternative to Node.js, it’s better to learn from someone else's mistakes. Complete benchmark results—featuring Go, Node.js, Dart, Bun, Deno, and .NET—along with methodology, configurations, and raw numbers, are available on GitHub.

What follows is an engineering drama: how 2 weeks were spent shifting architectures, why everything seemed flawless on paper, and how the "memory savings" hypothesis shattered against raw benchmark realities. More importantly, it’s about why an AI agent did everything right—and why that exactly became the problem.

Disclaimer: The biggest mistake here wasn’t choosing Dart, but the order of operations. Instead of running a raw benchmark on a production-like scenario on day one, I blindly trusted AOT compilation, static typing, and "ready for cloud" marketing claims. This isn't just about Dart; it’s a pricey lesson on validating your runtime hypothesis before building architecture around it. To avoid micro-optimization flame wars, all manifests, CPU profiles, and source code are isolated in the repository. I’m a regular JS/TS developer, not a Go or .NET guru, so if you spot a flaw, PRs are welcome.


Act I: The Marketing Honeymoon

I work on a SaaS product powered by Node.js. Generally, it satisfies all our needs: solid performance, fast development cycles, and a unified language across the stack. Sure, under heavy loads, certain services get greedy. Our OAuth2 service, for instance, would peak at 500MB of RAM. But tokens were issued smoothly, memory was eventually reclaimed, and performance degradation was strictly bound to CPU-heavy cryptography.

However, when running a SaaS with hundreds of identical microservices, an idle footprint of 80MB per instance scales into a noticeable infrastructure bill.

We began exploring alternatives. Go is the obvious candidate, but our team is JavaScript to the bone. Go triggered zero enthusiasm: err != nil tracking every line, and passing context.Context as the first argument felt like a relic from the past—vividly reminding the team of Node’s old callback hell where err was always the first argument.

Then we stumbled upon Dart. On paper, it ticked every box: AOT compilation, static typing, and a familiar syntax. The official dart.dev documentation explicitly states: "Creating scalable, high performance APIs and event-driven apps are good use cases for Cloud Run." Since it was coming straight from the source, I bought into it.

You know that honeymoon phase with a new technology? The landing page is pristine, the syntax is elegant, and you think: "This is the silver bullet! Why is everyone else still suffering with legacy tools?" You dive in headfirst.

We knew we wouldn’t hit Go-level performance. But dropping from 80MB to 10MB idle? Our AI assistant, having scraped the same marketing blogs, promised exactly that. To be fair, a barebones HTTP server compiled to AOT genuinely consumed peanuts. I ran it, verified it, and got inspired. Static typing, AOT, an 8x reduction in memory, and wiping out the black hole of node_modules—it sounded flawless.

Keyword: sounded.


Act II: The Reality of the Codebase

Problem 1: The Backend Ecosystem Ghost Town

To test the waters, we decided to rewrite our auth service. The Node.js version relied on NestJS, a custom Redis ORM, and ts-oauth2-server. Backed by Claude Code, porting a clean TS codebase with structured architecture seemed trivial. Move the structure, translate the logic, swap the runtime. What could go wrong?

As it turns out, Dart is Flutter’s world. Outside of it, the server-side ecosystem is virtually non-existent. There is no NestJS equivalent, Redis clients can be counted on one hand, and something resembling ioredis simply doesn't exist. Sure, there are Shelf and Serverpod. But we didn’t need a monolithic full-stack framework designed to bundle mobile apps (Serverpod), nor did we want to micro-manage routing like it’s Express.js in 2015 (Shelf). We needed an enterprise-grade backend architecture.

I had long wanted to build a lightweight alternative to NestJS to bypass its classic pain points—like bulky dependency trees and excessive runtime reflection magic. The thought of "Since Dart lacks NestJS, I’ll just build my own perfect mini-framework" felt incredibly empowering at the time. I was already imagining the GitHub stars. Combined with an un-capped AI agent token limit and a habit of reinventing wheels, the plan felt as precise as a Swiss watch.

Problem 2: Language Constraints & Code Generation Hell

I remember the early 2010s hype when Google pushed Dart as a JavaScript replacement. After writing actual production code in it, I finally understood why that push failed.

Want to iterate over an object's properties with a simple for...in loop? Forget it. Want to invoke a static method dynamically via a reference to a Type? No chance. The Type primitive is severely limited, and invoking anything on it in AOT mode is blocked by design. Runtime reflection is stripped out for AOT. But how do you build a proper DI container without reflection?

Okay, I thought, time to accept the Dart gospel and stop writing TypeScript in Dart. I looked at how the ecosystem deals with this, and hit the ultimate developer nightmare: pervasive, heavy code generation.

Dart’s approach is highly intrusive: every file requires a manual part 'file.g.dart' declaration. Your clean source file is intrinsically coupled to a file that doesn't exist yet. You are left with two options: either commit thousands of lines of auto-generated clutter into your repository, or run heavy build runners on every single pipeline stage.

To minimize this mess, I used an experimental flag (--enable-experiment=enhanced-parts) and wrote a custom CLI tool. The workflow looked like this: spin up the entry point in JIT mode → extract annotations and types via dart:mirrors → convert ClassMirror to descriptors → trigger annotations → generate files needed for AOT. Something that requires three lines of runtime reflection in C#, Java, or TS here required building an entire toolchain piping infrastructure.

Paradoxically, the core language is pleasant. Writing Dart code feels smooth, logical, and highly predictable; most errors are caught early during compilation. Claude Code managed to port ioredis in a few hours—resulting in 4,500 lines of Dart against 23,500 lines of the original TypeScript. The syntax is clean enough that even an AI writes it elegantly. But the moment you venture beyond writing basic business logic, you hit a wall. Because of this friction, nobody builds tooling, leaving the ecosystem stagnant.

Over two weeks, we engineered a NestJS-like framework with hierarchical DI (similar to Angular), transport layer isolation, request-scoping via Zone, and a code-gen CLI. Claude flawlessly ported our Redis ORM. On the surface, everything looked spectacular. Yet, an unsettling feeling remained. On day 14, I finally decided to run a clean, isolated load test.


Act III: The Production Reality Check

Problem 3: Performance Under Throttling

I set up a straightforward benchmark: three endpoints, Postgres, Redis, and identical infrastructure bounds for all runtimes. No frameworks, no ORMs—just raw HTTP servers to evaluate the execution engines themselves.

I anticipated Dart scoring slower than Go, but easily outperforming Node.js. The initial results forced a quick reality check.

At baseline, Dart looked unbeatable: instant boot time, 3MB RSS versus Node’s 18MB, and a tiny 5MB Docker image. But as soon as traffic hit, the illusion collapsed.

In terms of Requests Per Second (RPS), Dart scored nearly 2x worse than Node.js. But lower RPS was only half the issue. Under strict Kubernetes resource limits (100m CPU) and 500 Virtual Users (VUs), Dart’s p95 latency spiked to a staggering 9.5 seconds. Node.js clocked 5 seconds under identical constraints, while Go managed 2.9 seconds. A 9.5-second p95 latency under load isn't just "slow"—it means cascading timeouts and an immediate production outage.

Memory behavior was even more telling. At peak CPU load, both runtimes sat around 39-47MB. However, once traffic dropped, Node.js released up to 80% of its allocated memory back to the OS. Dart released virtually nothing (roughly 5%), permanently holding onto its peak allocation.

I experimented with every available Garbage Collector configuration flag: --dontneed_on_sweep, --use_compactor, --force_evacuation, --mark_when_idle, --old-gen-heap-size. Nothing shifted the behavior. Eventually, the Dart VM team confirmed it: this is by design.

The Dart VM is meticulously tailored for Flutter. Its priority is minimizing GC pause spikes to guarantee a seamless 60fps UI rendering on mobile screens. Releasing RSS back to the OS host is an afterthought. While brilliant for client-side mobile apps, this design is catastrophic for Kubernetes containers.

Kubernetes has no awareness that your process is just "caching memory for later use". It reads the active RSS usage. If an HPA (Horizontal Pod Autoscaler) scales your service to 10 pods during a traffic surge, those Dart pods will permanently retain that peak memory long after traffic subsides. The cluster cannot bin-pack or downscale nodes effectively. Node.js pods would shrink back down, freeing cluster resources, while Dart forces you to pay for your peak usage indefinitely.

And this is an engine marketed as "ready for cloud" on Google Cloud Run—a serverless platform billed exactly on a memory × time metric. Hosting Dart here is literally more expensive than running Node.js.

The final indicator of ecosystem neglect: our ioredis port, mechanically spit out by an AI agent, yielded 5% higher RPS than the most popular, community-vetted Redis client on pub.dev. That’s not a praise of AI capability; it’s an indictment of the ecosystem. No one is building or optimizing heavy server infrastructure in Dart.

The flawless marketing facade had completely crumbled.


Act IV: A Sober Retrospective

After two weeks of heavy lifting—authoring a DI engine, porting Redis clients, and running load profiles—the verdict is absolute: for backend cloud workloads, Dart is a paper tiger. Its true home is strictly Flutter. The engineering team sacrificed reflection for small mobile binaries, stalled on macro language specifications for years, and tuned the VM exclusively for client side interactions.

It’s a shame, because Dart was a few architectural adjustments away from becoming a true competitor in cloud-native microservices. A 3MB boot footprint paired with structural typing is fantastic. If the GC promptly returned unneeded memory to the host OS, it would fit the serverless lifecycle perfectly: rapid scaling on surges, instant contraction post-load. Sadly, prioritizing mobile UI frame rates over container resource elasticity killed its entire server capability.

Ultimately, my search for a silver bullet led me right back to Go. Yes, it can feel repetitive, verbose, and demanding of explicit err != nil handling. But in a real-world production environment—throttled by CPU ceilings, managing database network hops, and requiring nimble memory management—Go simply scales. It delivers 1.5x to 3x the RPS of Node or Dart under strict constraints and reclaims memory flawlessly.

(As a side note, Bun performed exceptionally well in our tests, creeping close to Go's throughput, but under severe 100m CPU throttling, it consistently choked, failing liveness probes. For hardened K8s setups, it’s not production-ready yet).

So, I am opening up the Go tour and starting from scratch.

The Real Lesson

Commenters will rightfully point out: "A two-hour k6 script on day one would have saved you two weeks." They are completely correct.

But there is a subtle trap here that I only understood at the end of this journey. Tools like Claude Code make mechanical migration incredibly cheap—essentially free. And that's the paradox. When the cost of writing code drops to zero, it becomes dangerously easy to forget that the cost of an unverified runtime hypothesis remains identical. An AI agent won't challenge you and ask: "Are you certain this execution engine fits your infrastructure model?" It will simply build what you asked for, beautifully, swiftly, and without hesitation.

Validate the runtime hypothesis first. Only then let the AI raise the walls.

P.S. This writeup was supposed to be a quick post based on preliminary findings. Instead, validating the numbers dragged me down a benchmark rabbit hole for another two weeks: warming up containers, adjusting throttling quotas, and evaluating .NET, Bun, and Deno.

Validate your hypothesis. Validate your benchmarks. Only then write the article. One month of work instead of a two-hour test.