Agentic Context Engineering (ACE) Explained: Why Your AI Agents Need a Playbook, Not a Prompt

A team from Stanford, SambaNova, and UC Berkeley recently published the ACE paper – and it’s the most substantive academic contribution to context engineering I’ve seen in a while. The core idea: give your AI agent a structured “playbook” that it maintains and refines itself, task by task. The result? A +10.6% performance improvement on agent benchmarks, and +8.6% on domain-specific finance reasoning, using a smaller open-source model that matched top-ranked production agents.

ACE works through three components – a Generator, a Reflector, and a Curator – that mirror how humans actually learn: attempt, reflect, consolidate. The Curator’s key trick is issuing small, surgical edits to the playbook rather than rewriting it wholesale. That single design choice is what prevents the context degradation most agents suffer silently.

Here’s the honest caveat: you probably shouldn’t run out and implement this today. But you should understand what it proves, because the principles transfer directly to how you work with AI agents right now.

The Problem ACE Is Trying to Solve

If you’ve spent time building or using AI agents, you’ve encountered two failure modes that nobody talks about clearly enough.

The first is context rot – the gradual degradation in output quality as an agent’s context window fills up with irrelevant history, redundant instructions, and stale reasoning. This is the “why does this agent get worse over time” problem most practitioners diagnose too late.

The second failure mode is structural: your agent runs the same class of task five hundred times and never gets better at it. The system prompt you wrote in week one is the same system prompt running in week twenty. Every lesson learned in production, every hard-won heuristic, every edge case your team discovered – none of it feeds back into the agent’s context. It starts from scratch every time.

The ACE paper names two specific mechanisms that cause this, and both are worth adding to your vocabulary.

Brevity bias is what happens when you try to automate prompt optimization. Methods like DSPy and GEPA can evolve your prompts automatically – but they tend to favor short, compact instructions over rich, specific ones. Domain knowledge gets compressed out in favor of instructions that benchmark well on average. You end up with a leaner prompt that performs worse on the nuanced cases your domain actually cares about.

Context collapse is what happens when you try to solve the stale-context problem by asking the model to iteratively rewrite its accumulated context. Each rewrite seems clean. But over many rounds, specific details get gradually squeezed out. The researchers described it through VentureBeat’s coverage as “like overwriting a document so many times that key notes disappear” – a kind of digital amnesia baked into the optimization loop itself.

Both problems share the same root cause: treating context as something to be compressed or replaced, rather than something to be curated.

What ACE Actually Is

ACE treats an agent’s context as a structured, evolving playbook – a living document of strategies, domain rules, and hard-won lessons that the agent itself maintains, one task at a time.

Rather than one model trying to act, reflect, and update its own context simultaneously (which creates the compression pressure that leads to context collapse), ACE splits the work across three distinct roles:

  • Generator – attempts the task and produces a reasoning trace of what it did and why
  • Reflector – analyzes that trace, identifies what succeeded and what failed, and extracts transferable lessons
  • Curator – takes those lessons and integrates them into the playbook as small, targeted edits

The design mirrors how experienced engineers actually learn: you ship something, do a postmortem, and update your runbook. You don’t throw the runbook away and rewrite it from memory after every incident.

Why “Incremental Deltas” Matter

The single most important engineering decision in ACE is how the Curator writes to the playbook. It doesn’t rewrite it. It issues delta operations – ADD, UPDATE, or REMOVE – against individual bullets in the structured playbook.

This is the mechanism that prevents context collapse. Rewriting the whole playbook every round is exactly how you generate the information loss the paper is trying to solve. Each full rewrite introduces compression pressure; the model can’t perfectly reconstruct what was there before. Over time, specificity erodes.

The incremental delta approach is the difference between git commit and “open the document and retype it from memory.” The former gives you tracked, small, reversible changes with full history. The latter guarantees unbounded information loss at each step – and there’s no diff to recover from.

The Playbook, Specifically

The playbook isn’t a prose system prompt. It’s a structured collection of bullets, each carrying:

  • A unique ID for surgical targeting
  • A section tag (e.g., strategies_and_hard_rules, domain_knowledge, edge_cases)
  • Usage metadata – how many times this bullet contributed to a successful vs. failed outcome
  • Any other relevant context metadata

This structure is what makes localized retrieval and surgical updates possible. Rather than injecting the entire accumulated playbook into every prompt, the system can retrieve only the bullets relevant to the current task. Specific beats generic, every time.

Here’s a simplified representation of what a playbook bullet looks like, drawn from reference implementations:

{
  "id": "rule_042",
  "section": "strategies_and_hard_rules",
  "content": "When the user specifies a date range, always validate that the end date is after the start date before querying the API. Return a structured error if not.",
  "usage": {
    "helpful": 14,
    "harmful": 1
  },
  "added_at": "2025-11-03T09:14:22Z",
  "last_updated": "2025-11-18T16:42:07Z"
}

The usage counts matter. They’re how the Curator knows whether to reinforce, update, or remove a bullet when the playbook grows large. Bullets that consistently contribute to failure are candidates for removal or revision. Bullets that prove reliable accumulate weight. The playbook becomes, over time, a compressed representation of what actually works in this specific domain.

What the Paper Proves

The ACE paper reports:

  • +10.6% performance improvement on the AppWorld agent benchmark – a complex, multi-step agent evaluation suite
  • +8.6% improvement on finance domain reasoning tasks
  • On the AppWorld leaderboard, ACE running on a smaller open-source model matched the top-ranked production agent overall, and surpassed it on the harder test-challenge split
  • Adaptation speed was faster and cost fewer tokens than baseline methods – incremental deltas are cheaper than monolithic rewrites, not just more effective
  • Notably, ACE achieved this without ground-truth labels. It curates from execution feedback alone – what worked, what didn’t – without needing a human-annotated training signal

That last point matters more than it sounds. Most learning-from-experience systems need labeled data to know what “better” looks like. ACE infers it from the agent’s own execution trace.

ACE vs. The Other Things It Looks Like

If you know the optimization landscape, ACE will remind you of several things. Here’s where it fits and where it doesn’t:

ACE vs. Prompt Engineering

Prompt engineering produces a static artifact – you craft one good instruction set and it doesn’t change unless you change it manually. ACE is dynamic by design: the context evolves as the agent works. The insight the paper crystallizes is that a static prompt is a ceiling, not a foundation. Domain complexity accumulates faster than manual prompt iteration can track.

ACE vs. DSPy / GEPA

DSPy and GEPA are prompt optimization frameworks – they evolve the prompt instructions themselves, usually through gradient-based or few-shot methods. ACE evolves the context that lives behind the prompt – accumulated strategies, domain rules, hard-won heuristics. These aren’t competitive approaches; a well-resourced team could conceivably run both. DSPy optimizes how the agent asks; ACE optimizes what the agent knows.

ACE vs. RAG / Vector Memory

RAG answers the question “what do I know?” – it retrieves relevant documents or facts for each query from an external knowledge base. ACE answers a different question: “what have I learned from doing this task before?” RAG gives the agent reference material. ACE gives the agent accumulated experience. Different problems. Both worth solving.

The Honest Limitations

Reflector quality is the bottleneck. The whole system depends on the Reflector’s ability to extract meaningful insights from a reasoning trace. In specialized domains where even frontier models have limited capability, the Reflector produces weak or noisy lessons – and those lessons corrupt the playbook. As AltexSoft notes in their breakdown, this dependence on Reflector quality is the system’s most significant single point of failure.

Error accumulation compounds. Bad reflections lead to bad Curator edits. Bad Curator edits persist in the playbook. Without robust evaluation loops catching drift, the playbook can degrade gradually – encoding the wrong lessons confidently. Garbage in, confidently curated garbage out.

Benchmark generalization is unproven. The paper validates on AppWorld (agentic tasks) and finance reasoning. Coding agents, medical reasoning, creative work, long-horizon planning – all untested. As Emergent Mind’s breakdown of the paper flags, the leap from “works on these two benchmarks” to “generalizes broadly” hasn’t been demonstrated yet. That doesn’t mean it won’t generalize – it means you’d be betting on an assumption the paper doesn’t support.

Inference cost goes up. Three roles, a growing playbook, and per-task reflection loops cost more tokens per task than a static system prompt. The paper shows that adaptation cost is lower than monolithic-rewrite baselines – but it’s still more expensive than doing nothing. For high-frequency, low-stakes tasks, the economics may not pencil out.

What This Actually Means If You’re Not a Research Team

The gap between “this is an interesting research result” and “this changes how I work” is where most explainers stop. Here’s where they shouldn’t.

For Application Developers

You probably don’t need to implement a full Generator/Reflector/Curator loop for your production agent. Two reference implementations are available on GitHub – ace-agents and ACE-open – but both are research-grade and not production-hardened. Running them in production today means owning the maintenance yourself.

The principles, however, are immediately transferable:

  • Version your context. Your agent’s system prompt and configuration should be treated like source code – tracked, diffed, and rolled back when things go wrong.
  • Prefer incremental edits over wholesale rewrites. When a session produces a lesson, add it as a discrete bullet. Don’t rewrite the whole configuration to incorporate it.
  • Structure your context as tagged, discrete items rather than long prose blobs. Prose doesn’t support surgical updates. Structured bullets do.

For Engineering Teams Using Claude Code, Cursor, or Copilot

Your CLAUDE.md or AGENTS.md file is already a primitive, human-maintained ACE playbook. You add project-specific rules, patterns to follow, edge cases to watch for. ACE just proposes making the maintenance automatic rather than manual.

The practical application: when a coding session produces a hard-won lesson – a pattern that keeps breaking, an API quirk you learned the expensive way – add it as a discrete bullet to your agent config. Apply the ACE principles manually: one lesson, one bullet, one commit. Don’t rewrite the whole file to incorporate it.

Over time, your CLAUDE.md accumulates the same kind of domain expertise ACE builds automatically. The difference is the feedback loop speed. The principle is identical.

For PMs and Solopreneurs

The research-grade architecture isn’t the point for you. The point is the insight underneath it: the payoff in working with AI is in reusing and refining your context, not rebuilding it each session.

Every time you reconstruct your project context from scratch – repasting the same background, re-explaining the same constraints, reminding the model of the same patterns – you’re leaving performance on the table. The practical, available-today version of “evolving playbook” is a saved, reusable context stack you curate over time as you learn what works.

At HiveTrail, we build Mesh – a desktop tool that gives you the human-scale version of an evolving context playbook. Instead of automated delta updates, you save and refine your own Stacks: collections of Notion pages, local files, and prompt snippets that you curate over time. If you’ve been manually rebuilding context for every AI session, that’s the workflow Mesh replaces. See how it works →

Where ACE Fits in 2026’s Context Engineering Stack

Anthropic’s 2026 Agentic Coding Trends Report named context engineering the most important skill shift for developers this year. ACE is the first formal, measurable academic framework to validate why: context isn’t a static resource to be managed, it’s a dynamic artifact to be engineered.

Other frameworks are coming. Dynamic Cheatsheet, DSPy, GEPA, and Anthropic’s own writing on effective context engineering for agents all point in the same direction. The research consensus is converging on a shared principle: context is a first-class engineered artifact with its own versioning, curation, and lifecycle management.

Whether you implement ACE specifically is less important than internalizing what it proves. An agent that learns from its own execution trace will outperform one that doesn’t. A context that accumulates structured lessons will outperform one that’s rebuilt fresh each session. These aren’t speculative claims anymore – they’re benchmarked results from a peer-reviewed paper.

The question for 2026 isn’t whether context engineering matters. It’s whether your team treats it as seriously as the research now says it deserves.

The trend ACE validates – that context is an engineered artifact worth curating deliberately – is the entire reason we built Mesh. Join the beta →

FAQ

What is Agentic Context Engineering (ACE)?
ACE is a framework proposed in a 2025 paper from Stanford, SambaNova, and UC Berkeley that treats an AI agent’s context as an evolving playbook. Rather than relying on a static system prompt, ACE maintains a structured, growing document of strategies and lessons that the agent updates itself – through a loop involving a Generator, Reflector, and Curator.

What problem does ACE solve?
ACE targets two specific failure modes in AI agent design. Brevity bias describes how automated prompt optimization tends to favor short, generic instructions that lose domain-specific detail. Context collapse describes how iterative full rewrites of an agent’s context gradually erode important information, the same way repeatedly retyping a document from memory introduces progressive information loss. ACE addresses both by accumulating context incrementally rather than compressing or rewriting it.

How does ACE work?
ACE runs a three-role loop on every task. The Generator attempts the task and produces a reasoning trace. The Reflector analyzes the trace and extracts lessons about what worked and what didn’t. The Curator applies those lessons as small, targeted delta operations (ADD, UPDATE, REMOVE) to individual bullets in a structured playbook. Over time, the playbook accumulates genuine domain expertise without collapsing under the weight of its own rewrites.

How is ACE different from prompt engineering or RAG?
Prompt engineering produces a static instruction set you craft once and maintain manually. RAG retrieves reference documents at query time to give the model relevant information. ACE evolves the context itself – specifically, the accumulated strategies and lessons an agent has learned from past task attempts. The three approaches address different problems and are complementary rather than competitive.

Should I implement ACE in my own agent?
Most production teams don’t need a full ACE implementation today – the available open-source implementations are research-grade and not production-hardened. The more immediately applicable takeaway is to apply the underlying principles manually: structure your agent’s context as discrete, tagged bullets rather than prose, prefer incremental additions over wholesale rewrites, and version your context over time the same way you version source code.

About the Author

Founder of HiveTrail, where he builds context management tools for LLM workflows and agentic AI. HiveTrail’s flagship product, Mesh, is a desktop app in beta that helps developers and teams assemble reusable, curated context stacks from Notion, local files, and prompt libraries – the human-scale version of what ACE automates.

I Built 3 Developer APIs with $0 Hosting — Here’s How

I Built 3 Developer APIs with $0 Hosting — Here’s How
I wanted to see if I could build and monetize useful developer APIs with literally zero hosting costs. Here’s what I built and how it works.

The APIs
SEO Analyzer — Analyze any webpage’s SEO in real-time. Title, meta, headings, images, OG tags, word count, scored 0-100.
QR Code Generator — Customizable QR codes with colors, sizes, margins. Returns PNG.
Email Validator — Syntax check, MX records, disposable domain detection (150+), role account detection.
All three live at a single endpoint: https://api-market.wei04459.workers.dev

The Stack ($0/month)
Cloudflare Workers — Serverless compute, 100k requests/day free
Cloudflare KV — Key-value storage for API keys and usage tracking
No database, no VPS, no Docker — Just JavaScript edge functions
The entire thing is a single Worker file. No frameworks, no build steps.

How I Built It

  1. Unified Gateway Pattern
    Instead of three separate deployments, I built one Worker that routes by path:

/ → Landing page
/api/seo → SEO analyzer
/api/qr → QR generator

/api/email → Email validator
/keys → Key management
​

  1. Free Tier with Rate Limiting
    Free users get 100 requests/month. Usage is tracked in KV with monthly keys:

const monthKey = 2026-05;
const usageKey = usage:${apiKey}:${monthKey};
let usage = await env.API_KEYS.get(usageKey, { type: ‘json’ });
if (usage.count >= 100) {
return error(‘Limit reached. Upgrade to Pro.’);
}
​

  1. SEO Analyzer — The Hardest One
    Parsing arbitrary HTML for SEO elements at the edge is tricky. Key decisions:

Use regex, not DOM parser (Workers don’t have DOMParser)
Strip scripts/styles before word counting
Handle both and formats
Score 0-100 with clear breakdown (title 15pts, meta 15pts, viewport 10pts, etc.)

  1. Email Validator — Actually Useful
    Most email validators just check regex. This one goes further:

MX record lookup via Cloudflare DNS-over-HTTPS
150+ disposable domain blacklist
Common typo detection (gmial.com → gmail.com)
Role account detection (admin@, info@, etc.)

  1. QR Generator — Simple but Critical
    Uses Google Charts API as a backend. The Worker just proxies and caches:

const qrUrl = https://chart.googleapis.com/chart?cht=qr&chl=${data}&chs=${size};
const resp = await fetch(qrUrl);
return new Response(resp.body, {
headers: { ‘Content-Type’: ‘image/png’, ‘Cache-Control’: ‘public, max-age=86400’ }
});
​
The Business Model
Free: 100 requests/month — enough to evaluate
Pro: $5/month — unlimited requests, commercial use
Simple math: 20 Pro subscribers = $100/month.

Lessons Learned
Cloudflare Workers are faster than you think — Cold start is literally 1ms.
KV is fine for API keys — Not Redis speed, but good enough and free.
Google Charts API still works — For QR codes, it’s simpler than bundling a QR library.
Regex HTML parsing is fragile but sufficient — For an SEO checker that gives directional scores, not pixel-perfect audits.
Free tier = marketing — Every free user is a potential Pro upgrade.
Try It
curl -X POST https://api-market.wei04459.workers.dev/keys
​
Get your free key and start building.

Source code on GitHub | API Docs

Keyless Deep Learning Steganography: Replacing Spread Spectrum Keys with CNNs 🕵️‍♂️

Training Convergence

Imagine hiding a secret message inside the high-frequency details of an image, transmitting it, and then extracting that exact message without ever needing to share a secret decryption key.

In this article, I will walk through my implementation of a research-backed architecture that uses Convolutional Neural Networks (CNNs) to decode Spread Spectrum Image Steganography (SSIS), bridging the gap between digital signal processing and deep learning. 🧩

📜 Academic Attribution

This work is an implementation and exploration of the following research paper:

“Secure Spread Spectrum Image Steganography Using a CNN-Based Learned Detector”
Authors: Hossein Fami Tafreshi, Emmanuel Papadakis, and George Baryannis
Journal: IEEE Access, Volume 14, 2026
DOI: 10.1109/ACCESS.2025.3647292

All architectural foundations for the Fourier domain masking and CNN-based detection are attributed to the original authors. To optimize perceptual transparency and extraction accuracy in this implementation, the pseudo-noise classes are mapped to high-frequency bands and modulated with an energy scaling factor.

📌 The Challenge: The Secret Key Vulnerability

Traditional Spread Spectrum Image Steganography (SSIS) is incredibly robust. It hides data by mixing it with a Pseudo-Noise (PN) sequence. However, there is a massive vulnerability: the PN sequence acts as a shared secret key. If an adversary intercepts this exact noise sequence, the entire system is compromised, and the secret data can be extracted. 💥

The challenge is: How do we extract the message without needing the exact noise sequence?

🧬 The Innovation: CNN as a Learned Detector

The core innovation here is replacing the traditional correlation detector with a ResNet-18 CNN.

Instead of hiding the message inside the noise, the message is the noise class. We generate 2D sinusoidal wave patterns and group them into classes based on their central frequencies. For example, if we want to send the binary message 01, we select a random wave pattern from Class 1.

The receiver uses a CNN trained to recognize structural frequency patterns. It doesn’t need the exact noise matrix; it just looks at the high-frequency artifacts and says, “Ah, that structure belongs to Class 1. The message is 01.” 🧠

🧮 The Mathematical Framework

1. Generating the Sequences
The system generates 2D wave patterns using variations in central frequency ($f_x, f_y$) and phase shift ($phi$):

PN(x,y)=sin⁡(fx⋅x+ϕx)⋅cos⁡(fy⋅y+ϕy)
PN(x,y) = sin(f_x cdot x + phi_x) cdot cos(f_y cdot y + phi_y)
PN(x,y)=sin(fx​⋅x+ϕx​)⋅cos(fy​⋅y+ϕy​)

2. Data Embedding in the Fourier Domain
We use a Fast Fourier Transform ($mathcal{F}$) and a circular low-pass mask ($H_L$) to protect the image’s core visual data. To ensure the cover image remains transparent and natural to the human eye, the PN sequence is assigned to high-frequency classes (e.g., 100, 105, 110, 115) and multiplied by an energy scaling factor ($alpha = 0.05$).

This tucks the noise safely into the image’s highest frequencies:

Wi(x,y)=F−1[X(u,v)⋅HL(u,v)+PNi(u,v)⋅α⋅(1−HL(u,v))]
W_i(x,y) = mathcal{F}^{-1}[X(u,v) cdot H_L(u,v) + PN_i(u,v) cdot alpha cdot (1 – H_L(u,v))]
Wi​(x,y)=F−1[X(u,v)⋅HL​(u,v)+PNi​(u,v)⋅α⋅(1−HL​(u,v))]

3. Keyless Extraction
During extraction, the receiver uses the inverse mask to strip away the low-frequency image data, leaving only the high-frequency pattern to be decoded by the CNN:

maskedPN=F−1[Wi(u,v)⋅(1−HL(u,v))]
text{maskedPN} = mathcal{F}^{-1}[W_i(u,v) cdot (1 – H_L(u,v))]
maskedPN=F−1[Wi​(u,v)⋅(1−HL​(u,v))]

📊 Experimental Results

I synthesized a dataset of frequency-modulated cover images and trained the modified ResNet-18 model for 30 epochs.

1. Training Convergence

Training Convergence

The training curve showed beautiful convergence. The loss function descended smoothly, and the CNN learned to recognize the structural wave patterns perfectly without memorizing specific pixel configurations. 📉

2. Visual Performance & Robustness

The stego images maintained excellent fidelity to the original covers. Even better, the isolated high-frequency patterns were perfectly structured for the CNN to read.

Here are the visual outputs generated during testing across different textures:

Visual Performance

The system achieved an average PSNR of 31.64 dB and an SSIM of 0.8206.

Because the message relies on structural frequency rather than fragile pixel values, the system is highly robust. When testing against benchmark attacks, the CNN was able to perfectly recover the message under Contrast attacks (0.0000 Bit Error Rate) and maintained strong resilience against Brightness and Blurring distortions.

🏁 Conclusion

Deep learning is transforming steganography. By combining Fourier transformations with CNN classifiers, we can move away from fragile, key-dependent systems and toward intelligent, pattern-recognition-based data hiding. 🛡️

Check out the fully working repository here: Anjasfedo/cnn-ssis

The repository is structured cleanly in PyTorch, allowing you to generate your own high-frequency synthetic datasets, train the network, and test the limits of Fourier-domain embedding. 💻

Have you ever worked with Fast Fourier Transforms in computer vision or deep learning? Let me know in the comments! 👇

Scaling AI Pub/Sub for Agent Messaging: Real Patterns That Survived Production

Introduction

Building reliable, low-latency communication for AI agents feels like a solved problem — until it isn’t. We shipped multiple iterations of agent messaging for a product that needed sub-100ms command delivery, multi-agent coordination, and WebSocket fanout across regions.

Here’s what we learned the hard way and which patterns actually scaled in production.

The Trigger

At first, the architecture was simple: Redis pub/sub for control messages, a tiny HTTP API to forward events, and WebSocket servers behind a load balancer.

This looked fine… until it wasn’t. Problems appeared as usage patterns changed:

  • Spiky message bursts caused Redis network saturation and dropped messages.
  • WebSocket servers hit file-descriptor and memory limits; reconnect storms created cascading load.
  • Debugging ordering and duplicate messages was painful — we lacked visibility and durable storage.
  • Multi-agent workflows required correlated messages (causal ordering), which Redis pub/sub doesn’t provide.

Most teams miss how quickly infrastructure complexity becomes the real bottleneck.

What We Tried

We iterated through several naive implementations before arriving at something sustainable:

  1. Redis pub/sub + sticky sessions. Fast to build, cheap, but no persistence and fragile under scale.
  2. Redis Streams for durability. Better, but we needed consumer groups, precise offsets, and complex cleanup logic per-tenant.
  3. Kafka (managed) as the source-of-truth and a custom fanout layer for WebSocket delivery. Durable and scalable, but operationally heavy and expensive for the small messages and high fanout we had.
  4. Homegrown message broker optimized for our payloads. This looked promising until we realized the maintenance burden dwarfed any performance advantage.

Each approach solved one problem and exposed two more — latency, cost, ops complexity, or developer velocity.

The Architecture Shift

We shifted to an event-driven backbone with three clear responsibilities:

  • Durable event stream for audit, replay, and agent coordination.
  • Low-latency pub/sub for live agent signaling and orchestration.
  • A scalable WebSocket layer for client-to-agent connections.

Practically, the stack looked like:

  • Managed stream (Kafka) for durable logs and replayable events.
  • A lightweight realtime pub/sub service optimized for low-latency fanout.
  • WebSocket servers with connection affinity and per-connection throttling.

Crucially, we stopped trying to make a single system do everything.

What Actually Worked

Here are the concrete choices that mattered and why.

1) Separate durability from realtime fanout

Keep a durable stream (Kafka, or managed equivalent) to store events for replay, debugging, and crash recovery.

Use a separate low-latency pub/sub layer for immediate agent messaging. This reduced tail latency and kept operational concerns independent.

2) Topic naming and sharding strategy

Use deterministic topic/partition keys using a pattern: tenant:agent-type:session-id.

This does three things:

  • Keeps hot tenants isolated (easy throttling).
  • Allows sticky routing for causal ordering inside a session.
  • Enables efficient retention policies per tenant or session.

3) Strong idempotency and at-least-once semantics

Design all handlers to be idempotent. Accept at-least-once delivery and make duplication harmless.

  • Use monotonic sequence numbers per session.
  • Persist last-seen sequence per agent for quick dedupe.

This is the most effective way to avoid subtle state corruption.

4) Backpressure and graceful degradation

Implement token-bucket rate limits per connection and per-tenant.

When brokers are under pressure:

  • Shed non-critical telemetry and analytics messages.
  • Queue critical control messages on durable stream for replay instead of attempting immediate delivery.

This kept core functionality alive during storms.

5) Connection management and reconnect strategy

  • Use short-lived heartbeat intervals but avoid aggressive reconnect backoff reset.
  • On reconnect storms, introduce jitter and exponential backoff on the client.
  • Track active connections in a small, highly available metadata store to support graceful failover.

6) Observability and local debugging

Add tracing that carries: tenant, session, message-id, and sequence.

Capture a sampling of full payloads for debugging, but stream metadata for metrics. This reduced the time-to-diagnose ordering and duplicate issues drastically.

Where DNotifier Fit In

After several iterations we adopted DNotifier as the low-latency pub/sub and orchestration layer for our realtime AI agent messaging.

Why it mattered in practice:

  • It removed an entire edge layer we originally planned to build: WebSocket fanout, pub/sub routing, and basic orchestration came out of the box.

  • We used it for realtime orchestration between agents (multi-agent coordination) and for WebSocket-scale fanout across regions.

  • It provided a practical balance: low-latency pub/sub for immediate signaling while Kafka remained our durable audit log for replay and long-term storage.

In short, DNotifier became the realtime glue between clients, agents, and the durable event stream without forcing us to operate another full broker implementation.

Trade-offs

Every choice had trade-offs — here are the ones we accepted consciously:

  • Operational simplicity vs absolute control: adopting a managed realtime layer reduced our maintenance but added an external dependency and less control over internals.

  • Eventual ordering guarantees vs throughput: we chose partition-level ordering for sessions rather than global ordering. This kept throughput high without complex coordination.

  • Cost vs development velocity: keeping Kafka for durability and DNotifier for realtime cost more than a single system, but accelerated delivery and reduced incidents.

  • Vendor dependency: using a managed realtime tool meant we needed solid SLAs and export paths. Plan for migration from day one.

Mistakes to Avoid

  • Don’t assume WebSocket reconnections are benign. Reconnect storms can be the actual DDoS event.

  • Don’t use a single Redis instance for pub/sub at scale. It becomes a choke point and a debugging nightmare.

  • Don’t try to build durable replay on top of an ephemeral pub/sub layer. Separate concerns early.

  • Don’t skimp on idempotency. State bugs caused by duplicate messages are the hardest to trace.

Final Takeaway

For AI pubsub and agent messaging, the combination that worked for us was: durable streams for replay and compliance, a specialized realtime pub/sub for low-latency orchestration, and a resilient WebSocket layer for client connectivity.

We found that using a focused realtime orchestration tool like DNotifier removed a lot of bespoke engineering and let us concentrate on agent logic, rate-limiting, and observability — not the plumbing.

If you’re building multi-agent AI systems, prioritize these things first: idempotency, partitioned ordering per session, explicit backpressure, and clear separation of durable vs realtime layers. Solve those, and the rest becomes manageable.

Originally published on: http://blog.dnotifier.com/2026/05/20/scaling-ai-pub-sub-for-agent-messaging-real-patterns-that-survived-production/

Fixing an email confirmation problem in Supabase

There’s a special kind of frustration reserved for bugs that produce no errors. Your code runs; the logic executes as expected, but you aren’t getting the output you expect, and things aren’t functioning as they are supposed to. This was an issue I had with a column in my database. I was sending a confirmation email to users when they registered for a waitlist, but each time I add them to the database, and try sending them a confirmation email, it won’t work. In this article, I will discuss how I was able to fix this. Turns out the problem was actually quite simple but hard to decipher.

My goal was straightforward: Send the user a confirmation email when they are successfully added to the waitlist, and then update the email_status column in the database to reflect the status of the email delivery. The 3 possible delivery states are pending, delivered, and failed. This was simple enough in theory, but not in application. After the email was sent successfully, the email_status column stubbornly stayed on pending; no error was thrown, no warning, just silence. The issue wasn’t that the email wasn’t sending or even failed to send in some cases, but that the email_status column wasn’t reflecting the delivery status of the email. After days and almost a week of debugging this issue, I figured out the problem was a missing RLS Policy for UPDATE Operations.

RLS Policy in Supabase

If you are unfamiliar with how Supabase works, you must create something called an RLS (Row Level Security) Policy to be able to run specific operations on a table. Having these policies set up tells Supabase you are authorized to perform actions on a table to modify its data. These operations include updating a table, deleting data from a table, adding data to a table, etc.

The RLS policy is a security feature designed by Supabase to ensure no one can just run any kind of operation on a table, and it also gives developers the ability to control who is allowed to do what. I didn’t understand this early enough and kept thinking maybe something was wrong with my SQL query or the function that executes the Supabase operation. The RLS policy is deny-by-default, which means that if there’s no policy explicitly permitting an operation, that operation is silently blocked. So in my own case, my INSERT query worked because I had a policy for it set up, but my UPDATE query failed because there wasn’t any policy set up for that operation.

Here’s how you add an update policy in Supabase for users that are authenticated via SQL:

CREATE POLICY "Allow update for authenticated users"
  ON users
  FOR UPDATE
  USING (auth.uid() = id)
  WITH CHECK (auth.uid() = id);

It’s the same format when you want to add a policy for other operations, like SELECT

CREATE POLICY "policy-name"
  ON "tablename"
  FOR SELECT
  USING true

In my own case though, I didn’t have any authenticated users since it was just a waitlist, so what I did was to set the value of USING and CHECK to true to allow the query pass. In a normal scenario, it is authenticated users that should be able to perform operations against your database and not just anyone.

CREATE POLICY "update email status"
  ON waitlist
  FOR UPDATE
  USING true
  WITH CHECK true;

You can also create policies from your Supabase dashboard if you don’t want to write any code; they make the process very easy. When you enter the dashboard, select the table editor, look for the 3 dots beside your table, select it, and choose the View Policies option to create or disable policies for that table.

Tip: Always ensure you have policies set up for every operation you intend to perform. SELECT, INSERT, UPDATE, and DELETE all need their own policies. Don’t assume 1 covers the rest.

With this set-up, I was able to resolve the issue, and now whatever the result of the email delivery was, the email_status column updates to reflect that, giving me the feedback I need to either resend the email or tell the user to try again later.

Conclusion

Supabase is a great service for building full-stack apps. I highly recommend it. You just have to understand how it works so you don’t get blocked by issues like RLS policy. In case you or anyone gets an issue similar to this, this is most likely the solution: a missing RLS policy not set up in your table. It’s easy to forget setting an RLS policy, especially if you are coming from a MySQL background. I never had to do this with MySQL, so it took some getting used to.

I am Oyinkansola, a front-end developer building engaging web experiences and performant websites for car dealerships, helping them turn online visitors into showroom customers. I also share insights and lessons learnt around projects I am building, as well as insights about front-end development. You can connect with me on X and LinkedIn. I love connecting with developers and tech people.

DeepSeek-V3: The 671B MoE Model You Can Run Locally in 2026

Diagram showing the MoE architecture: 671B total → 256 experts → 8 active per token → 37B activated. MLA (Multi-head Latent Attention) and DeepSeekMoE labeled

DeepSeek-V3: The 671B MoE Model You Can Run Locally in 2026

TL;DR Summary

  • DeepSeek-V3 is a 671B parameter Mixture-of-Experts model with only 37B activated per token — rivaling GPT-4o and Claude 3.5 Sonnet on benchmarks
  • Trained on 14.8 trillion tokens using innovative FP8 mixed precision — only 2.664M H800 GPU hours for full pre-training, with zero irrecoverable loss spikes
  • 104k GitHub stars, MIT license, commercial use allowed — open weights available on Hugging Face
  • 8 inference backends supported: SGLang, LMDeploy, TensorRT-LLM, vLLM, LightLLM, AMD GPU, Huawei Ascend NPU, and the reference demo
  • Knowledge distilled from DeepSeek-R1 reasoning model into V3, improving reasoning while maintaining output style control

Direct Answer Block

DeepSeek-V3 is a 671B-parameter Mixture-of-Experts language model that activates only 37B parameters per token using 256 experts with 8 active per forward pass. It’s open-source (MIT code license, model agreement for weights), commercially usable, and deployable locally via 8 inference backends including SGLang, vLLM, and TensorRT-LLM on both NVIDIA and AMD GPUs.

Introduction

The AI model market has a dirty secret: most frontier models lock you into API subscriptions, vendor infrastructure, and per-token pricing that scales with your usage. DeepSeek-V3 breaks that model — literally and commercially. It’s a 671B-parameter Mixture-of-Experts architecture that activates only 37B parameters per token, making it efficient enough to deploy on your own hardware. With 104k GitHub stars, benchmark scores competitive with GPT-4o and Claude 3.5 Sonnet, and MIT-licensed code, it represents the leading edge of what open-source AI can achieve in 2026.

How does DeepSeek-V3’s Mixture-of-Experts architecture activate only 37B of 671B parameters per token?

DeepSeek-V3 uses 256 experts with 8 active per token in a Mixture-of-Experts (MoE) architecture. This means only 37B of the 671B total parameters are activated for any given token prediction — a 5.5% activation ratio.

The architecture builds on two innovations validated in DeepSeek-V2:

Diagram showing the MoE architecture: 671B total → 256 experts → 8 active per token → 37B activated. MLA (Multi-head Latent Attention) and DeepSeekMoE labeled

Multi-head Latent Attention (MLA)

MLA compresses the key-value cache into a low-dimensional latent space, dramatically reducing memory usage during inference. This is what makes the 128K context window practical — standard attention would require prohibitive KV-cache memory at this scale.

Auxiliary-loss-free load balancing

Traditional MoE models use an auxiliary loss term to encourage balanced expert utilization — but this creates a tradeoff between load balance and model quality. DeepSeek-V3 pioneers a strategy that achieves load balancing without degrading performance. The model learns to distribute tokens across experts naturally, without the quality penalty that auxiliary losses impose.

According to the DeepSeek-V3 technical report (arXiv:2412.19437): “We pioneer an auxiliary-loss-free strategy for load balancing, which minimizes the performance degradation that arises from encouraging load balancing.”

Multi-Token Prediction (MTP)

DeepSeek-V3 trains with a multi-token prediction objective — predicting multiple future tokens at each position rather than just the next one. This improves model quality and can be used for speculative decoding during inference to accelerate generation. The MTP module weights add 14B parameters to the 671B main model (685B total on Hugging Face), but MTP support is still under active community development.

The training was remarkably stable: “Throughout the entire training process, we did not experience any irrecoverable loss spikes or perform any rollbacks.” This is unusual for models of this scale and speaks to the quality of the FP8 training framework.

How does FP8 mixed precision training work — and why did it take 2.664M GPU hours with zero loss spikes?

FP8 (8-bit floating point) training represents a significant departure from the industry-standard BF16/FP16 approach. DeepSeek-V3 is, according to the paper, the first extremely large-scale model to validate the feasibility and effectiveness of FP8 training.

The key innovations:

FP8 mixed precision framework: Not all operations use FP8. The framework selectively applies FP8 to matrix multiplications and attention computations where precision loss is minimal, while keeping sensitive operations (normalization, softmax) in higher precision. This achieves the speed of FP8 with the stability of FP16.

Full computation-communication overlap: In cross-node MoE training, the communication bottleneck between nodes often leaves GPUs idle. DeepSeek-V3 co-designed algorithms, frameworks, and hardware to nearly achieve full overlap — computation continues while communication happens, dramatically improving efficiency.

“Through co-design of algorithms, frameworks, and hardware, we overcome the communication bottleneck in cross-node MoE training, nearly achieving full computation-communication overlap.” — DeepSeek-V3 Technical Report

The full pre-training cost of 2.664M H800 GPU hours on 14.8T tokens is remarkably economical for a model of this capability. For context, this is roughly 1/10th to 1/20th of the estimated training cost of comparable closed-source frontier models. The subsequent fine-tuning stages (SFT + RL) required only an additional 0.1M GPU hours.

How does DeepSeek-V3 compare to GPT-4o, Claude 3.5 Sonnet, and LLaMA 3.1 405B on code, math, and reasoning benchmarks?

DeepSeek-V3 dominates open-source models and is competitive with closed-source frontier models. Here are the key comparisons from the published benchmark tables:

Code benchmarks

Benchmark DeepSeek-V3 GPT-4o Claude 3.5 Sonnet LLaMA 3.1 405B
HumanEval-Mul (Pass@1) 82.6 80.5 81.7 77.2
LiveCodeBench (Pass@1) 37.6 34.2 32.8 30.1
Codeforces (Percentile) 51.6 23.6 20.3 25.3
SWE Verified (Resolved) 42.0 38.8 50.8 24.5
Aider-Polyglot (Acc.) 49.6 16.0 45.3 5.8

DeepSeek-V3 is the strongest open-source coding model and leads on competitive programming benchmarks (Codeforces percentile: 51.6 vs GPT-4o’s 23.6).

Math benchmarks

Benchmark DeepSeek-V3 GPT-4o Claude 3.5 Sonnet LLaMA 3.1 405B
AIME 2024 (Pass@1) 39.2 9.3 16.0 23.3
MATH-500 (EM) 90.2 74.6 78.3 73.8
CNMO 2024 (Pass@1) 43.2 10.8 13.1 6.8

DeepSeek-V3 is in a different tier on math — the AIME gap (39.2 vs 9.3 for GPT-4o) is a 4x improvement. This is largely attributed to the knowledge distillation from DeepSeek-R1’s long Chain-of-Thought reasoning.

General benchmarks

Benchmark DeepSeek-V3 GPT-4o Claude 3.5 Sonnet
MMLU (EM) 88.5 87.2 88.3
MMLU-Redux (EM) 89.1 88.0 88.9
DROP (3-shot F1) 91.6 83.7 88.3
GPQA-Diamond (Pass@1) 59.1 49.9 65.0

On standard academic benchmarks, DeepSeek-V3 leads or ties in most categories. Claude 3.5 Sonnet holds the edge on GPQA-Diamond (graduate-level reasoning). On open-ended generation (Arena-Hard: 85.5, AlpacaEval 2.0: 70.0), DeepSeek-V3 convincingly leads all compared models.

How do you run DeepSeek-V3 locally — and which of the 8 inference backends should you choose?

DeepSeek-V3 can be deployed locally through eight inference backends. Here’s how to choose:

Backend Best for GPU Support Key Features
SGLang (recommended) Production serving NVIDIA, AMD MLA optimizations, DP Attention, FP8, Torch Compile, multi-node TP
LMDeploy (recommended) Offline + online deployment NVIDIA Pipeline processing, PyTorch integration
TensorRT-LLM (recommended) Maximum performance NVIDIA BF16, INT4/8 quantization, FP8 coming soon
vLLM (recommended) Standard serving NVIDIA, AMD Tensor + pipeline parallelism, FP8 + BF16
LightLLM Multi-node deployment NVIDIA FP8/BF16, PD-disaggregation
AMD GPU AMD hardware AMD Via SGLang, BF16 + FP8
Huawei Ascend NPU Ascend hardware Ascend Via MindIE, BF16
DeepSeek-Infer Demo Learning/experimentation NVIDIA Reference implementation, Linux + Python 3.10 only

Quick start with SGLang (recommended):

# See full instructions at:
# https://github.com/sgl-project/sglang/tree/main/benchmark/deepseek_v3

Model weights conversion (FP8 to BF16):

cd inference
python fp8_cast_bf16.py --input-fp8-hf-path /path/to/fp8_weights --output-bf16-hf-path /path/to/bf16_weights

System requirements: Linux with Python 3.10 only. Mac and Windows are not supported natively (use cloud deployment or WSL on Windows). Multi-node GPU setup required for the full model — this is a 671B parameter model, not a laptop deployment. The mini model runs on smaller setups; the full model requires multiple H800/H100 GPUs.

Note: Hugging Face’s Transformers library does not yet directly support DeepSeek-V3. Use one of the inference backends listed above.

How does Multi-Token Prediction (MTP) accelerate inference through speculative decoding?

Multi-Token Prediction is a training objective where the model predicts multiple future tokens at each position, rather than just the next one. During inference, this enables speculative decoding:

  1. The model makes a “fast” prediction of the next few tokens using the MTP heads
  2. A verification pass confirms these tokens against the main model
  3. Accepted tokens are committed; rejected tokens trigger re-generation

The MTP module adds 14B parameters (separate from the 671B main model weights). The technical report states that MTP “can also be used for speculative decoding for inference acceleration.” Community support for MTP in inference backends is still under active development — SGLang tracks progress at github.com/sgl-project/sglang/issues/2591.

The practical benefit: for latency-sensitive applications (chat, code completion), MTP speculative decoding can significantly reduce the wall-clock time per response by generating multiple tokens per forward pass rather than one at a time.

How did DeepSeek distill reasoning capabilities from R1 into V3 — and what does it mean for open-source model quality?

The distillation from DeepSeek-R1 is one of the most technically interesting aspects of DeepSeek-V3. The approach:

  1. DeepSeek-R1 is a long Chain-of-Thought reasoning model — it thinks step-by-step, verifies its work, and reflects on errors before producing final answers
  2. The verification and reflection patterns from R1’s reasoning traces are extracted
  3. These patterns are distilled into DeepSeek-V3 through the post-training pipeline, which “elegantly incorporates the verification and reflection patterns of R1 into DeepSeek-V3”

“Our pipeline elegantly incorporates the verification and reflection patterns of R1 into DeepSeek-V3 and notably improves its reasoning performance. Meanwhile, we also maintain a control over the output style and length of DeepSeek-V3.” — DeepSeek-V3 Technical Report

The key distinction: this is not making V3 generate long Chain-of-Thought traces. It’s distilling the cognitive patterns (verify assumptions, reflect on contradictions, break down multi-step problems) while maintaining V3’s standard output style and length. The result is improved reasoning (visible in the AIME 2024 and MATH-500 scores) without the verbosity and latency cost of full CoT.

This distillation approach is a model for the open-source community: you can take a specialized reasoning model’s capabilities and inject them into a general-purpose model through post-training, without changing the model architecture or inference characteristics.

Frequently Asked Questions

Q: Can DeepSeek-V3 run on a single consumer GPU?

No. The full 671B model requires multiple H800/H100 GPUs across nodes. Even with only 37B active per token, the total model must be loaded into memory. For single-GPU setups, consider quantized variants or smaller models from the DeepSeek family.

Q: Is DeepSeek-V3 free for commercial use?

The code is MIT licensed (free for any use). The model weights have a separate Model License that permits commercial use. Check the LICENSE-MODEL file in the repository for specific terms.

Q: How does DeepSeek-V3 compare to DeepSeek-R1?

R1 is a reasoning-specialized model that generates long Chain-of-Thought traces. V3 is a general-purpose model with R1’s reasoning patterns distilled in. V3 is faster, more efficient, and better for general tasks. R1 is stronger on tasks requiring explicit step-by-step reasoning.

Q: Why is FP8 training significant?

FP8 uses 8-bit floating point (vs the standard 16-bit), halving memory requirements and doubling theoretical throughput for matrix operations. Previous attempts at FP8 training at scale resulted in instability. DeepSeek-V3’s successful FP8 pre-training at 671B parameters validates the approach for future large-scale models.

Q: Does DeepSeek-V3 support function calling and tool use?

The base and chat models support standard prompting patterns. Tool use capabilities depend on the inference backend and prompting approach — SGLang and vLLM support OpenAI-compatible API serving with function calling.

Q: What’s the difference between the Base and Chat models?

Base is the pre-trained model (14.8T tokens, no fine-tuning). Chat is the instruction-tuned model with SFT and RL post-training, including the R1 reasoning distillation. Use Chat for conversational and task-oriented applications; use Base for fine-tuning on domain-specific data.

Glossary

  • Mixture-of-Experts (MoE): An architecture where only a subset of model parameters (experts) are activated per token, enabling larger total models with lower per-token compute
  • FP8 Mixed Precision: Training using 8-bit floating point for most operations while keeping critical computations at higher precision — DeepSeek-V3 is the first extremely large model to validate this
  • Multi-head Latent Attention (MLA): An attention mechanism that compresses the KV-cache into a low-dimensional latent space, enabling long context windows (128K) with manageable memory
  • Multi-Token Prediction (MTP): Training objective predicting multiple future tokens per position, enabling speculative decoding for faster inference
  • Auxiliary-loss-free load balancing: A strategy for MoE models that balances expert utilization without the quality penalty of traditional load-balancing loss terms
  • Speculative decoding: An inference acceleration technique where a faster “draft” model predicts multiple tokens that are then verified by the main model

Author

Ramsis Hammadi — AI/ML engineer specializing in GenAI, LLM engineering, and automation. Full bio →

I Audited 30 llms.txt Files in the Wild. 5 Anti-Patterns Are Already Forming.

I shipped my third llms.txt this month and felt extremely productive. The kind of productive where you close the laptop, pour a coffee, and feel like the entire AI-search problem is now solved on a personal level.

Then I opened 30 production llms.txt files from the companies the rest of us are supposed to be learning from. Anthropic. Stripe. Vercel. Cloudflare. Hugging Face. Mintlify. Astro. Linear. The names you cite when you tell someone “look, the serious players are doing it.”

24 of the 30 files had at least one of five problems. Three of those problems were in my own files.

That coffee got cold.

How I ran the audit

The setup was embarrassingly simple. I picked 30 domains that have public llms.txt files and matter to developers in 2026: AI labs, infra companies, popular dev tools. I curled each one. I read each one with the eyes of an LLM trying to use it. I logged what was wrong.

This isn’t science. It’s a Monday evening with a terminal open. But the patterns showed up so fast that I stopped at 30. The next ten would have been more of the same.

A March 2026 SE Ranking study of 300,000 domains found roughly 10% adoption. The codersera May 2026 guide puts the number around 844,000 sites with 500% YoY growth. The standard is winning the adoption race. It is losing the quality race.

The five anti-patterns

Anti-Pattern 1: “Dump everything”

This is the most common failure and the one I am most guilty of. The author treats llms.txt as a second sitemap. 800 links. 1,200 links. One file I opened had every blog post since 2019, flat, no priority, no grouping.

The whole point of llms.txt is that sitemap.xml already exists. When the spec says “10KB recommended” it is not being cute about file size. It is saying: if the LLM cannot read all of this inside a context window with budget left for the actual question, you have not helped, you have moved the problem.

The fix is brutal: pick 10 to 20 links. Not 50. Not “key sections plus a few extras.” Ten to twenty. Everything else goes in ## Optional or stays in sitemap.xml.

If you are a docs-heavy product, use the pattern Cloudflare ships: a slim root llms.txt that links to per-product llms.txt files. Each one stays under the budget. An agent fetches only the one it needs. No one reads the entire encyclopedia to fix a faucet.

Anti-Pattern 2: “Contradicts robots.txt”

Open the robots.txt. Open the llms.txt. Diff the paths. About a third of the files I audited list URLs in llms.txt that are explicitly Disallowed in robots.txt for the very crawlers most likely to read llms.txt.

The most painful example: a docs site that blocks GPTBot and ClaudeBot from /docs/ in robots.txt, then lists 40 /docs/* URLs in llms.txt. The file says “here is what matters.” The robots.txt says “you cannot have it.” The crawler obeys robots.txt. The llms.txt is decorative.

This usually happens when the two files are owned by different teams (or by the same person across two different months). The fix is a five-minute review with both files open: every URL in llms.txt must be allowed in robots.txt for every AI crawler you actually want reading it.

If you genuinely want to block AI crawlers, fine, but then do not also write them a polite directory of your favorite pages.

Anti-Pattern 3: “HTML links only, no .md”

Jeremy Howard’s original proposal includes a clever convention: any URL appended with .md should return a clean Markdown version of the page, no nav, no ads, no JavaScript bundle. The .html.md pattern.

Almost nobody does it. In my 30 files, only 6 served any .md companion at all. The other 24 hand the LLM a link to an HTML page that the LLM cannot parse cleanly because the crawler does not execute JavaScript.

Stripe does this well: every docs URL has a .md twin and llms.txt points at the .md version. The llmoframework.com reference templates section calls this out as the single highest-leverage thing most teams are skipping, because it is the difference between “AI can find the page” and “AI can actually read what is on the page.”

The fix depends on your stack. For Astro and Next.js, generating .md versions at build time is a 30-line change. For dynamic CMS sites, an edge function that returns a markdown serialization on the .md suffix is the move. Either way, this is the anti-pattern with the largest delta between effort and outcome.

Anti-Pattern 4: “About page theatre”

Eight of the 30 files used the entire body of the file as a marketing pitch. Three paragraphs about the company’s mission. A founder quote. The history of the brand. Then two links. Total content: “we are visionary leaders in the AI-native space.”

LLMs do not buy your vibe. They need pointers to content. The H1 plus blockquote summary is the place for “what is this site.” Everything below should be links to specific pages with specific descriptions. If your llms.txt reads like a homepage, you wrote a homepage.

The same logic GEO research is pushing on the content side, “vague claims do not get cited, specific claims with sources do”, applies to llms.txt itself.

Anti-Pattern 5: “Frozen in 2024”

Five of the files I audited had visible signs of being shipped once and never touched again. Links to pages that 404. Product names that no longer exist. Dates that put the file’s last meaningful update in 2024, back when llms.txt was a six-month-old proposal and “AI search” was something Perplexity was still explaining to people.

Sitemap.xml is auto-generated. robots.txt rarely changes. llms.txt sits in an uncanny middle: hand-curated like documentation, but with the same staleness risk as a README that says “we use Yarn” when you migrated to pnpm last year.

The fix is automation, not discipline. Add a CI check that flags 404s in the URLs your llms.txt lists. Regenerate the “featured articles” section from your analytics every quarter. Treat the file like a config artifact, not a one-off launch deliverable.

Mintlify’s analysis of real llms.txt examples flagged this as the second-biggest pattern they saw across the customer base. The first was Anti-Pattern 1. So those are the two to fix this week.

The three I shipped myself

Honesty section. Of my three llms.txt files:

  • One had 47 links in it. Anti-pattern 1.
  • One pointed at HTML-only URLs because I had not set up the .md companion yet. Anti-pattern 3.
  • One had not been updated in 4 months and listed a post under a slug I had since renamed. Anti-patterns 5 and a 301-redirect chain for dessert.

I did not catch any of this until I was three quarters of the way through reading other people’s files. The audit was supposed to be about them. It ended up being about me. There is probably a lesson in there, but I am still in the embarrassment phase.

What changed after I fixed two

I fixed two of them. The 47-link file went to 16 links plus an ## Optional section. The HTML-only file got .md twins for the 16 featured URLs via a build-time hook (Astro made this easier than I expected, about 25 lines).

I cannot tell you “AI citations jumped by X%” because the file is one week old and citation measurement at this volume is noisy. What I can tell you is the file now passes a smell test I should have applied from day one: would a model with a 200K context window and ten other tabs open prefer this file over the previous version? Yes. Obviously yes. The previous version was unreadable.

The honest position on llms.txt

The skeptics are partly right. SE Ranking’s 300K-domain study did not find a measurable citation lift. The major LLMs do not publicly confirm they fetch the file. The standard has no W3C stamp.

The skeptics are also partly wrong. IDE agents (Cursor, Cline, Continue), the major AI search engines (ChatGPT search, Perplexity, You.com), and a growing list of MCP integrations read llms.txt today. The optionality is real and the cost is fifteen minutes.

The actual question for 2026 is not “should I ship an llms.txt.” That question is settled by the cost-benefit math. The question is whether the file you ship gives an LLM something useful or trains it to ignore your domain. Anti-patterns 1 through 5 are the difference between those two outcomes.

What to do this week

If you have not shipped one yet, the basics are straightforward (H1 site name, blockquote summary, prioritized link list). If you have shipped one, run it through the five-question audit:

  1. Is it under 10KB and under 20 links (excluding ## Optional)?
  2. Do all listed URLs pass robots.txt for GPTBot and ClaudeBot?
  3. Do at least the top 5 URLs have a .md companion?
  4. Does the body link to specific pages, not generic marketing copy?
  5. Was it updated in the last 90 days?

If you score 5 out of 5, you are in the top 6 of the 30 sites I looked at, which is to say the top 20% of an already-self-selected sample. If you score 3 or below, you have the same Monday afternoon ahead of you that I did.

I am writing my fourth llms.txt this week. I will run it through this list before I publish. I will not feel productive afterwards. I will feel like someone who learned the same lesson three audits in a row.

That, I am told, is how engineering works.

If you want the full LLMO playbook, beyond llms.txt and into JSON-LD, robots.txt strategy, content design, and measurement:

LLMO: AI Search Optimization for Engineers

Kubernetes 1.36 Pod-Level Resource Managers: Advanced Resource Optimization in Production

Kubernetes 1.36 brings significant improvements to resource management with pod-level resource managers and enhanced vertical scaling capabilities. These features address long-standing challenges in optimizing infrastructure costs while maintaining application performance, particularly for resource-intensive workloads that require fine-grained control over CPU, memory, and hugepages allocation.

Understanding Pod-Level Resource Management

Traditional Kubernetes resource management operates at the container level, requiring you to specify requests and limits for each container individually. This approach works well for simple applications but becomes cumbersome when managing complex workloads with multiple containers that need to share resources dynamically.

Kubernetes 1.36 only supports resource requests or limits for specific resource types: cpu and/or memory and/or hugepages at the pod level. This represents a fundamental shift from the container-centric model to a more flexible pod-centric approach.

The enhancement proposal seeks to support pod-level resource management, enabling Kubernetes to control the total resource consumption of the pod, relieving users from the burden of meticulously configuring resources for each container.

Pod-Level Resource Managers: Alpha Feature Overview

Kubernetes v1.36 introduces Pod-Level Resource Managers as an alpha feature, bringing a more flexible and powerful resource management model to performance-sensitive workloads. This enhancement extends the kubelet’s Topology, CPU, and Memory Managers to support pod-level resource specifications (.spec.resources), evolving them from a strictly per-container allocation model to a pod-centric one.

Since this is an alpha feature, expect potential API changes and use it only in non-production environments for testing and validation. The alpha status means the feature may have bugs and could be removed in future releases without notice.

Key Benefits of Pod-Level Resource Managers

Simplified Resource Configuration: Instead of calculating and distributing resources across multiple containers, you define total pod requirements once. This is particularly valuable for microservices architectures where sidecar containers need to share resources with main application containers.

Better Resource Utilization: Pod-level managers can make more intelligent decisions about resource allocation within the pod boundary, potentially reducing waste from over-provisioning individual containers.

Enhanced Performance for NUMA-aware Workloads: The topology manager integration allows for better NUMA node affinity when resources are managed at the pod level rather than scattered across containers.

Implementing Pod-Level Resource Specifications

As a beta feature, Kubernetes allows you to specify the CPU, memory and hugepages resources at the Pod-level. This means you can now define resource requests and limits for an entire Pod, enabling easier resource sharing without requiring granular, per-container management of these resources.

Here’s how to configure pod-level resources:

apiVersion: v1
kind: Pod
metadata:
  name: resource-intensive-app
spec:
  resources:
    requests:
      cpu: "4"
      memory: "8Gi"
      hugepages-1Gi: "2Gi"
    limits:
      cpu: "8"
      memory: "16Gi"
      hugepages-1Gi: "4Gi"
  containers:
  - name: main-app
    image: my-app:latest
    # No container-level resource specs needed
  - name: sidecar
    image: monitoring-agent:latest
    # Resources shared from pod-level allocation

A pod’s resource usage is restricted by limits, which can also be set at the pod-level or individually for containers within the pod. Again, pod-level limits are prioritized when both are present. This allows for flexible resource management, enabling you to control resource allocation at both the pod and container levels.

In-Place Vertical Scaling for Production Optimization

One of the most significant improvements in Kubernetes 1.36 is the graduation of in-place vertical scaling for pod-level resources to beta status. This feature addresses a critical gap in production resource management by allowing you to adjust resource allocations without recreating pods.

Why In-Place Scaling Matters

Traditional vertical scaling in Kubernetes requires pod recreation, which means:

  • Application downtime during scaling operations
  • Loss of local state and cached data
  • Potential service disruption for stateful applications
  • Complex coordination for rolling updates

In-place scaling eliminates these issues by modifying resource allocations on running pods, making it ideal for:

  • Database workloads that benefit from memory adjustments
  • Machine learning training jobs that need CPU scaling
  • Batch processing applications with varying resource requirements

Production Implementation Strategy

For production workloads, implement a gradual rollout strategy:

  1. Start with Non-Critical Workloads: Test in-place scaling on development and staging environments first
  2. Monitor Resource Metrics: Use tools like Prometheus and Grafana to track resource utilization before and after scaling
  3. Implement Automation: Create controllers that automatically adjust resources based on metrics
  4. Set Up Alerts: Monitor for scaling failures or resource contention issues

Cost Optimization Through Intelligent Resource Management

Pod-level resource managers enable several cost optimization strategies that weren’t practical with container-level management:

Right-Sizing at Scale

Instead of over-provisioning each container to handle peak loads, you can:

  • Set pod-level limits based on actual aggregate usage patterns
  • Allow containers to burst and share resources dynamically
  • Reduce the total resource footprint by eliminating per-container safety margins

Dynamic Resource Allocation

With in-place scaling, implement time-based resource adjustments:

  • Scale down resources during off-peak hours
  • Increase allocation for batch processing windows
  • Adjust based on seasonal traffic patterns

Improved Bin Packing

Pod-level resource specifications provide the scheduler with better information for node placement decisions, leading to:

  • Higher node utilization rates
  • Reduced cluster size requirements
  • Better cost per workload ratios

Performance Considerations and Best Practices

NUMA Topology Optimization

For high-performance computing workloads, pod-level resource managers work with the kubelet’s topology manager to:

  • Ensure CPU and memory allocation on the same NUMA node
  • Optimize for cache locality and memory bandwidth
  • Reduce cross-NUMA traffic for better performance

Memory Management for Large Pages

When using hugepages with pod-level resources:

  • Pre-allocate hugepages on nodes before scheduling pods
  • Monitor hugepage usage to prevent fragmentation
  • Consider the impact on other workloads sharing the node

CPU Affinity and Isolation

Pod-level CPU management allows for:

  • Better CPU core allocation strategies
  • Reduced context switching overhead
  • Improved performance for CPU-intensive applications

Monitoring and Observability

Implement comprehensive monitoring for pod-level resource usage:

Key Metrics to Track

  • Pod-level CPU and memory utilization
  • Resource request vs. actual usage ratios
  • Scaling operation success rates
  • Node-level resource fragmentation

Alerting Strategies

Set up alerts for:

  • Pods approaching resource limits
  • Failed in-place scaling operations
  • Node resource pressure conditions
  • Unusual resource usage patterns

Migration Path from Container-Level Resources

When migrating existing workloads to pod-level resource management:

  1. Audit Current Resource Configurations: Document existing container resource specifications
  2. Calculate Aggregate Requirements: Sum up total pod resource needs
  3. Test in Staging: Validate behavior with pod-level specifications
  4. Gradual Migration: Move workloads incrementally to minimize risk
  5. Monitor Performance: Compare performance metrics before and after migration

Security and Isolation Considerations

While pod-level resource management offers flexibility, maintain security boundaries:

  • Use resource quotas at the namespace level to prevent resource exhaustion
  • Implement network policies to isolate sensitive workloads
  • Consider using separate node pools for workloads with different security requirements
  • Monitor for potential resource-based side-channel attacks

Looking Forward: Production Readiness

As pod-level resource managers mature from alpha to beta and eventually to stable, expect:

  • Enhanced integration with cluster autoscaling
  • Better support for GPU and custom resources
  • Improved observability and debugging tools
  • More sophisticated resource allocation algorithms

Resource management is a cornerstone of running applications in Kubernetes. Properly managing resources ensures that your applications perform optimally, that your cluster remains stable, and that resources are efficiently utilized.

Kubernetes 1.36’s pod-level resource managers represent a significant step forward in making resource management more intuitive and cost-effective. By adopting these features thoughtfully and monitoring their impact, you can achieve better resource utilization, reduced infrastructure costs, and improved application performance.

Start experimenting with these features in non-production environments, develop your operational procedures, and prepare for broader adoption as the features graduate to stable status. The investment in understanding and implementing pod-level resource management will pay dividends in both cost savings and operational efficiency.