AI 资讯
Thin vs Thick Provisioning: Which One Is Actually Eating Your Datastore?
Thin vs Thick Provisioning: Which One Is Actually Eating Your Datastore? You just got an alert: your datastore is at 92% capacity. But when you check the actual VMs, they're barely using half the storage you allocated to them. Welcome to the most common source of confusion in virtualization storage — the gap between allocated and used . This comes down to how you provisioned your virtual disks in the first place. Thin Provisioning: Pay As You Go With thin provisioning, a 100 GB virtual disk doesn't actually consume 100 GB on your datastore right away. It grows as data is written to it. Create ten VMs with 100 GB thin disks, and if they're only using 20 GB each, your datastore shows 200 GB used — not 1 TB. This is why thin provisioning is the default choice for most environments today. It lets you overcommit storage and squeeze more VMs onto the same physical hardware. The catch: you must monitor actual datastore consumption, not just allocated capacity. If every VM suddenly starts writing more data than expected, you can run out of physical space even though your dashboards showed "plenty of room" based on allocated sizes. Thick Provisioning: Reserve It All Up Front Thick provisioning reserves the full disk size the moment you create it. There are two flavors: Lazy-zeroed : space is reserved, but blocks are only zeroed out the first time the VM writes to them. Faster to create, slightly slower on first write. Eager-zeroed : every block is zeroed at creation time. Slower to provision (a 500 GB disk can take a while), but delivers the most predictable, consistent I/O performance from the very first write. Which One Should You Actually Use? A simple rule of thumb: default to thin provisioning for general-purpose VMs — web servers, file servers, domain controllers, dev/test environments. Switch to eager-zeroed thick provisioning specifically for workloads where I/O consistency matters more than storage efficiency — databases, latency-sensitive applications, anything whe
开发者
We spent two days bisecting a prompt change. The regression was noise.
Quality went from 0.81 to 0.78. Someone had edited a prompt that week. Obvious culprit, obvious investigation. Nobody had measured that re-running the same prompt scores 0.77-0.84 across seeds. 0.78 was never a regression. It was Tuesday. The number was real. The comparison was not, because nobody measured the instrument before trusting it. So now I do this in order, and the order is the whole point: Calibrate the judge. Can it separate a known-good answer from a known-bad one? A judge returning 3/4 for everything gives you a rock-steady dashboard that would stay green if the agent returned Lorem Ipsum. Measure the noise floor. Run each case across several seeds. That spread is the resolution of your instrument. Then gate. A delta smaller than the noise floor is not a small regression. It is no information at all. A gate that fires on noise gets marked flaky and gets continue-on-error added within a month. Then you have no gate. How many of your eval numbers have a measured error bar? Calibrate the judge, measure the noise floor, then gate in that order. Github Repo: https://lnkd.in/dbfwtsM6
AI 资讯
AWS Open Sources Kiro Crew for Asynchronous Coding Agents
Amazon recently announced Kiro Crew, an open-source system for running multiple Kiro coding agents across sessions, tools, and tasks. The new workspace lets developers assign asynchronous coding tasks to AI agents, allowing work such as incident investigation, ticket triage, migrations, and PR monitoring to continue without active supervision. By Renato Losio
开发者
What should the next Weekend Challenge theme be??
The next DEV Weekend Challenge launches next week, and we have some ideas up our sleeves, but we...
开发者
How to Convert Text to Binary (and Back) in JavaScript
You type "Hi" and the computer stores 01001000 01101001 . Text is just numbers wearing a costume. Here is exactly how a string turns into binary, why UTF-8 matters, and how to do the conversion both ways in a few lines of JavaScript. What "binary" actually means here Computers do not store letters. They store numbers, and every number is a run of ones and zeros. Each character maps to a code point, that number becomes a byte, and each byte is written as eight bits . The letter A has the ASCII code 65. In binary that is: 65 = 01000001 Lowercase a is 97, which is 01100001 . So the whole word "Hi" ( H = 72, i = 105) becomes: 01001000 01101001 Group the bits into bytes of 8 and you can read any binary string back into text. Text to binary in JavaScript The reliable way is TextEncoder . It hands you the raw UTF-8 bytes, so you do not have to worry about character codes above 127. function textToBinary ( text ) { const bytes = new TextEncoder (). encode ( text ); return Array . from ( bytes ) . map ( b => b . toString ( 2 ). padStart ( 8 , " 0 " )) . join ( " " ); } textToBinary ( " Hi " ); // "01001000 01101001" toString(2) gives the binary digits, and padStart(8, "0") keeps every byte a full 8 bits. Without the pad, H would come out as 1001000 (7 bits) and the string would be impossible to split back cleanly. Binary back to text Reverse the process: strip spaces, cut the string into 8-bit chunks, parse each chunk as a base-2 number, then decode the bytes with TextDecoder . function binaryToText ( bin ) { const bits = bin . replace ( / \s +/g , "" ); const bytes = new Uint8Array ( bits . length / 8 ); for ( let i = 0 ; i < bytes . length ; i ++ ) { bytes [ i ] = parseInt ( bits . slice ( i * 8 , i * 8 + 8 ), 2 ); } return new TextDecoder ( " utf-8 " ). decode ( bytes ); } binaryToText ( " 01001000 01101001 " ); // "Hi" Two checks worth adding in real code: reject anything that is not 0 or 1 , and reject a bit count that is not a multiple of 8. Those two guards catch almo
AI 资讯
A practical preflight checklist for Manifest V3 extension releases
An extension can work perfectly in development and still fail after packaging. The risky change is often not in the feature code itself. It can be a permission that moved, a host pattern that expanded, a content script that now runs somewhere new, or a browser surface that was never included in the release checklist. Here is the small preflight review I now use before testing an MV3 release. 1. Compare the packaged manifests Compare the last version you actually shipped with the new packaged version, not only the source manifest. Check separately: required permissions; optional permissions; required host access; optional host access. A permission moving from optional to required deserves attention even if the set of permission names looks familiar. 2. List every browser surface Turn the manifest into a list of things a person can interact with or that Chrome can start: action popup; options page; side panel; background service worker; content scripts; commands; externally connectable pages; declarative network rules; web-accessible resources. If a surface changed, add at least one release check for it. This sounds obvious, but it is easy to review the main popup while forgetting an options page or a host-specific content script. 3. Check where code can now run For every content script, compare: match patterns; excluded matches; frames; execution world; run timing. The JavaScript file can be unchanged while one of these settings changes the extension's behavior on real sites. 4. Test the packaged build Run the checklist against the same build directory that will be uploaded. A development build can hide packaging, path, minification, or generated-manifest differences. At minimum, reload the packaged extension and exercise one path through each changed surface. 5. Record why each check exists Instead of keeping a generic list such as “test the popup,†connect each check to a release change: host access expanded → test the new host and confirm the old hosts still
AI 资讯
I Replaced grep-Based Code Review with a Knowledge Graph + MCP. Here Are 3 Bugs Vector Search Missed.
For about a year, my AI code review setup looked like this: AI gets a PR, AI greps for related code, AI reads way too many files, AI says "looks fine." It mostly worked. Until the bugs that didn't show up in grep started shipping. The problem wasn't the model. It was the retrieval. Vector search and keyword grep are great at finding files that mention auth.py . They're terrible at finding files that depend on auth.py through three import hops, an event bus, and a decorator. That's where the bugs live. I rewired the retrieval layer with a code knowledge graph plugged in through MCP. Three bugs surfaced in the first week that vector search had been quietly missing. Here's what changed and the bugs themselves. Why grep + vector search missed these Vector search retrieves by semantic similarity . "Find code about authentication" finds auth.py , login.py , password_validator.py . Useful. Knowledge graphs retrieve by structural relationship . "What depends on auth.py ?" returns the call graph -- including event_handlers/login_event.py , which never mentions auth in its variable names but listens to a login event whose payload changes when auth.py changes. Both are valid. They answer different questions. The bugs that ship to production tend to live in the second question. The setup: code KG as an MCP server The Model Context Protocol (MCP), released by Anthropic in late 2024, lets you expose tools to a model in a standard way. By 2026 it's supported by Claude Code, Cursor, Windsurf, Zed, VS Code, and (as of GA in May 2025) the official MCP Registry hosts hundreds of servers. I used code-review-graph , an open-source tool that builds a property graph of your codebase and exposes it as an MCP server. The setup is a three-line ritual: pip install code-review-graph code-review-graph build ./my-project code-review-graph install # auto-detects Claude Code / Cursor / Windsurf The graph contains nodes for files, classes, functions, and tests, with edges for imports, calls, inheri
AI 资讯
The failures that don't fail loudly
I spent a week building an agent that upgrades dependencies and repairs what the upgrade breaks. Dependabot opens the PR and walks away; this one stays until the tests are green. The interesting part wasn't the repairs. It was that almost every serious bug I hit — in my code, in the harness, in my own agent — announced success while being wrong. The premise Detection is solved. Dependabot, npm audit and OSV all find the advisory. What nobody automates is the bit afterwards: the fix is a major version bump, the bump breaks your build, and now it's your afternoon. So: pull real advisories, spawn one subagent per vulnerable package, each on its own branch in its own sandbox. Bump, install, run the suite. If it breaks, read the failure and patch the source. Re-verify from a clean checkout. Open a PR and stop — merging is a human decision. That's the design. Here's what actually happened. 1. The advisories weren't where I looked My first scan found nothing. The manifest said js-yaml: ^3.13.1 , which sounds vulnerable, but ^3.13.1 resolves to whatever the latest 3.x is today — and that's patched. Vulnerabilities live in the resolved tree, not the manifest. Scan the lockfile, including transitive dependencies, or you scan nothing. All three advisories I eventually found were transitive dev dependencies that appear nowhere in package.json . A scanner that reads the manifest returns "you're clean" and is wrong. It doesn't error. 2. The agent caught itself The first proper scan reported 124 vulnerable packages out of 290. Then it said something I didn't expect: "Some results look suspicious — js-yaml@4.3.2 with 10 advisories, which is usually clean." It cross-checked OSV's batch endpoint against the single-query endpoint and found its own bug: it had nested version inside the package object instead of alongside it. The API silently ignored the version and returned every advisory ever filed for each package. Real answer: three. Not 124. The API didn't reject the malformed quer
AI 资讯
Nginx Load Balancing with DNS-Based Service Discovery on Incus
Nginx Load Balancing with DNS-Based Service Discovery on Incus Hari ini saya buat satu practical lab untuk memahami Nginx Load Balancing , DNS-based Service Discovery , dan operational logging dalam persekitaran self-hosted menggunakan Incus. Lab ini bermula dengan architecture yang simple: Client │ ▼ Nginx LB │ ├──► web01 └──► web02 Kemudian saya tambah satu DNS server supaya backend tidak perlu bergantung sepenuhnya kepada hard-coded IP address. 1. Architecture Final architecture: DNS dns / dnsmasq 10.107.109.18 ▲ │ DNS lookup: web.incus │ │ Nginx LB 10.107.109.69 │ Load Balancing ┌──────────┼──────────┐ ▼ ▼ ▼ web01 web02 web03 .100 .253 .xxx Ada dua jenis communication flow dalam architecture ini. DNS resolution Nginx LB ──────► DNS │ └── web.incus ↓ .100, .253, .xxx DNS hanya digunakan untuk mengetahui IP address backend. HTTP traffic Client │ ▼ Nginx LB │ ├────► web01 ├────► web02 └────► web03 DNS tidak membawa HTTP traffic . DNS hanya menjawab: Where is web.incus ? Nginx kemudian menggunakan IP yang diperoleh daripada DNS untuk melakukan load balancing. 2. Static / Hard-Coded Upstream Cara paling mudah untuk configure Nginx Load Balancer ialah dengan meletakkan IP backend secara terus. Contoh: upstream backend { server 10.107 .109.100 ; server 10.107 .109.253 ; } Architecture: Nginx LB │ ├──► 10.107.109.100 │ └──► 10.107.109.253 Kelebihan Simple Mudah difahami Predictable Sesuai untuk environment kecil Tidak memerlukan DNS service discovery Kekurangan Kalau tambah web03 : web01 web02 web03 Nginx configuration perlu diubah: upstream backend { server 10.107 .109.100 ; server 10.107 .109.253 ; server 10.107 .109.xxx ; } Kemudian configuration perlu divalidasi dan biasanya Nginx perlu di-reload. 3. DNS-Based Service Discovery Pendekatan kedua ialah menggunakan hostname sebagai service identity. Contohnya: web.incus DNS: web.incus ├── 10.107.109.100 ├── 10.107.109.253 └── 10.107.109.xxx Nginx tidak perlu mengetahui backend IP secara hard-coded. Contoh: resolver 10.
AI 资讯
Stop Guessing Your App's Resource Requirements
After development comes deployment - whether on-premise or on a cloud based environment. And then we face a simple question: how much resource should I assign to this system? What is the ideal numbers? If we get this wrong, we often need to go back time and again to fine tune - either to ensure our application is capable of handling the targeted load, or to avoid paying for resources we are not using. This article explains the approach step by step. So that we spend just enough time upfront to avoid spending exponentially more time and money at later stages. Who Is This For? This article is written primarily for developers. But if you are a manager or a CTO, there are sections written specifically for you. Feel free to jump straight there. 👉 If you are a Manager or Project Manager 👉 If you are a CTO or Architect For everyone else - the full article is worth reading top to bottom at least once. But if you are revisiting a specific topic, jump to whatever is relevant. Table of Contents Local is the Starting Point When Should You Start Thinking About Right Sizing? How Long Will This Actually Take? Start With What You Have - Your Local Setup Setting Up Your Load Generation - The Hammer The Cost of Testing - This Is Not Free Sizing Your Pod More Resources Per Pod or More Pods? Scaling - Easy to Set Up, Hard to Get Right Periodic Right-Sizing - You Are Not Done Yet Local is the Starting Point Local system is always where we start. To try things out, to check if things work. But 99% of what we test locally is the sunny day scenario. Does the MVP work? Does the happy path hold? Even if you're diligent enough to test negative scenarios, you're almost certainly not testing production-level load on your laptop. Which means you have no idea what resources your app actually needs when it matters . This is where the problem starts. On local, we routinely kill the heavy IDE, close browser tabs, shut down background processes -without ever stopping to ask: how much memory and CPU d
AI 资讯
The undo has to exist before the write does
An agent that changes something runs in the order decide, act, report. Verification, where there is any, reads what already happened. That's a fine shape for a log. As a control it's empty: by the time the check fails, the effect is already on disk, and what's left is describing the damage, attempting a repair nobody verified, or restoring from a backup whose age nobody measured. For the last few months I've been building the other order, not for one tool but for the whole path a change takes. A proposed change gets a canonical identity. Its inverse is constructed, checked, and stored before anything is applied. A gate rules on it and returns one of three verdicts. The outcome, refusals included, becomes a signed record that a third party can re-check offline with no trust in me. There's a longer draft paper behind this, deposited at doi.org/10.5281/zenodo.22168558 . It's a draft, not peer reviewed, and not a specification. This post is the part that fits in a coffee break. What I'd have to be wrong about Putting this first, because a claim that only becomes checkable after you already agree with it isn't checkable. Inverse availability. The escrow design assumes a useful fraction of write-capable tools expose something you can build an inverse from. A first census of public MCP tools put that at about 13.8% of the tools that write anything at all (census v2 stage 1, public MCP servers only, not production deployments). If the real number in production is at or under that, this is mostly a refusal machine, and "reversibility as a property" degrades into "refusal as a property", which is a much smaller and much less interesting thing to have built. That's the most dangerous fact in the project and it's mine, not a critic's. Offline re-verification. If a signed receipt can't be re-checked with networking off and no trust in the issuer, meaning signature, log inclusion and identifier consistency, then the provenance layer is a log and not a proof. This one is runnable
AI 资讯
The Architecture Behind CoxOutage.us
When an internet outage hits, users immediately turn to their phones to find out if it's just them or a widespread network issue. Because they are often relying on spotty cellular data, any tracking site needs to load instantly and deliver highly localized information. I recently launched CoxOutage.us to map and track Cox Communications disruptions. Here is a breakdown of the technical and SEO strategies I used to build it. Performance & Traffic Handling Outage trackers face a unique challenge: they get zero traffic when things are fine, and massive, sudden spikes the minute a service goes down. Aggressive Caching: I implemented LiteSpeed Cache combined with Memcached for object caching. This ensures that database queries are kept to an absolute minimum when a sudden wave of users hits the site. Edge Delivery: Everything sits behind Cloudflare for DNS management and edge-level caching, ensuring the server (hosted via InterServer) doesn't get overwhelmed during regional outages. Scalable SEO & Routing Architecture The biggest hurdle was capturing local search intent accurately. Hyper-Specific URL Slugs: Initially, you might think to use a simple routing structure like /los-angeles . However, I found that using full keyword slugs—such as /cox-outage-los-angeles —significantly boosted visibility and search performance. Automated Indexing & Schema: I utilized the Google Indexing API to push new city landing pages instantly. Paired with Rank Math, the site generates precise schema markup so search engines understand the real-time nature of the status updates. Looking Forward Right now, the focus is on scaling out the localized landing pages and refining the automated reporting pipeline. If you have experience building high-traffic, real-time alert systems or handling sudden traffic spikes, I’d love to hear your approach. Check out the live project here: CoxOutage.us Feedback and suggestions are always welcome!
AI 资讯
Building a Sub-Second Resume Parser and ATS Diff Engine
When applying for engineering roles, automated applicant tracking systems (ATS) often silently reject candidates due to parsing blockers like multi-column layouts, missing quantitative metrics, or non-standard font embeddings. To fix this latency bottleneck, I built MyRizzume ( https://myrizzume.me ) — designed to parse and score resumes end-to-end in under 1,000ms. What it checks: Layout Integrity: Validates that column and table layouts won't merge or scramble text during ATS ingestion. Action Verb Strength: Highlights passive phrases and suggests active, quantifiable replacements. Keyword Density: Compares section headers and skill blocks against common parser taxonomies. Try it out live at https://myrizzume.me and let me know how it handles your layout!
AI 资讯
I built an AI agent for production incidents. The interesting part is when it refuses to act.
I wrote this for the All Things Agentic Hackathon. Every incident-response demo you have seen ends the same way: something breaks, the agent fixes it, everyone applauds. I want to show you the opposite. Here is my agent, at 95% confidence, having correctly diagnosed a bad deployment, deciding not to roll it back. That refusal is the whole project. The question underneath At 3am an alert fires. An engineer wakes up, reads several hundred log lines, correlates them against recent deploys, and rolls something back. Most of it is mechanical. It is an obvious target for automation. But "automate it with an LLM" does not dissolve the problem, it relocates it. The new question is: how much would you let an agent change in production without asking you first? Give it too little and it is a chatbot that writes summaries. Give it too much and one confidently wrong diagnosis takes down your service at 3am with nobody watching. I named the project Sonjomon — Bengali for restraint. The autonomy ladder An agent should not have one blanket permission level. How far it may act alone is a function of two things: how confident it is, and how much damage the proposed action does if that confidence turns out to be wrong. tier = f(confidence, blast_radius) OBSERVE record findings, take no action SUGGEST recommend to a human, do not execute APPROVE stage the action, execute on explicit approval ACT execute now, then verify independently A restart is medium risk — reversible in seconds. A rollback is high risk — it shifts production traffic, and a needless rollback during a real outage extends it. Deleting data is critical, and no confidence level unlocks it. Six conditions can only ever push the tier down, never up: the blast-radius ceiling, thin evidence, a similar action that just failed, a third attempt at the same fix, a stale incident, and a global dry-run switch. Nothing pushes it up. A wrong action is far more expensive than a missed one. Three things the model does not control It
AI 资讯
Why the AI character would not calm down, and how I fixed it
An early version of Say It Ahead had a basic problem. A user could listen carefully, ask good questions, and offer a reasonable plan, but the AI character might still sound just as upset as it did at the start. That made the practice feel arbitrary. The user could not tell whether anything they said had changed the conversation. The character had a strong opening mood, but no clear reason to move away from it. The fix was not a list of magic calming phrases. It was a simple model of how a difficult conversation can move forward. This note explains that model, how the live progress display works, and where the system can still get it wrong. The first character knew how to be upset The first parent scenario was easy to start. The prompt described an angry parent, gave the parent a complaint, and told the voice to push back. The result sounded convincing for the first few turns. The problem appeared when the user handled the conversation well. The model had been told why the parent was upset, but not what would make the parent become more open. It often treated anger as the character's permanent personality. A good question might produce an answer, but the next reply could jump back to the original complaint as if no trust had been built. Adding more instructions such as 'calm down when appropriate' did not solve the problem. Appropriate is too vague. The model needed to know what evidence to watch for and how its behavior should change after seeing it. A useful character needs a reason to resist Each ready-made scenario now gives the character more than a mood. It describes what happened, what the character believes, what facts they know, why they do not trust an easy answer, and what a credible resolution would look like. For example, a parent may reject a general promise because two earlier meetings led nowhere. A manager may care less about one missed deadline than about whether the same communication problem will happen again. An interviewer may accept transferabl
AI 资讯
My first Firefox add-on was a manifest change
KH4 Companion is a small extension I built: it counts down to Kingdom Hearts IV, puts the days remaining on the toolbar badge, pulls series news and trailers from public feeds, carries a lore compendium, and hides a three-lane rhythm minigame in the popup. It has been on the Chrome Web Store since 19 August. As of this week it is also on addons.mozilla.org , which makes it my first Mozilla listing. I had been putting the port off, because "port" sounds like work. It was not. Same build, same version number, same feature set — what changed was four keys in manifest.json . This is the writeup I wanted to find before I started. The thing nobody tells you first The blocker is not your code. It is that AMO rejects the package before it ever shows you a listing form. So the order of operations is: fix the manifest, get the linter to zero errors, then worry about icons and screenshots and copy. Assets built against a package that cannot upload are wasted. npx addons-linter@latest <extension-dir> is the gate. Run it before you touch anything else. 1. Firefox needs an explicit add-on ID Chrome derives an extension ID for you. Firefox does not — in MV3 you must state it: "browser_specific_settings" : { "gecko" : { "id" : "kh4-companion@dhseadev.online" } } The email-ish form or a {8-4-4-4-12} GUID both work. Pick carefully: this ID is your update identity forever. Changing it later means a new listing, not an update. 2. There are no extension service workers in Firefox This is the real difference, and it is smaller than it sounds. Firefox runs an event page where Chrome runs a service worker. background.service_worker is simply ignored, with a BACKGROUND_SERVICE_WORKER_IGNORED warning. The cross-browser answer is the dual key: "background" : { "scripts" : [ "core/lib.js" , "background.js" ], "service_worker" : "background.js" } Chrome reads service_worker . Firefox reads scripts . One file, both browsers. Two traps live in here, and both pass a manifest review and fail at run
AI 资讯
OpenAI Is Cutting Off Cursor: The AI Coding Lock-In Lesson Every Developer Needs
Last Friday, thousands of developers opened their AI code editor and found out that one of the models inside it has an expiration date. OpenAI announced it is terminating its contract with Cursor, effective November 12, 2026. The trigger was not anything Cursor did. It was who bought them. SpaceX completed its $60 billion acquisition of Anysphere, the company behind Cursor, in mid-August. OpenAI's contract had a change-of-control clause, and the moment ownership changed, a short cancellation window opened. OpenAI used it, and it picked the latest date the clause allowed. If your daily workflow runs through an AI coding tool, this story is about you, not about Musk or Altman. It is the clearest proof yet that model access inside your editor is rented, never owned. I have spent the last two years building my own AI agent infrastructure, and this kind of news is exactly why I treat every tool in my stack as replaceable. Here is what actually happened, what it means for your setup, and the exit plan I would put in place this week. What actually happened, in plain numbers The headlines make this sound apocalyptic. The details are more useful. The deal: SpaceX agreed in June to buy Anysphere in an all-stock deal valued at $60 billion. It closed earlier this month. The cutoff: OpenAI is ending Cursor's access to its models effective November 12, 2026. It is also withholding its upcoming Astra model from the platform entirely. The stated reason: OpenAI says it cannot be confident SpaceX will operate within its terms of service. It pointed to a pattern: a Twitter data licensing deal worth about $2 million a year that Musk cut off in December 2022, and an acknowledgment earlier this year, reportedly under oath, that xAI had distilled OpenAI data for training. The actual impact: Cursor co-founder Michael Truell says OpenAI models account for roughly 5% of Cursor's AI traffic. Anthropic immediately said it would increase compute to keep Claude models flowing inside the editor.
AI 资讯
Stop Poisoning Your React Server Components | 2026 Guide
The Silent Killer of Next.js Performance: Component Poisoning In the modern React ecosystem, specifically within Next.js and the new paradigms introduced in React 19, the distinction between Server Components and Client Components is the most critical architectural concept to master. Yet, it is also the most frequently misunderstood. If you have ever imported a React Server Component directly into a Client Component, you have inadvertently "poisoned" your application. This silent performance killer is rampant in production codebases, leading to bloated bundles, broken security, and a complete breakdown of the server-side benefits you migrated to React Server Components (RSC) to achieve in the first place. What is Component Poisoning? Component poisoning occurs when a developer treats file boundaries as mere organizational choices rather than strict execution boundaries. When you write import MyServerComponent from './MyServerComponent' inside a file marked with 'use client' , you are telling the bundler to include that component in the client-side JavaScript bundle. The moment that import statement is parsed, the Server Component is stripped of its server-only capabilities—like direct database access or environment variable usage—and compiled into a Client Component. The result? Bundle Bloat: Code that was meant to stay on the server is now shipped to the browser. Broken Logic: Any code relying on Node.js-specific APIs or secret keys will throw errors at runtime because it is now executing in the browser's environment. Performance Degradation: The primary benefit of RSC—reducing the amount of JavaScript sent to the client—is completely negated. The Mental Model: Respecting the Serialization Boundary To avoid poisoning, you must shift your mental model. Client Components cannot "own" Server Components. They cannot import them, nor can they directly control their execution lifecycle. Instead, think of the Serialization Boundary . React Server Components render on the
AI 资讯
The nginx misconfigurations that fail silently
Most nginx misconfigurations announce themselves. You typo a directive, nginx -t fails, you fix it. That feedback loop is fast and it works. The dangerous ones are different. The config is valid. nginx -t passes. The server starts, serves traffic, logs nothing unusual. And the thing you configured is quietly not happening. I maintain gixy-ng , a static analyzer for nginx configs. A growing share of its checks exist for exactly this category, because it turns out static analysis is the only practical way to catch a failure that produces no signal at runtime. Here are four worth knowing about. 1. OCSP stapling that staples nothing server { listen 443 ssl ; server_name example.com ; ssl_certificate /etc/ssl/example.com.pem ; ssl_certificate_key /etc/ssl/example.com.key ; ssl_stapling on ; ssl_stapling_verify on ; } Looks right. It does nothing. OCSP stapling means nginx fetches the certificate's revocation status from the CA itself and attaches it to the handshake, so the client does not have to. To do that, nginx has to make an outbound request to a hostname. nginx does not use the system resolver for runtime lookups. It has its own, and it only exists if you configure it. No resolver in scope means the hostname never resolves, the fetch never happens, and stapling is silently skipped. Your config test passes. Your clients go do their own OCSP lookups, which is the exact thing you turned stapling on to avoid. resolver 127.0 .0.1 valid=300s ipv6=off ; resolver_timeout 5s ; Use a local resolver or your cloud provider's internal DNS. Pointing this at 8.8.8.8 sends every internal lookup off your network in cleartext, which is its own problem. Check it with: echo | openssl s_client -connect example.com:443 \ -servername example.com -status 2>/dev/null \ | grep -A 17 'OCSP response' Working stapling prints OCSP Response Status: successful . Broken stapling prints no response sent . Run it twice, since the first handshake after a reload usually goes out unstapled while the f
AI 资讯
Standing Up a GPU Cluster on AKS for vLLM
This article is Part of a series on running vLLM on AKS and walks through creating an AKS cluster with a GPU node pool, deploying vLLM onto it, and wiring up Prometheus and Grafana for visibility. Companion pieces: Choosing the right GPU | Why your autoscaler flaps | Source Setup Summary Cloud: Azure GPU node: Standard_NV36ads_A10_v5 (1× A10, 24 GB) Image / model: vllm/vllm-openai:latest serving Qwen/Qwen2.5-7B-Instruct-AWQ Observability: kube-prometheus-stack (Prometheus + Grafana), KEDA, NVIDIA DCGM exporter All commands below are bash. The steps are ordered and each one depends on the previous. Dependency chain The build order follows one chain: model → VRAM requirement → GPU SKU → region availability → quota. Step 0 — Prerequisites (one-time, survives resource group deletion) GPU quota. Request through Portal → Quotas → Compute → This article: Requested Standard NVADSA10v5 Family vCPUs = 108 in westus (108 = 3 nodes × 36 vCPUs, matching the autoscaler's max-count 3 set in step 3). Quota is granted per-subscription and survives resource group deletion, so this step happens once, not on every rebuild. A quota is Azure's per-subscription limit on how much of a resource (here, GPU vCPUs in a specific VM family) you're allowed to provision at once. New subscriptions start at 0 for GPU families since it's expensive and can be abused. You need it because without an approval, az aks nodepool add for a GPU will fail outright. The request goes through manual Azure approval, so it has to happen before you plan to build. * Prerequisites * Existing Azure Subscription: Local tooling: Helm 3+ kubectl Bash Bash Variables to set for use through the setup RG = <resource-group-name> CLUSTER = <cluster-name> LOCATION = <preferred-location> Step 1 — Create Resource group az group create -n $RG -l $LOCATION Step 2 — Create AKS cluster, on a CPU system pool az aks create -g $RG -n $CLUSTER \ --node-count 1 --node-vm-size Standard_D2s_v5 \ --generate-ssh-keys The GPU does not go on thi