Normal view

Why smarter AI caching sometimes makes everything slower

Abstract 3D digital render of geometric concrete blocks and glowing red and cyan glass cubes, symbolizing complex AI database caching layers and infrastructure latency.

Caching was one of the most critical optimizations in modern AI systems long before most teams realized it. Early prototypes of Retrieval-Augmented Generation (RAG) pipelines, AI copilots, and semantic search platforms often performed perfectly on small datasets and with limited traffic. 

But as soon as real production workloads arrived, tail latency, compounding infrastructure costs, and repeated retrieval operations started becoming impossible to ignore.

Our first instinct was that it was an easy fix. Redis would solve this effortlessly.

It was fast, simple, tested, and already trusted in high-scale systems for session storage, API caching, and rate limiting. Exact-match prompt caching dramatically reduced response times, allowing many repeated AI requests to be served in milliseconds without touching the expensive retrieval or inference layers again. For a while, Redis proved us right and solved almost every performance problem we had.

Until our workloads changed.

Traditional string-matching caches break down the moment your infrastructure becomes semantic. Human language variation means two users will ask for the exact same information using completely different wording. 

“Traditional string-matching caches break down the moment your infrastructure becomes semantic.”

Because Redis relies on exact string matches, it misses those connections entirely, creating duplicate, fragmented cache entries for identical intents. Before long, our hit rates tanked, memory utilization spiked, and we were stuck with a massive cloud bill for storing redundant data contexts.

That was when semantic caching via vector databases started to look attractive. On paper, it seemed like the perfect architectural evolution: match queries based on vector-distance math so that varied prompts could reuse old embeddings, context chunks, or past LLM answers.

Of course, production reality was far messier than the hype suggested. Vector database caching introduced its own set of problems: latency spikes, false-positive matches, embedding drift, operational complexity, and difficult tuning decisions around similarity thresholds. In some workloads, semantic caching significantly improved performance. In others, it became slower and more expensive than the Redis setup it was supposed to replace.

“Of course, production reality was far messier than the hype suggested.”

What we eventually learned is that Redis and vector databases solve fundamentally different caching problems. One optimizes exact retrieval speed. The other optimizes semantic reuse. Treating them as interchangeable technologies led to architectural mistakes that only became apparent under real production traffic.

The AI architecture we started with

Before the caching problems started appearing, our AI stack looked fairly standard for a modern Retrieval-Augmented Generation (RAG) system. The pipeline was designed around three major stages: embedding generation, document retrieval, and LLM inference.

A user query first entered the API layer, where preprocessing handled normalization, authentication, rate limiting, and conversation context assembly. Once the request was validated, the query was converted into an embedding vector using an embedding model. That vector was then used to retrieve semantically relevant chunks from a vector database before the final context was passed into the language model for response generation.

The simplified request flow looked like this:

  • User sends a query
  • Query is embedded into a vector
  • Vector search retrieves relevant documents
  • Retrieved context is assembled into a prompt
  • LLM generates the final response
  • Response is optionally cached

On a small scale, this worked perfectly. The real headaches started when traffic scaled and we noticed the exact same database queries and heavy inference workloads hitting us thousands of times an hour.

One of the first optimizations we introduced was Redis-based caching

The initial idea was straightforward: avoid recomputing expensive operations for repeated requests. We started by caching exact prompt-response pairs, embedding results, and frequently accessed retrieval outputs. 

Because Redis operates entirely in memory, lookup times were rapid, immediately reducing pressure on both the vector database and the LLM layer.

A simplified Redis caching flow looked like this:

const cacheKey = `llm_cache:${hash(userQuery)}`;

try {
const cachedResponse = await redis.get(cacheKey);
if (cachedResponse) {
return JSON.parse(cachedResponse);
}
} catch (cacheError) {
console.warn("Cache read failed, falling back to LLM:", cacheError);
}

const embedding = await generateEmbedding(userQuery);
const documents = await vectorSearch(embedding);
const response = await generateLLMResponse(documents);

try {
await redis.set(cacheKey, JSON.stringify(response), "EX", 3600);
} catch (cacheError) {
console.error("Failed to write response to cache:", cacheError);
}

return response;

The immediate results were excellent: near-instant response times for duplicate prompts, reduced API costs, and stable infrastructure that handled high traffic without requiring aggressive LLM scale-out. If a query matched an existing keyword-for-word, we skipped the entire expensive AI pipeline and served the answer straight from memory.

Why Redis looked like the perfect solution

Unlike vector indexes, Redis gave us clean, predictable metrics for memory usage, throughput, and latency characteristics under load. There were no similarity thresholds to configure, no ANN indexes to optimize, and no recall-versus-latency trade-offs to worry about. A cache key either existed or it didn’t. That predictability made the system easier to reason about during incidents and easier to scale under pressure.

We initially used Redis across multiple layers of the AI pipeline, including prompt-response caching, embedding caching, session state storage, rate limiting, temporary conversation memory, and caching frequently accessed retrieval outputs.

const cacheKey = `prompt:${hash(query)}`;
try {
const cached = await redis.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
} catch (cacheError) {
console.warn("Cache read or parse failed, bypassing cache:", cacheError);
}

We also started caching embeddings because generating embeddings became surprisingly expensive at scale. Even though embeddings were much cheaper than LLM inference, generating them repeatedly for popular queries still consumed a noticeable amount of compute resources.

const embeddingKey = `embedding:${hash(query)}`;
let embedding;

try {
const cachedEmbedding = await redis.get(embeddingKey);
if (cachedEmbedding) {
embedding = JSON.parse(cachedEmbedding);
}
} catch (cacheError) {
console.warn("Redis read failed, proceeding to generate new embedding:", cacheError);
}

if (!embedding) {
embedding = await createEmbedding(query);

try {
await redis.set(
embeddingKey,
JSON.stringify(embedding),
"EX",
86400
);
} catch (cacheError) {
console.error("Failed to write embedding to Redis:", cacheError);
}
}

As an added bonus, scaling horizontally with Redis clusters is a familiar process for most infrastructure teams. For a while, Redis significantly reduced both latency and infrastructure costs. Cache hit rates were high, GPU workloads dropped, and the vector database handled far fewer retrieval requests.

The architecture looked efficient enough that we initially believed Redis alone would resolve most of our AI caching challenges. That belief did not survive real semantic workloads for very long.

The problem was that AI workloads rarely behave like traditional web workloads for long. Users almost never ask the same question repeatedly. Instead, they ask semantically similar questions with slightly different wording, tone, or context. From Redis’ perspective, these were entirely different cache keys, even when the retrieval results and final answers were nearly identical. That limitation eventually pushed us toward semantic caching using vector databases.

Why we moved toward vector DB caching

Unlike Redis, vector databases do not rely on exact string matching. Instead, they compare numerical embeddings that represent the semantic meaning of text. This made it possible to retrieve cached results for prompts that were semantically similar, even when the wording was completely different.

Instead of hashing the raw prompt into a Redis key, we would generate an embedding for the incoming query and search for previously cached embeddings that were semantically close enough to reuse. If a sufficiently similar match existed, the system could skip large parts of the retrieval or inference pipeline.

The caching flow looked like this:

const embeddingKey = `embedding:${hash(query.toLowerCase().trim())}`;
const cachedString = await redis.get(embeddingKey);
let embedding;

if (cachedString) {
// Parse the stored string back into a workable array
embedding = JSON.parse(cachedString);
} else {
embedding = await createEmbedding(query);
await redis.set(
embeddingKey,
JSON.stringify(embedding),
"EX",
86400
);
}

This approach immediately solved one of Redis’ biggest weaknesses: wording variation. Queries that previously produced separate Redis entries could now reuse cached retrievals or responses if their embeddings were sufficiently close in vector space. This meant significantly higher cache hit rates for real conversational workloads.

The payoff from semantic caching was immediate, especially for conversational traffic where users ask the same question ten different ways. A string-matching setup like Redis misses completely if a user changes a single word. With a vector database, prompts like “How can I speed up vector search?” and “Best ways to optimize semantic retrieval performance?” resolve to the same underlying intent, allowing us to recycle the same cached response, context chunks, or embeddings seamlessly.

We also saw potential cost reductions beyond response caching alone. Embedding reuse became more effective because semantically similar prompts often generated nearly identical retrieval behavior. Retrieval outputs themselves could also be reused across related queries, reducing load on the vector search layer and decreasing the number of repeated context assembly operations.

Semantic caching appeared especially promising for RAG systems, AI copilots, internal knowledge assistants, search-heavy AI applications, and conversational agents with repeated intent patterns because these workloads frequently involve semantically similar queries that can benefit from intelligent cache reuse.

At first, the results were promising. Semantic caching immediately optimized our hit rates and reduced redundant retrieval calls across varied prompts. However, scaling this layout under full production traffic quickly exposed a brand new category of latency and performance constraints.

Where vector DBs started breaking

The advantages of semantic caching were real, but so were the new problems it introduced. As traffic increased and vector indexes grew larger, the system began to develop issues that were harder to predict and debug than the Redis problems we had dealt with earlier.

The first major issue was latency instability. Unlike Redis, which provided highly predictable exact-match lookups, vector similarity search performance degraded unpredictably under load, query complexity, metadata filters, and concurrency levels. Under heavy workloads, some semantic cache lookups became significantly slower than expected, especially when the system searched across millions of embeddings.

A typical semantic lookup now involves multiple operations:

  • Generating an embedding
  • Running ANN similarity search
  • Evaluating similarity thresholds
  • Retrieving metadata and cached responses

Even before LLM inference occurred, the cache layer itself was becoming computationally expensive.

False-positive matches also became a serious problem. Two prompts could appear semantically similar in vector space yet require very different responses in practice. This occasionally caused cached responses to be reused in contexts where they were only partially relevant or subtly incorrect. For context, a query about optimizing vector search for low-latency chat applications might accidentally reuse cached retrievals intended for large-scale offline analytics systems simply because the embeddings appeared highly similar.

The hardest part was tuning similarity thresholds correctly.

const SIMILARITY_THRESHOLD = parseFloat(process.env.CACHE_SIMILARITY_THRESHOLD || "0.93");
const cacheKey = `llm_cache:${hash(userQuery)}`;

try {
const cachedResponse = await redis.get(cacheKey);
if (cachedResponse) {
return JSON.parse(cachedResponse);
}
} catch (cacheError) {
console.warn("Cache read failed, falling back to semantic search:", cacheError);
}

const embedding = await createEmbedding(userQuery);

const result = await vectorIndex.query({
vector: embedding,
topK: 3,
});

if (result.matches && result.matches.length > 0) {
const bestMatch = result.matches[0];

if (bestMatch.score >= SIMILARITY_THRESHOLD) {
return bestMatch.metadata?.cachedResponse ?? bestMatch.cachedResponse;
}
}

const response = await generateLLMResponse(result.matches);

try {
await redis.set(cacheKey, JSON.stringify(response), "EX", 3600);
} catch (cacheError) {
console.error("Failed to write response to cache:", cacheError);
}

return response;

Another benefit was the reduction of repeated embedding and retrieval workloads. Since semantically related prompts often produced highly similar retrieval patterns, the infrastructure handled fewer redundant searches overall. This became especially valuable under high concurrency, where reducing repeated vector searches significantly lowered infrastructure load.

Semantic caching also improved the user experience in some scenarios. Similar prompts tended to receive more consistent responses because they reused previously validated retrieval contexts rather than generating entirely fresh retrieval paths every time.

For a while, vector database caching looked like the clear evolution of AI caching systems. The architecture appeared smarter, more adaptive, and better aligned with how humans naturally communicate.

But the more we pushed into production, the more we started discovering the hidden costs of semantic similarity itself. Finding a stable similarity threshold proved incredibly fragile. Low thresholds maximized cache hits at the expense of precision, while tight thresholds neutralized false positives but destroyed cache utility. This sensitivity turned threshold management into a major operational bottleneck, directly impacting downstream inference costs and system accuracy.

if (match.score >= 0.90) {
return match.cachedResponse;
}

Embedding drift introduced another long-term challenge. As embedding models changed over time, older cached vectors gradually became less compatible with newer embeddings. Semantic relationships shifted, reducing retrieval accuracy and forcing expensive re-indexing operations across the cache layer.

Operational complexity also increased substantially compared to Redis. Maintaining vector indexes required tuning ANN algorithms, balancing shards, handling index rebuilds, and monitoring recall accuracy as workloads changed. The infrastructure became harder to reason about because semantic correctness was no longer deterministic.

We also discovered that semantic caching consumed resources differently than traditional caching systems. Even cache hits still required embedding generation and vector search operations before matches could be identified. Unlike Redis, where a successful lookup was nearly free, semantic cache hits still carried noticeable computational overhead.

In production, the system began to reveal an uncomfortable reality. Semantic caching solved the exact-match problem, but it introduced an entirely new category of latency, accuracy, and operational challenges that traditional caching systems rarely encounter.

Redis vs Vector DB: The real production trade-offs

Once both systems had been running in production long enough, the comparison between Redis and vector database caching became much clearer. Neither technology was universally better. Each one is optimized for a completely different type of workload, and the real trade-offs only become visible under large-scale AI traffic.

Redis dominated in raw speed and predictability. Exact-match lookups were extremely fast, operationally simple, and relatively easy to scale. If a query had already been seen before in the exact same form, Redis almost always delivered the lowest possible latency. Cache hits are often completed in milliseconds with minimal computational overhead.

Operationally, Redis was also easier to maintain. Debugging cache misses was straightforward because the behavior was deterministic. A cache key either existed or it did not. Infrastructure teams already understood replication, sharding, persistence, and monitoring strategies because Redis has been battle-tested for years across traditional distributed systems.

Its weakness was semantic rigidity. Humans don’t write identical strings. If someone adds a typo or changes a single word, Redis drops the ball and treats it as a brand-new cache entry. Vector databases fixed that exact-match rigidity by letting us cache responses based on meaning. On paper, it’s a dream for RAG pipelines and copilots. In production, though, you realize you’re just paying a different tax. Vector lookups have actual computational weight. Unlike Redis, where an O(1) RAM read takes single-digit milliseconds, checking a semantic cache means you’re stuck waiting on an embedding model call and a graph traversal step just to see if you have a match.

“Unlike Redis, where an O(1) RAM read takes single-digit milliseconds, checking a semantic cache means you’re stuck waiting on an embedding model call and a graph traversal step.”

Worse, you lose determinism. With Redis, a key is either there or it isn’t. A vector cache forces you to manage a fuzzy threshold where the system occasionally treats two completely distinct user intents as “similar enough,” blindly serving bad data. Our infrastructure bill transformed too: we went from a system that was heavily memory-bound on RAM to one that aggressively chewed through compute just to optimize and search indexes.

The hybrid architecture that finally worked

After months of experimenting with both systems independently, we eventually stopped trying to choose between them and began using Redis and vector databases as complementary layers rather than competing technologies.

The final architecture used a multi-layer caching strategy. Redis handled ultra-fast exact-match caching for highly repetitive requests, session state, temporary conversation memory, and hot-path retrievals. The vector database handled semantic reuse for prompts that were conceptually similar but not textually identical.

The request flow became layered. The system first checked Redis for an exact-match cache hit, and if that failed, it moved on to a semantic vector cache lookup. If the semantic lookup also missed, the request proceeded through the full pipeline of retrieval and inference, after which the resulting output was stored back into both cache layers where appropriate.

A simplified hybrid flow looked like this:

try {
const exactCached = await redis.get(cacheKey);
if (exactCached) {
return JSON.parse(exactCached);
}
} catch (cacheError) {
console.warn("Redis read failed, proceeding to semantic search:", cacheError);
}

const embedding = await createEmbedding(query);
const semanticMatch = await vectorIndex.query({
vector: embedding,
topK: 1,
});
const SIMILARITY_THRESHOLD = parseFloat(process.env.SEMANTIC_CACHE_THRESHOLD || "0.93");

const bestMatch = semanticMatch.matches[0];

if (bestMatch?.score >= SIMILARITY_THRESHOLD) {
  return bestMatch.metadata?.response;
}


const response = await generateLLMResponse(query);
try {
await redis.set(cacheKey, JSON.stringify(response), "EX", 3600);
} catch (cacheError) {
console.error("Failed to write exact match to Redis:", cacheError);
}
await vectorIndex.upsert([
{
id: crypto.randomUUID(), // Most vector DBs require a unique ID
vector: embedding,
metadata: {
response,
},
},
]);
} catch (vectorError) {
console.error("Failed to upsert semantic cache to vector index:", vectorError);
}
return response;

This hybrid approach solved several problems simultaneously. Redis continued to handle the lowest-latency exact cache hits, protecting the infrastructure during traffic spikes and repetitive workloads. The vector cache improved semantic reuse without forcing every request through expensive ANN searches unnecessarily.

The layered design also improved reliability. Even if vector search latency increased temporarily, Redis still absorbed a large share of repeated traffic. Likewise, if exact-match cache hit rates dropped, semantic caching still recovered some of the lost reuse efficiency.

The architecture became easier to optimize because each layer had a clearly defined responsibility: Redis optimized speed, the vector database optimized semantic understanding, and the inference layer handled only true cache misses.

Over time, we also became more selective about what entered the semantic cache. Not every response benefited from semantic reuse, especially highly dynamic or context-sensitive outputs. Restricting semantic caching to stable retrieval patterns improved both precision and infrastructure efficiency.

Production lessons we learned

The biggest lesson was that AI caching behaves fundamentally differently from traditional application caching. Human language introduces semantic variation that exact-match systems struggle with, but semantic systems introduce probabilistic complexity that exact-match systems avoid.

In production, we learned that Redis and vector databases are not competing solutions but tools optimized for different layers of AI caching. Redis excels at fast, deterministic exact-match retrievals, while vector databases are better suited for semantic reuse in variable, intent-driven workloads. The most stable systems are not built on choosing one over the other, but on combining both in a layered architecture that matches the nature of AI traffic.

Ultimately, there is no “best” caching system for AI workloads. Redis and vector databases solve fundamentally different problems, and treating them as interchangeable leads to architectural inefficiencies at scale. 

Redis delivers speed and predictability for exact-match scenarios, while vector DB caching enables semantic reuse where user intent matters more than exact wording. In real production systems, the most reliable approach is not replacement but combination.

The post Why smarter AI caching sometimes makes everything slower appeared first on The New Stack.

Meta and the rise of the accidental cloud

Close-up of server rack hard drive bays with yellow locking handles

In the same quarter, a $1.7 trillion social network and a shoe company both became cloud providers. Nobody’s operating model was designed for this.

On July 1, Bloomberg reported that Meta was building a cloud business to sell its excess AI capacity, signaling that one of the largest GPU fleets on Earth is about to get a price list.

As the report outlines, the company is still weighing two business models that are part of its Meta Compute initiative: it could offer hosted access to AI models running on Meta infrastructure (similar to AWS Bedrock), or directly rent raw compute capacity, à la the CoreWeave model.

Two weeks before that report, Allbirds had finished becoming Smartbird. The erstwhile sneaker company — which hit its peak in 2022 in selling 3 million pairs — sold its footwear brand for $39 million, lined up a convertible note facility that it later expanded to $100 million, hired an ex-AWS executive as CEO, and set out to sell GPU-as-a-Service. 

When it first announced the pivot in April, the stock spiked nearly 600% in a day, adding more than $100 million in market value at its peak — all before the company had racked a single GPU.

One of these is a serious supplier, and the other is a public shell chasing an AI multiple, but I don’t think the distinction matters much. Compute supply is fragmenting faster than any enterprise can absorb it, and overbuild always finds a buyer.

Overbuild becomes inventory

Meta isn’t selling compute because its leaders woke up wanting to fight AWS. It’s selling compute because it provisioned for its own peak, and there’s a gap between what it built and what it uses. That’s what an accidental cloud is: Infrastructure that was never meant to be a product, monetized because the alternative is depreciation.

That’s what an accidental cloud is: Infrastructure that was never meant to be a product, monetized because the alternative is depreciation.

Meta won’t be the last. Everyone who bought more GPUs than they needed in the last three years is facing the same math. Some will eat the write-down. The rest will sell. Stack that on top of the neoclouds (CoreWeave, Nebius, Lambda), the sovereign clouds, and now the Smartbirds, and the list of places you can buy serious compute has gone from a handful to many in about two years. 

The market read the Meta news as bad for neoclouds. CoreWeave and Nebius both dropped double digits on the day, and I get why: Nebius has a $27 billion contract with Meta and CoreWeave a $21 billion deal. Both had Meta as a customer and later witnessed it become a competitor in the compute business. But I’d pull a different lesson from it. It’s not that one supplier wins and another loses. It’s that supplier positions are now unstable everywhere. 

If the suppliers can’t predict their position two years out, betting your operating model on any one of them is a risk you’re not pricing.

More suppliers should mean leverage. Mostly it means sprawl.

On paper, a fragmenting supply side is great for buyers: price competition, more choice, more leverage. Cheaper compute is coming, and for AI workloads, it’s coming fast.

Most teams I talk to can’t capture any of it. Every new supplier shows up with its own console, its own billing format, its own identity model, and its own hole in your governance coverage. Signing a supplier is cheap. Operating one is not. The security review, the tagging standards, the budget enforcement, the offboarding plan — all of it gets rebuilt per provider. Choice without governance isn’t leverage. It’s sprawl, and sprawl costs more than the discount that created it.

Choice without governance isn’t leverage. It’s sprawl, and sprawl costs more than the discount that created it.

This bites hardest with GPU capacity, because that’s where the fragmentation is happening and where the money is. Workloads end up pinned to whichever supplier had chips available the day the contract was signed, and they stay there. Not because moving is impossible, but because nothing above the suppliers makes moving routine, and the team that signed the contract usually isn’t the team on the hook for utilization. Those incentives don’t fix themselves.

The Smartbird end of the market makes this non-optional. Capacity from a vendor with no enterprise track record is only usable if you can exit it in a day. That’s something you design for up front, not something you negotiate into a contract.

The durable position is above the suppliers

Every argument about picking the right cloud assumes the list of clouds is stable. It isn’t, and it’s about to get less stable. The position that survives supplier churn is the layer above them: a single control plane where every provider — hyperscaler, neocloud, or accidental cloud — is just a target you provision to, under the same policies, approvals, cost visibility, and exit path.

This is the VMware argument, extended forward. Broadcom taught the industry what single-supplier dependence costs when the supplier’s incentives change. Meta just taught the follow-up lesson. The future holds more clouds, not fewer, arriving faster and from stranger directions than anyone planned for.

The enterprises that win the price war won’t be the ones that picked the right supplier. They’ll be the ones for whom the supplier stopped mattering.

The practical version of this is an abstraction layer that treats every supplier as a provisioning target rather than a separate operating model. When a new supplier appears — Meta Compute, or a neocloud that didn’t exist last quarter — it plugs into the governance the team already defined, rather than becoming a new operating model to build from scratch. The policies get written once; the supplier list underneath can churn.

Meta selling compute and a sneaker company selling GPUs are the same headline: supply is no longer scarce; it’s fragmented. The enterprises that win the price war won’t be the ones that picked the right supplier. They’ll be the ones for whom the supplier stopped mattering.

The post Meta and the rise of the accidental cloud appeared first on The New Stack.

“The database is the product”: What breaks when memory devices scale

Abstract 3D digital render of dark, monolithic towers textured with microchip patterns, symbolizing complex database architecture and infrastructure scale.

Imagine you just finished a two-hour meeting. You were wearing a small AI work companion that promised to capture the conversation, structure it, and let you ask questions about it later. Two hours after the meeting, you open the app and ask for the transcript. You wait. The spinner turns. The whole reason you bought the device was so you’d never have to remember a meeting again, and now the one thing it promised to do well — recall what was said — is the thing that’s making you wait.

This is the failure mode that fascinates me about AI hardware products, because it’s not a model problem. The transcription was perfect. The summarization was good. The thing that frayed was the part nobody markets: getting the right bytes off disk and onto the screen at the moment the user asks. That’s a data problem. And for a product whose entire promise is memory, a data problem is a product problem. 

“For a product whose entire promise is memory, a data problem is a product problem.”

I want to walk through a real version of this because the team that hit it, Plaud, makes the most popular AI notetaker on the market, and the architecture that broke is the architecture almost every team in this category starts with. It feels reasonable at launch. It becomes a liability at scale. And the reasons why are worth understanding before you ship, not after.

First, what was built correctly

It would be easy to tell this story as “they made a mistake.” They didn’t. The original architecture was a sensible set of decisions, and I want to be precise about that before I dissect what went wrong, because the lesson is in the gap between “reasonable” and “right at scale,” not in anyone’s competence.

Plaud’s product generates two very different kinds of data per recording. There’s structured metadata: who recorded it, when, how long, what tags, what state the processing pipeline is in. And there’s the unstructured payload: the audio file and its transcript, which can run tens of megabytes per session. The team did the textbook thing. They put the structured metadata in MySQL, where relational queries and transactions are cheap, and they put the large objects in S3, where storage is cheap and effectively infinite.

If you’ve built systems, you’ve made this exact call. Object storage for blobs, a relational database for everything you need to query. It’s in every architecture diagram. It’s the default. And for a long stretch of the product’s life, it worked fine.

The problem is not that the decision was wrong. The problem is that it contained a hidden assumption: that the metadata and the content could live in separate systems because they would never need to be consistent with each other in real time. For most applications, that assumption holds. For a product whose core interaction is “give me back exactly what I recorded, right now,” it doesn’t. And the gap between those two worlds is where everything started to fail.

The transcript sidecar

In my article on RAG retrieval, I identified an anti-pattern I called the vector sidecar: the habit of standing up a separate vector database alongside your primary store, only to discover that the two systems can’t answer a single query together. The Plaud architecture is the same shape, applied to an AI hardware product. Call it the transcript sidecar.

The transcript sidecar is what you get whenever you split structured metadata from unstructured content across two systems with no shared transaction guarantee. The metadata says a recording exists, is complete, and is ready. The content lives elsewhere, reached via a separate call, with its own latency and failure modes. Nothing ties the two together. There is no transaction boundary that spans “the row that says this transcript is ready” and “the object that contains the transcript.”

This produces three distinct compounding problems.

  • Retrieval latency is not a network problem; it’s a data locality problem. S3 is excellent object storage. It is not a database. When you make object storage the primary retrieval path for tens-of-megabytes payloads under concurrent load, you’re trading the consistency and latency guarantees of a database for the simplicity of a blob store. Under light load, the trade is invisible. Under heavy concurrent load, S3 retrieval latency and its variability become the user’s experience of your product.
  • Consistency gaps open between two systems that fail independently. The MySQL row can indicate that a recording is ready a moment before the S3 object is durably reachable, or a replica can lag, causing the metadata a user sees and the content they fetch to disagree. With no shared transaction, the application layer inherits the job of papering over the gap, with retries, polling, and reconciliation logic that grows more elaborate every quarter.
  • The schema becomes immovable at exactly the wrong time. More on this below, but the short version is that the metadata store hit a scale ceiling where changing the schema required a maintenance window. For a product still evolving its feature set, that’s a database governing the roadmap, rather than the other way around.

The unifying insight is the one I keep coming back to throughout this whole series: any time you split data across systems that can fail independently, you have handed the consistency problem to the application layer, where it is not solved so much as managed, and where it compounds over time.

When the database governs the roadmap

The most interesting failure in the Plaud story isn’t the latency. It’s the schema freeze, because it’s the one that teams least expect and feel most acutely.

With around 300 million rows, the team’s MySQL setup reached a point where schema changes such as adding a column or changing an index — the routine evolution of any growing product — could no longer be performed online without risk. DDL operations on a table that large, on that architecture, meant locking, replication strain, and the real possibility of downtime. So changes had to be batched into maintenance windows.

Sit with what that means. A maintenance window for a schema change is the time the database allows the product team to ship. The roadmap now bends around the database’s limitations. A feature that needs a new column will wait until the next window. The product’s cadence is set by the operational fragility of the data layer. Most teams don’t notice this inversion because it happens gradually, and then one day a product manager asks why a small change is a two-week project, and the answer is “the database.”

“A maintenance window for a schema change is the time the database allows the product team to ship. The roadmap now bends around the database’s limitations.”

The 300-million-row ceiling is a forcing function that teams hit later than they expect and should hit later than they do. Expect, because single-instance MySQL feels limitless right up until it doesn’t. Should, because the architecture that gets you to 300 million rows is rarely the architecture that takes you past it, and the migration is far more disruptive at 300 million rows than it would have been at 30 million. The ceiling is real; it is predictable, and most teams plan for it only after they’ve hit it.

What changing the architecture actually fixed

Plaud’s resolution was to consolidate the metadata layer into a distributed SQL database (they moved to TiDB), which removed the single-instance ceiling and restored online schema changes. I’m going to use their numbers, but not as a product pitch. I want them as evidence for a claim about where architectural debt goes in a product like this.

Before (dual-store-brain at scale)After (consolidated metadata layer)
Throughput strained under concurrent load~10x QPS headroom
Tail latency variable under loadP95 under 10 ms
Schema changes require maintenance windowsOnline DDL, no downtime
Single-instance ceiling at hundreds of millions of rowsHorizontal scale across multiple clusters
Figures per Plaud’s reported migration results.

QPS headroom and tail latency matter, but the first result I’d point to is the online DDL. Restoring the ability to change the schema without a maintenance window is what handed the roadmap back to the product team. The database stopped governing the release cadence. That’s not a performance win you can put on a benchmark chart, but it’s the one the product organization feels every week.

Also notice what the fix did not do: it did not attempt to store 30-megabyte audio files in the database. Large objects can still be stored in object storage. The point was never “put everything in one system for its own sake.” The point was that the metadata layer, the part that has to be consistent, queryable, and evolvable in real time, needed to actually behave like a database at scale, instead of becoming the fragile half of a split-brain architecture.

Where architectural debt goes

Here’s the claim the Plaud numbers are evidence for. When the database is the product, architectural debt does not accumulate in some back-office system that only the platform team feels. It accumulates in the product experience, where every user feels it.

This is the structural difference between an AI note-taker and, say, an internal analytics tool. For a product like this, every meaningful user interaction is a database operation. Recording creates rows and objects. Transcription updates state. Retrieval is a read. Editing is a write. Search is a query. There is no part of the product that isn’t, underneath, the database doing something. Architectural problems surface as product problems, one-for-one. A consistency gap becomes a transcript that is briefly missing. Slow retrieval reads as a product that is slow to remember. A frozen schema means features arrive late.

No user will ever file a bug report that says “your metadata store and your object store lack a shared transaction boundary.” Left unaddressed, this class of debt manifests as a product that feels less dependable precisely when someone depends on it. For a product whose entire value proposition is “trust me to remember,” the debt lands on the promise itself. This is why Plaud’s decision to re-architect when it did matter. The team fixed the data layer before the failure became noticeable to users.

“You can have the best transcription model in the category and still ship a product that feels unreliable, because reliability for this kind of product is a data architecture property, not a model property.”

This is why I say the database is the product. Not as a slogan. As a literal description of where the product’s quality is determined. You can have the best transcription model in the category and still ship a product that feels unreliable, because reliability for this kind of product is a data architecture property, not a model property.

The trap is waiting for the whole category

AI hardware is having a moment. Note-takers, wearables, ambient recorders, pendants, badges — each built on the premise that the device will remember so you don’t have to. The category is growing, and the products are getting better at the parts everyone talks about: the models, the form factor, the battery life.

But underneath, almost all of them start with the same architecture Plaud started with, because it’s the reasonable default. Structured metadata in a single-instance relational database. Large content in object storage. No shared transaction boundary. A schema that’s easy to change at ten million rows and frozen at three hundred million. The trap is identical, and it’s waiting at the same place on the growth curve for every team in the category.

The teams that will do well are the ones that recognize this early, understand that, for a memory product, the metadata layer is not back-office plumbing but the spine of the user experience, and plan their data architecture for the scale they’re trying to reach rather than the scale they’re at. Plaud’s migration is the pattern worth studying before you hit 300 million rows, not after. The lesson is cheaper to learn from someone else’s 300 million rows than from your own.

When your database and your product are the same thing, you don’t get to treat the database as someone else’s problem. It is the product. Build it like one.

The post “The database is the product”: What breaks when memory devices scale appeared first on The New Stack.

The impressive AI demo is dead. Here’s what actually reaches production

Abstract digital render of vibrant blue and purple neon light trails curving upward against a dark background, representing real-time data streaming pipelines for AI infrastructure.

Most engineering teams I talk to can ship an AI demo. The prototype works, stakeholders are impressed, and everyone agrees the use case has potential. Then the project hits a wall.

The reasons for this can vary, but new research shows that difficulties in collecting and parsing real-time data from multiple sources are often the problem. And it’s compounded by a growing skills shortage.

“Only 32% of organizations report having agentic AI running in production.”

According to Confluent’s 2026 Data Streaming Report, only 32% of organizations report having agentic AI running in production. At the same time, two-thirds of respondents cited data infrastructure and data quality as barriers to the success of agentic AI. The models work in controlled conditions, but production is a different story.

Why the demo-to-production gap is so wide

Demos tend to work because everything around them is controlled. The data is static and curated carefully to support exactly what the model will be asked to do. Production environments don’t always offer those luxuries.

In production, AI systems have to query data that lives across dozens of sources, including databases, event streams, application logs, and third-party feeds. Much of that data is poorly governed, and little of it is designed to be consumed by an AI agent in real time. Models that looked impressive in pilots return unreliable results because they’re working with stale, incomplete, or uncontextualized data.

The instinct is to tune the model, but the problem is more likely to be the data feeding it.

In the report, 72% of IT leaders cited insufficient infrastructure for real-time data processing as a barrier to scaling AI, up from 61% the year before. That increase suggests the problem isn’t going away; it’s getting more visible as teams move projects into production.

“The instinct is to tune the model, but the problem is more likely to be the data feeding it.”

AI systems need data that’s trustworthy, contextualized, and current, and those properties are hard to guarantee when data is sitting in siloes that weren’t built for continuous consumption. Batch pipelines almost always introduce latency, lack formal data contracts, and obfuscate lineage. The AI system ends up working with an inconsistent, partial snapshot of the business instead of what’s actually happening now.

The skills problem makes this harder

The report reveals another challenge: 71% of IT leaders cited a shortage of relevant expertise and skills as a barrier to AI adoption. 

The work of application development has shifted from encoding business logic to creating an information environment where automated systems can learn and generalize.  Building reliable AI applications requires developers to be stronger data engineers. They need to understand distributed systems, streaming architectures, data quality controls, and how to build pipelines that hold up under real-world conditions. They need to reason about data lineage, schema evolution, and what happens when an upstream source changes. And the QA patterns that work for deterministic software — where the same input yields the same output — don’t transfer to probabilistic systems.

Most developers haven’t had to think this way before. The discipline of getting the right data to the right system at the right time, in a governed and reusable way, has gone from a specialist concern to a requirement for anyone building production AI.

This affects how organizations should think about closing the demo-to-production gap. The investment in data engineering skills needs to keep pace with the investment in AI itself.

What production-ready AI actually requires

Organizations that make it out of the pilot stage treat data infrastructure as a first-class concern from the start. That means building real-time pipelines rather than batch processes. It means applying schema definitions, ownership metadata, and quality checks at the point of data production rather than in the data lake. And it means structuring data as reusable products that different teams and applications can build on, so the engineering work supporting one AI application can accelerate the next one, rather than starting from scratch.

The 2026 report found that 88% of IT leaders said data streaming platforms help address data infrastructure and quality issues for agentic AI. That’s because they address the specific reasons AI projects stall — real-time data delivery, upstream governance, and making data trustworthy enough to use at inference time.

The shift is already happening

For the first time, the report found that investments in data streaming outranked those in AI and machine learning, by 88% to 82%. Organizations that have tried to ship production AI are increasingly recognizing that the model isn’t the hardest part. 

“For the first time, the report found that investments in data streaming outranked those in AI and machine learning, by 88% to 82%.”

So if you’re stuck at the pilot stage, resist the urge to keep optimizing the model. A better question is whether the data feeding the model is fresh, accurate, and well-governed, and whether your pipelines were actually built for production AI or a demo that only had to work once.

The post The impressive AI demo is dead. Here’s what actually reaches production appeared first on The New Stack.

Why retrieval quality is becoming the defining challenge in AI agent architecture

Neon digital waves and scattered data particles on a dark background, representing hybrid search, data pipelines, and AI engineering infrastructure.

Agentic systems usually have two jobs: Build context, then use that context to produce an answer or action.

Many failures that look like LLM problems start in the context-building step. The answer the LLM gives is limited by the context it was given, or it finds through tool calls. If the agent model cannot find the right sources, then improving the generation model will not improve the overall system.

“Many failures that look like LLM problems start in the context-building step.”

A client, Specstory, wanted to give users the ability to ask questions from the agent’s history. For example, why a team chose Authlib for authentication and what alternatives they considered. The chatbot needs the right prior conversations, decisions, and tradeoffs from a large corpus of coding sessions. The model and system prompt help only after those chat turns have been retrieved and are in context.

If retrieval ranks implementation snippets above the discussion where the team weighed alternatives, the agent can still produce a confident answer. It may find code that imports Authlib and a few inline comments, then describe the decision based on implementation evidence rather than the actual trade-off discussion.

The same pattern showed up in an AnkiHub operator review in our private community. A request for help studying based on lecture slides only works if the agent’s tool calls retrieve the right flashcards. The hard part is not finding any related cards. A lecture on the function of the heart may match hundreds of cards. Ranking decides whether the core cards make it into context or whether the system has to raise top_k and flood the prompt.

The exact setup changes by product. The context-building step might use local search, semantic search, web or API calls, or database queries. It might be handled by an agent, a fixed workflow, or application code. The process stays the same: gather the right context, then generate from it.

For example, a coding agent runs rg, opens files, reads logs, and inspects tests before writing a patch. A research agent searches the web and internal notes before writing an answer. A study assistant searches deck facts and user context before suggesting what to learn next.

When context building fails, the symptoms look like generation failures.

Retrieval failures mimic generation bugs

SymptomRetrieval cause
HallucinationThe answer source never made it into context.
Context rotLow recall forces a high top_k, so noisy results fill the context window.
LatencyWeak retrieval leads to more tool calls, larger candidate sets, and larger context windows.

A better model helps with reasoning and writing, but it cannot give a better answer without the right context.

“A better model helps with reasoning and writing, but it cannot give a better answer without the right context.”

The Mixedbread OfficeQA-Pro Eval shows the same pattern at the benchmark scale. OfficeQA-Pro uses 89,000 pages of financial documents, dense tables, scanned PDFs, and questions that require reasoning across documents. Giving Codex better search tools reduced tool calls and improved answer quality.

A scatter plot mapping Accuracy (%) against Tool Calls for three AI configurations.

Plain-text tools like grep and rg work (ish) on flat code files. They do not work well when context lives in PDFs, tables, chat histories, multi-modal inputs, web results, and permissioned data. In those cases, the agent needs a retrieval that can combine exact terms, meaning, metadata, permissions, and ranking quality.

Retrieval needs traces and evals

Once retrieval enters the architecture, the next question is whether it finds the right information.

For that, you need traces and evals. For each retrieval step, the minimum trace is the input, the outputs, and a way to label whether each output was relevant.

A flowchart diagram illustrating a data workflow where a horizontal sequence connects four steps: Input, Tool call, Output, and Label.

For a coding agent using rg the input is the command, the output is the returned snippets, and the label says which snippets helped, which were noise, and which relevant files were missing.

For product retrieval, the step might be BM25, semantic search, hybrid search with reranking, a generated SQL query, or something else. Capture the query or arguments, the returned documents or chunks, and whether those results were helpful.

Trace each retrieval step by itself, then evaluate the full context-building pass. The local trace answers “Did this query return useful material?” The full trace answers “Did the system collect everything the model needed before generation?” If it did, failures are a generation problem. If not, it’s a retrieval problem.

You cannot know where the failure started or what to fix without traces.

Different failures need different fixes

“Improve retrieval” is too broad to be useful, as different problems require different solutions. If a relevant document is missing, the trace should show where it disappeared: query building, retrieval, filtering, ranking, or final context assembly.

A sequential flowchart which maps a five-stage pipeline—Query builder, Retriever, Filters, Ranking, and Context—with each stage pointing down to its respective failure mode.

The failed step, plus what the trace shows, tells you what change to make.

Failed stepWhat the trace showsChange to make
rg / grepA conceptual query returns literal matches while missing relevant files.Add semantic search over files or chunks, or generate better keyword queries before calling rg.
BM25The query uses the right concept but different words from the source material.Add semantic search, synonyms, or query expansion.
Semantic searchExact names, error strings, document IDs, or domain terms are missing from the results.Add a keyword or BM25 path, or boost exact term matches.
Hybrid retrievalThe relevant passage is ranked 7th, but the context only takes the top 5.Add or tune a reranker, or raise candidate top_k before reranking.

The right fix depends on what the system was trying to retrieve. A decision-history question requires the decision, the alternatives, and the chats in which the team worked through them. A study question depends on the lecture material, deck metadata, semantic matches, and the user’s study context.

The architecture

Once you trace individual retrieval calls, the full architecture has a simple shape: fan out to context-building tools, then fan in to generate the final output.

A system architecture diagram showing a RAG pipeline.

The retrieval layer might be a search engine, a vector database, an SQL query, a local file tool, a web search API, or a custom service. The pattern stays the same: build candidate context, narrow it, rank it, assemble it, then generate from it.

Give agents human search controls

Semantic search compares embeddings (numerical representations of meaning). It helps when wording differs, but most retrieval intents also depend on structured constraints. A meeting search box can use semantic search over transcripts and notes, but a useful interface also lets someone filter by person, date, project, and source. 

A finance search may need the latest filing, a specific quarter, or an official source in addition to the closest semantic match. In e-commerce, the best semantic match for “32×30 cargo pants” may be an out-of-stock product. The system still has to decide whether to hide it, return it with a backorder note, or show it so the user can check later. That product decision is a retrieval decision because it changes which candidates reach the agent.

In a chat interface, those controls are in the tool schema, query planner, or app logic. If an agent runs the search, it needs arguments for the same constraints a human would set with filters, sliders, tabs, and sort menus.

A retrieval system usually needs several controls working together:

ControlWhat it doesExample
Exact matchMatches names, IDs, error strings, quoted phrases, tickers, or product codes.Find EADDRINUSE, Authlib, or a specific SEC accession number.
Semantic matchFinds related content when the wording differs.Find the meeting where the team discussed authentication tradeoffs.
Hard filtersRemoves invalid results before ranking.Limit by tenant, permissions, person, date range, size, or stock status.
SortsOrders candidates by a structured field.Prefer the newest, latest filing, lowest price, highest rating, or recency.
RankingScores candidates based on their likely usefulness for this request.Combine semantic match, exact match, freshness, source quality, and use.
RerankingUses a slower model or scorer on a smaller candidate set.Compare the query against the top 100 candidates before returning 10.

Here, a chunk means a small piece of source content, and a candidate is a chunk returned by the first search step. Ranking is the scoring step that orders those candidates. Context assembly then selects which chunks and structured fields to include in the model prompt.

Better ranking improves precision, which means a larger share of the returned chunks is useful. If the relevant chunks are near the top, the system can pass fewer chunks to the model, use fewer tokens, reduce latency, and expose the model to less noise. If the right chunk is ranked 40th and the context only includes the top 10, the system behaves as if the retrieval missed it.

People and agents use the same basic search path: ask for results, inspect what comes back, and decide what to use. A person can skim ten search results, compare titles, snippets, dates, domains, and URLs, and decide whether the result set looks right. They can open the third result, ignore the rest, and search again with a better query. An agent usually receives a bounded set of returned documents and reasons from the context. If the right source falls below the cutoff, the agent may answer from partial context. To avoid this, the system has to retrieve more candidates, run more searches, or pass more evidence into the model.

A missed document can change what the agent searches for next. Suppose someone asks why the team chose Authlib. If the first search misses the transcript where the team compared Authlib with alternatives, the agent may search the codebase instead. It finds imports, callback handlers, tests, and maybe a comment. Then it asks follow-up questions about OAuth configuration. The context starts to look complete, but it supports the wrong answer. It explains how Authlib was used and why it makes sense in the codebase, not why the team chose it.

“The context starts to look complete, but it supports the wrong answer.”

But ranking cannot repair every search problem. If the agent failed to request the latest filing, a reranker may faithfully select an older document with a closer wording match. If the tool has no date_range, person, source_type, size, or in_stock argument, the model has to impose hard constraints in the search text and hope that retrieval infers them. A hard filter gives the model less to infer, making semantic search more reliable.

Scale changes the retrieval problem

Search systems already have tools for this: indexes, filters, facets, sorts, caching, bounded reranking, and freshness jobs. Agent systems need the same discipline.

A human might search, adjust a date filter, scan the first page, then search again. One agent request can do that many times in seconds: rewrite the query, run keyword and semantic search, inspect thin results, issue follow-up searches, fetch sources for citations, and ask for more context before answering. With many concurrent users or agents, the retrieval layer can become a bottleneck.

Humans often wait through a slow search if the result is good. Agent systems often turn slow and uncertain search into more work. When ranking is weak, teams compensate by raising top_k, running keyword and semantic searches in parallel, adding reranking, fetching more source documents, and passing larger evidence bundles to the model. That can improve answers, but it moves the cost into tokens, latency, and retrieval load. A better ranking lets the system return fewer, better candidates, rather than making every request carry a larger pile of possible evidence.

With a small corpus, you can still search comprehensively quickly and cheaply, even with fully agentic approaches. That’s what I recommend when you’re starting and don’t have much data. Don’t add complexity until you need it. But with millions or billions of chunks, every extra retrieval call, candidate, ranking pass, and returned token adds up quickly.

Multi-stage retrieval is the production shape

Most production systems should split retrieval into stages, even when the UI is a chat box.

StageWhat happensTrace question
Search argument constructionThe app or agent turns the request and state into a query, filters, and sort.Did it ask for the right content with the right constraints?
Candidate generationThe system finds plausible chunks from text, vectors, or structured data.Did the right source enter the candidate set?
FilteringPermissions and product constraints narrow what can be returned.Was the source correctly excluded or wrongly lost?
SortingStructured fields order results when order matters.Was the latest, cheapest, highest-rated, or current item surfaced?
RankingThe system scores the candidates based on their usefulness for this request.Was the source present but ranked too low?
Summary returnThe system returns only the fields the agent needs.Did the app receive usable evidence and provenance?
Context assemblyThe app selects, formats, and budgets evidence for the model.Did useful evidence get dropped before generation?
EvaluationHumans or automated checks label whether the retrieval path worked.Can the team turn the failure into a specific fix?

Each stage leaves a different repair path. If the agent chose the wrong filters, changing the embedding model will not help. If the latest document was available but the tool never sorted by date, the fix belongs in the search arguments or retrieval API. If the right source was present but below the cutoff, the fix belongs in the ranking. If the right source came back but was dropped before generation, the bug is in context assembly.

As retrieval becomes a core part of agent architecture, teams increasingly need infrastructure that can combine semantic search, exact matching, filtering, ranking, and large-scale retrieval in a single system. Depending on requirements, this may involve search and retrieval platforms such as Vespa, Elastic, or Coveo, each of which supports different approaches to ranking, retrieval, and operational scale. 

The important point is not the specific technology choice, but recognizing that retrieval quality has become a first-class engineering concern. As agent workloads grow, retrieval systems are increasingly determining the accuracy, cost, latency, and reliability of the overall application.

The post Why retrieval quality is becoming the defining challenge in AI agent architecture appeared first on The New Stack.

Operating Kubernetes at scale: a few stories from running Amazon EKS

Abstract 3D render of a futuristic metallic data core with glowing blue and white lights, illustrating the scaling and resilience of a Kubernetes control plane.

Amazon EKS runs hundreds of thousands of Kubernetes clusters across more than thirty AWS regions. Operating at that scale has taught us something that has shaped how we build the service and that we think is useful to anyone running Kubernetes at scale: most availability problems do not stem from a component failing. They come from a component reacting to a problem in a way that makes it worse. A cache that goes stale and serves wrong answers. A health check that restarts the very process keeping a cluster alive.

What separates a resilient control plane from a fragile one is not the number of faults. It is whether a fault stays a fault or becomes an outage. This post is the story of how we keep the EKS-managed Kubernetes control plane on the right side of that line at ever-growing scale: the foundational changes we made and why, and what operating at fleet scale taught us about building systems that tolerate faults rather than spreading them. These are the reasons our most demanding customers confidently run their mission-critical workloads on EKS.

How AI and analytics workloads reshaped what “scale” means

Kubernetes was built for a particular rhythm of work. Pods came and went at predictable rates, and controllers had seconds or minutes to reconcile. The system’s design reflected that pace: strong data consistency, ordered watches, and consensus-replicated storage that puts correctness first. It worked beautifully for what it was designed to do, and it still does.

“What separates a resilient control plane from a fragile one is not the number of faults. It is whether a fault stays a fault or becomes an outage.”

But the workloads evolved faster than anyone anticipated. Foundation model training runs scale-up training jobs on thousands of GPU nodes in minutes. Real-time inference services scale from a warm baseline to thousands of replicas, then drop back within the hour. Apache Spark analytics pipelines burst from zero to tens of thousands of executor pods, chew through a dataset, and vanish. 

Emerging agentic AI workloads add yet another dimension: autonomous agents that spin up, fan out, execute tasks, and tear down in seconds or less. These workloads share a trait that distinguishes them from traditional microservices: they generate enormous volumes of state transitions within compressed time windows and are deeply intolerant of delays. This velocity of state change pushed us to reinvent some of the mechanics to support a scale that was previously impossible, and to contribute what we could upstream.

How EKS reimagined Kubernetes storage foundation

Every Kubernetes cluster depends on etcd as its source of truth. Every application, every service endpoint, every scheduling decision is stored there. If etcd loses data, the cluster forgets everything it knows. Protecting that state is the most important job for a managed Kubernetes service.

Operating etcd for one cluster is well understood. Operating it for a fleet of millions is a different problem entirely. Hardware fails, networks blip, and disks degrade, so something has to handle those events without a human in the loop. And the operations etcd needs most, like replacing a failed member or recovering after a zonal event, are exactly the ones where a person acting under pressure can make a mistake that causes permanent data loss.

From the beginning, we built an operator agent that runs alongside every etcd instance and automates its entire lifecycle. The agent has two jobs. First, backup and recovery: it takes point-in-time snapshots and stores them durably outside the cluster. If too many instances are lost at once and the survivors cannot form a majority, the agent automatically detects the condition and rebuilds from the latest snapshot. Second, membership management: when an instance fails, the agent removes the terminated member and adds its replacement in an order that protects quorum and prevents split-brain.

A recent, more fundamental change was replacing etcd’s consensus mechanism, Raft, with a purpose-built journal that provides durable, ordered storage independently of etcd. In traditional etcd, a majority of members must agree on every write before it is committed. If two of three are unhealthy, the cluster becomes unavailable. 

By offloading durability to the journal, etcd peers no longer negotiate quorum among themselves. Writes commit as soon as the journal acknowledges persistence, and that entire class of etcd quorum-loss failures disappeared. Since the journal handles persistence, etcd no longer needs to fsync writes to local disk, so its data store has moved to an in-memory filesystem. What was a disk-bound system became a compute-bound one, and storage latency was removed entirely from the critical path. For a deeper look at this architecture, read “Under the hood: Amazon EKS ultra scale clusters.”

“What was a disk-bound system became a compute-bound one, and storage latency was removed entirely from the critical path.”

For ultra-scale clusters, we went further and partitioned etcd into resource-specific shards. Each partition operates independently with its own storage budget and throughput capacity. The primary value is failure isolation. In a monolithic deployment, if the events keyspace exceeds its quota because a misbehaving controller creates objects faster than garbage collection can remove them, it blocks writes to everything, including node leases. 

Suddenly, healthy nodes appear unhealthy because their lease renewals are being rejected. With partitioned etcd, the events partition hits its quota, but the leases partition continues operating normally. Nodes remain healthy. The scheduler keeps running.

What replacing etcd’s consensus mechanism unlocked

Removing the quorum requirement allowed us to make a change we had wanted for a long time: running etcd on the same host as the API server. In the traditional layout, every read and write crosses the network between separate machines. Each trip is fast on its own, but at thousands per second, the travel time adds up. With collocation, the API server talks to its local etcd over a loopback interface, and pod scheduling and controller reconciliation get measurably faster. For workloads where job controller queue depth is the binding constraint, shaving milliseconds off each API call means many more jobs are processed per second before the queue starts growing.

Diagram showing the evolution of EKS Kubernetes architecture

This is where the operator agent paid off. When etcd runs on the same host, an etcd member comes and goes whenever a control-plane host is replaced, which happens routinely. That only works if membership management is completely safe and automatic, which is exactly what the agent was already doing. We did not have to build a colocation from scratch; we built it on top of infrastructure that had been managing etcd membership safely since day one.

Collocation also taught us a lesson worth passing on: the convenient path needs a failover in case it breaks. The local etcd is the fast path, but if it becomes impaired, the API server fails over to another etcd member that is actively serving other API servers from the same journal. When you optimize for the common case, design just as deliberately for the moment that optimization is not available.

Fixing bottlenecks across the stack

At extreme scale, you have to address bottlenecks across the entire Kubernetes stack, and most of them are not bugs in the traditional sense. They are design choices that were correct at the scale Kubernetes originally targeted and break down only when the numbers get large. Rather than working around them internally, we fix them upstream so the entire community benefits.

One example involved the watch cache, the in-memory layer that distributes state changes from etcd to every controller watching for updates. When a controller starts, it requests a full snapshot of the current state via a mechanism called WatchList, and the existing implementation holds a shared read lock for the duration of the response build. 

At hundreds of thousands of objects, that work runs long enough to starve the writer that needs exclusive access, so the cache’s resource version cannot advance. Consistent reads see a stale cache and fail over to etcd, while the response building churns through hundreds of thousands of allocations under the lock. We identified this as a limitation in the watch-cache’s locking model and are working with the community to refactor the underlying data structures and interfaces to eliminate the contention.

The same shape appears elsewhere. In the Horizontal Pod Autoscaler, a single mutex protecting the scaling state becomes a serialization point at high HPA counts, where workers spend nearly all their time blocked rather than doing useful work. A redesigned data store (PR #139142) restores parallelism and raises reconciliation throughput by orders of magnitude. In the scheduler, we identified a bottleneck (issue #138426): every scheduling cycle rebuilds a set of in-use persistent volumes by scanning every node in the cluster, even for pods that do not use storage at all. The fix computes that information lazily, and only for pods that actually need it, restoring throughput at scale.

Each of these started from a real production workload hitting a cliff, and we are working on the fixes upstream so the improvements reach every Kubernetes user.

From engineering to guarantees: EKS Provisioned Control Plane

The engineering described above made the EKS control plane more resilient and performant. But customers had a different problem: they could observe that the control plane kept up today, but they could not reserve its capacity the way they reserve compute or GPU capacity. 

A team planning a thousand-node training run could secure the instances weeks in advance, yet had no equivalent mechanism for the orchestration layer that would coordinate them. EKS Provisioned Control Plane fills that gap. It exposes the control plane’s performance as dimensions you size explicitly, backed by the same kind of commitment you expect from the rest of your infrastructure.

You choose a scaling tier that maps to concrete, measurable capabilities: API request concurrency, pod scheduling rate, and cluster database size. The tiers range from XL through 8XL. At the top end, 8XL on Kubernetes 1.34 provides 16,000 concurrent API request seats, 400 pods-per-second scheduling rate, and 16 GB of cluster database storage, all backed by a 99.99% availability SLA measured in one-minute intervals.

Tiers are not static. You step up before a GPU training run or a large sales event, step back down during quiet periods, or grow permanently as your platform matures. Configuration happens through the console, CLI, eksctl, CloudFormation, or Terraform on any cluster, without recreation or downtime. 

For AI workloads, orchestration capacity is planned alongside GPU capacity, available when the compute comes online. For analytics platforms submitting hundreds of jobs per minute, the control plane is ready for the burst before it arrives. And for organizations that need environmental consistency across staging, production, and disaster recovery, the same tier guarantees consistent performance characteristics everywhere.


Taking the same foundation to the edge

Architectural diagram of Amazon EKS on AWS Outposts

Some workloads cannot move to the cloud, whether due to data sovereignty requirements, latency constraints, or unreliable connectivity to the Region. Running Kubernetes in these disconnected environments introduces unique challenges: etcd must remain durable on hardware with only a few machines, the cluster must self-heal without reaching the cloud, and observability must survive network partitions that last days. 

With the updated architecture for EKS local clusters on instance store Outposts, we brought edge clusters onto the same management plane and software stack as EKS clusters in the cloud.

The control plane lives in an EKS-managed account on the Outpost rather than in the customer’s account, so customers never manage control plane instances, etcd backups, or logging agents themselves, and they cannot accidentally break the thing keeping their cluster alive. The same machine images, container images, and operator agent run in both places, with edge-specific behaviors selected by configuration. 

Because it is the same stack, new Kubernetes and EKS platform versions arrive in lockstep with their cloud release, and features like EKS add-ons, Pod Identity, and access entries work the same way they do in a Region.

The hardest part was keeping etcd healthy on hardware with only a few machines that may be cut off from the cloud for days at a time. We solved it by extending the same agent. It keeps a spare copy of the data continuously up to date and promotes it the instant a machine fails, so the cluster heals itself with no human involvement and no connection to the cloud. 

Observability survives the disconnect, too: the metrics agent continues collecting and writing to local disk, shedding the least critical data first when space runs short, so the signals that matter most are the last to go. When the link returns, the buffered data is flushed back with its original timestamps.

All of this only works because the system was designed from the start to operate without anyone logged in. That same design is what makes it possible to deploy changes safely across the entire fleet.

Operating safely at fleet scale

Every one of these changes was deployed to a running fleet of hundreds of thousands of clusters. The journal migration and collocation required transitioning each cluster individually. Every migration follows a strict sequence: validate pre-conditions, create a point-in-time snapshot, perform the switchover, validate post-conditions. If any step fails, the system rolls back automatically. 

Rollouts proceed cell by cell, zone by zone, region by region, with automated monitoring comparing latency, error rates, and throughput between updated and non-updated clusters. Any statistically significant deviation triggers an automatic halt.

What made all of this possible is that EKS is built to operate without human intervention at the individual cluster level. Through Zero Operator Access, the architecture prevents AWS personnel from having technical pathways to access customer content in the managed control plane. A system designed to work without human access must be observable, recoverable, and automatable from the start, and that same discipline is what enables operating at extreme scale.

Three operational lessons shaped how we approach this work.

The first is that a healthy leader is not the same as a working one. The control plane’s controllers run in an active-passive configuration, and early on, we treated an unhealthy standby as if cluster operations had halted. They had not; what matters is whether a leader exists. But the harder lesson: a leader can quietly stop making progress while still renewing its lease and passing every health check. The signal that caught this was watching the controller’s work queue depth. If the queue fills while the leader looks healthy, the system is falling behind in ways no liveness probe will catch.

“A leader can quietly stop making progress while still renewing its lease and passing every health check. The signal that caught this was watching the controller’s work queue depth.”

The second is that maintenance ordering matters as much as the maintenance itself. etcd defragmentation is blocking, and the pause grows with database size. When it hit the leader, every write stalled. We taught the agent to move leadership to a healthy node before defragmenting, so the disruptive work always lands on a follower while writes keep flowing.

The third is that liveness is not readiness. A process can be alive but not ready while it warms caches, and routing based solely on liveness sends requests to an instance that cannot handle them. Equally, readiness flapping during graceful draining should never trigger a restart. We keep the two signals strictly separate: one decides recovery; the other decides routing.

None of this work is visible from the outside, and that is the point. The largest clusters taught us lessons that made every cluster faster. The riskiest migrations produced safety machinery that protects every upgrade. The upstream fixes we contributed for workloads at the edge of what Kubernetes can handle flow back to every user of the project.

“None of this work is visible from the outside, and that is the point.”

When you deploy on EKS and your pods come up in seconds, even during a burst, even when something behind the scenes goes wrong, that speed is not accidental. It is the accumulated result of years of operating at scales where small problems can become big ones fast, and engineering the system to contain them before they do.

To explore the architectures referenced in this post, see EKS Provisioned Control Plane and local Amazon EKS clusters on AWS Outposts.

The post Operating Kubernetes at scale: a few stories from running Amazon EKS appeared first on The New Stack.

The AI agent identity problem nobody’s talking about

Abstract dark blue digital wave background with flowing fine golden lines representing complex data networks and system infrastructure.

Many agentic projects can sail through development just fine. Then they hit security review — and that’s where things can grind to a halt. Unclear identity models and overly broad permissions quickly become blockers.

You’ve probably seen this play out: A customer support agent is working well; it triages tickets and processes refunds, handles the whole workflow without a hitch. Then security asks a simple question: Under whose identity is this running? The answer stops the process cold: It’s a shared account with broad permission, no clear ownership, no audit trail, and no least-privilege controls in sight.

The root issue isn’t complicated. It’s undefined identity and poorly scoped permissions. And that challenge is accelerating fast. Research from the 2026 Tech Leader Study, conducted with Oxford Economics and IBM, shows surveyed enterprises expect to deploy an average of 1,661 AI agents, a 38% increase from today. Each new agent introduces another identity to secure, and without clear boundaries, the problem compounds quickly. 

As a result, many agentic systems focus on what agents can do without defining what they should do, or under whose authority. Agents also don’t hold a fixed set of permissions. They request access, call new tools, and assume roles as they work, so access paths compound in ways no one explicitly granted or reviewed. Without a verifiable identity, there’s no accountability, making least-privilege enforcement, traceability and incident response difficult.

“Each new agent introduces another identity to secure, and without clear boundaries, the problem compounds quickly.”

To address these gaps, this guide is written for developers, architects and DevOps engineers building agentic systems — and for the IT leaders responsible for approving them.

The four identity decisions every agentic system must make

Identity decisions can’t be treated as an afterthought. Identity shapes how agents authenticate, what they can access, and how their actions are controlled and audited over time. Get it wrong early, and you’re building on a shaky foundation.

Here are the four decisions that matter most:

Workload identity vs. shared service accounts 

Shared service accounts are easy, and that’s exactly what makes them dangerous. When multiple agents act under a single identity, it becomes hard to tell what happened or what went wrong after the fact. If an account is leaked or misused, everything it touched is exposed. 

“Shared service accounts are easy, and that’s exactly what makes them dangerous.”

Workload identity assigns each agent its own identity. Permissions stay scoped, and actions are attributable. It requires more setup but creates isolation and auditability.

Static API keys vs. short-lived credentials

Static API keys tend to stick around forever. They get hardcoded into apps, passed around between systems, and rarely rotated — which makes them a persistent vulnerability waiting to be exploited. 

Short-lived credentials work differently. They’re issued on demand, scoped to a specific task, and expire automatically. In practice, this often relies on identity federation (for example, using OIDC tokens) combined with systems that can issue dynamic credentials at runtime, rather than storing long-lived secrets in code or configuration

Direct credential handoff vs. brokered session access

Handing credentials directly to an agent is simple. It’s also opaque. You don’t have a natural point to evaluate policy or understand what’s happening in real time. 

Brokered access introduces a control point into the flow. Requests go through a broker, policies are evaluated in real time, and temporary credentials are issued per session. It adds infrastructure, but restores visibility and policy enforcement. 

Fragmented logging vs. full identity lineage

Most systems log what happened. Far fewer capture who initiated it or how an action propagated through a chain of agents and services. 

Full identity lineage connects every step. You can trace an operation from triggers to outcomes, which can make debugging faster and enable more credible incident response. The catch is that this requires consistent identity propagation and structured logging from the beginning—it’s hard to retrofit.

When these tradeoffs become real risks

These aren’t abstract architectural preferences. They show up as concrete vulnerabilities.  

Nightfall AI reports that organizations expose nearly 350 secrets per 100 employees each year, with 35% of exposed API keys still active. Combine that with persistent credentials and shared identities, and the potential blast radius grows fast

The pattern is consistent: shared accounts and long-lived keys are faster to build but harder to secure. Workload identity and short-lived credentials require more upfront investment but can deliver more security over time.

Debugging breaches by feel

Think about what happens when an agent running on a shared account with a long-lived key suddenly spikes its data access. Was it a bug? A breach? Routine behavior? Hard to say. Revoking the key might stop the issue, but it could also break a half-dozen unrelated workflows in the process. You’re now debugging by feel. 

Shortcuts reduce friction at the start and accumulate risk over time. 

Standardize identity at the platform layer

The answer isn’t to rebuild authentication, authorization and auditing from scratch for every agent you ship. That’s not scalable. 

Instead, standardize identity at the platform layer—centralized identity providers, policy engines and a credential broker to enforce secure defaults and make compliance straightforward rather than a constant negotiation. 

“Shortcuts reduce friction at the start and accumulate risk over time.”

Agentic AI works in production when identity is designed up front and enforced at runtime, rather than assumed from a prior login. When projects are treated as an afterthought, they stall. When it’s built in deliberately, agents can operate with the control that production environments demand. 

IBM supports this through an integrated identity-first approach that spans secrets management, secured access, and identity governance—helping organizations scale agentic systems securely without adding operational complexity. 

Learn how IBM approaches identity-first security for agentic systems

© Copyright IBM Corporation 2026. IBM and the IBM logo are trademarks of IBM Corp., registered in many jurisdictions worldwide. Examples presented are illustrative only. Actual results will vary based on client configurations and conditions; therefore, general expected results cannot be provided.

The post The AI agent identity problem nobody’s talking about appeared first on The New Stack.

Template-based data extraction is dead. Here’s what comes next.

Abstract digital landscape featuring a dark teal 3D wireframe mesh mountain range and pixelated data grid terrain under fine geometric lines.

Modern businesses are in a constant, uphill battle against what to do with unstructured data: PDFs, contracts, scanned images, customer call recordings, meeting videos, and more. Traditional document automation workflows that rely heavily on template-based extraction or rigid rules used to make sense. But document formats have changed; they’re diverse and don’t fit standard formats, making costly, brittle, traditional systems a relic of the past. 

“Modern businesses are in a constant, uphill battle against what to do with unstructured data.”

Enterprises demand faster, more accurate processing, which raises the question: How can we reliably turn messy, multimodal content into structured, actionable insights without a mountain of manual effort?

That’s where Amazon Bedrock Data Automation (BDA) comes in.

What is Amazon Bedrock Data Automation (BDA)?

Amazon Bedrock Data Automation (BDA) is a generative AI-powered, fully managed service on Amazon Web Services for end-to-end document and media automation. It enables users to automate the extraction, classification, and transformation of unstructured content across modalities such as documents, images, audio, and video.

“At its core are Foundation models which enable intelligent extraction and understanding of content.”

At its core are Foundation models (FMs) which enable intelligent extraction and understanding of content. It allows users to configure standard output for common use cases, or even define custom extraction logic using blueprints tailored to your business. BDA is designed for scalability, accuracy, and auditability, making it ideal for enterprise workflows.

Walk-through: creating a project, standard output & custom output using blueprints

1. Create a project via console

In the Amazon Bedrock Console, navigate to Data AutomationCreate Project.

The Data Automation → Create Project interface in Amazon Bedrock.

Enter the name of the project:

The window to create a new BDA project.

2. Standard output:

Standard output gives you the model’s default, unstructured response (text, image, audio, or video) directly from the Data Automation pipeline.

The standard output from the Data Automation pipeline.

In standard output, each modality has its own options for what is needed as an output. 

Document:

The document modality options within the standard output tab.

Image & Video:

Image and video modality options.

Audio:

Audio modality options.

Now let’s test Document Modality for Standard Output:

First, click on “Test” in the upper right corner.

The document processing interface within Data Automation.

Next, select the document from the system, sample, or S3 and choose the modality from the dropdown menu. 

Test document processing interface

Click on the “Generate results” button:

The "generate results" button within the test document processing pane.

After processing, it will show the summary and content of the document:

Post-processing summary of the document, with the "document attributes" tab shown.

Post-processing summary of the document, with the "page level" tab shown.

Post-processing summary of the document, with the "element level" tab shown.

Custom output (blueprints):

Custom output lets you define a structured, predictable format using blueprints, which ensures the output matches your exact schema, fields, and business rules.

Let’s test custom output using blueprints for the same document:

Navigate to “Custom output” and click on “Add Blueprint”:

The custom output tab in the test document processing interface of Amazon Bedrock.

From here, two options will appear. You can either use LLM power to generate the blueprint (where it inspects the document), or you can choose to enter field names, instructions, and other information manually.

The "Create blueprint" pane within the custom output setup.

Below is a blueprint generated by LLM which has pulled all possible fields and tables from the document:

Image showing a blueprint generated by an LLM.

It has extracted the information using the blueprint as demonstrated below, including the  Field name, Instruction, and Results:

A summary table showing all extracted information using the blueprint.

It also provides the Extraction type (which can be Explicit or Inferred), Confidence percentage, and other relevant information.

Image showing the type of each instance of extracted information.

Additionally, it can extract information in the form of a table, such as an account summary or transaction information:

Extracted information in the form of a table; in this case, an account summary of the example bank statement.

Code examples

Amazon Bedrock Data Automation (BDA) Utility Module
Description:
    Helper functions to create BDA projects, blueprints, invoke jobs,
    monitor job status, and fetch results.
import boto3
import time
import json
import botocore
class BedrockDataAutomation:
    def __init__(self, region="us-east-1"):
        self.bda = boto3.client("bedrock-data-automation", region_name=region)
        self.runtime = boto3.client("bedrock-data-automation-runtime", region_name=region)

    # ------------------------------------------------------------
    # BLUEPRINT OPERATIONS
    # ------------------------------------------------------------
    def create_blueprint(self, name, schema, description="", stage="LIVE"):
        """
        Create a BDA Custom Output Blueprint from a JSON schema.
        """
        print(f"Creating blueprint: {name}")

        response = self.bda.create_blueprint(
            blueprintName=name,
            blueprintStage=stage,
            type="DOCUMENT",
            schema=json.dumps(schema)
        )
        return response["blueprint"]["blueprintArn"]

    # ------------------------------------------------------------
    # PROJECT OPERATIONS
    # ------------------------------------------------------------
    def create_project(self, name, description, standard_output_config, custom_output_config=None):
        """
        Create a BDA Project with Standard or Custom Output.
        """
        print(f"Creating project: {name}")

        response = self.bda.create_data_automation_project(
            projectName=name,
            projectDescription=description,
            projectStage="LIVE",
            standardOutputConfiguration=standard_output_config,
            customOutputConfiguration=custom_output_config or {}
        )
        return response["projectArn"]

    # ------------------------------------------------------------
    # INVOCATION OPERATIONS
    # ------------------------------------------------------------
    def invoke_project(self, project_arn, profile_arn, input_s3_uri, output_s3_uri, blueprints=None):
        """
        Invoke a BDA project using async invocation.
        """
        print(f"Invoking project: {project_arn}")

        kwargs = {
"inputConfiguration": {"s3Uri": input_s3_uri},
"outputConfiguration": {"s3Uri": output_s3_uri},
"dataAutomationConfiguration": {
"dataAutomationProjectArn": project_arn,
"stage": "DEVELOPMENT"
},
"dataAutomationProfileArn": profile_arn
}

        if blueprints:
kwargs["blueprints"] = blueprints

        response = self.runtime.invoke_data_automation_async(**kwargs)
       invocation_arn = response["invocationArn"]

       print("Invocation ARN:", invocation_arn)
       return invocation_arn

    # ------------------------------------------------------------
    # JOB STATUS POLLING
    # ------------------------------------------------------------
    def wait_for_job(self, invocation_arn, poll_interval=10):
        """
        Poll until job finishes.
        Returns final status object.
        """
        print("Polling job:", invocation_arn)

        while True:
            try:
                resp = self.runtime.get_data_automation_status(
                    invocationArn=invocation_arn
                )
            except Exception as e:
                print("Error fetching status:", e)
                raise

            status = resp["status"]
            print(f"Status: {status}")

            if status in ("SUCCEEDED", "FAILED", "CANCELLED"):
                return resp

            time.sleep(poll_interval)



# --------------------------------------------------------------------
# EXAMPLE USAGE
# --------------------------------------------------------------------
if __name__ == "__main__":
    bda = BedrockDataAutomation(region="us-east-1")

    # 1. Create Blueprint
    blueprint_schema = {
        "type": "object",
        "properties": {
            "account_holder": {"type": "string"},
            "balance": {"type": "string"},
            "transactions": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "date": {"type": "string"},
                        "description": {"type": "string"},
                        "amount": {"type": "string"}
                    }
                }
            }
        },
        "required": ["account_holder", "transactions"]
    }

    blueprint_arn = bda.create_blueprint(
        name="BankStatementBlueprint",
        schema=blueprint_schema,
        description="Extract fields from bank statements."
    )

    # 2. Create Standard Output Config
    standard_config = {
        "document": {
            "extraction": {
                "granularity": {"types": ["PAGE", "LINE"]},
                "boundingBox": {"state": "ENABLED"}
            },
            "outputFormat": {
                "textFormat": {"types": ["PLAIN_TEXT", "CSV"]}
            }
        }
    }

    # 3. Create Project with Custom Blueprint
    project_arn = bda.create_project(
        name="BankStatementProject",
        description="Process PDF bank statements",
        standard_output_config=standard_config,
        custom_output_config={
            "blueprints": [
                {
                    "blueprintArn": blueprint_arn,
                    "blueprintStage": "DEVELOPMENT",
                    "blueprintVersion": "1"
                }
            ]
        }
    )

    # 4. Invoke the project
    # Ensure you replace <ACCOUNT_ID> with your actual AWS Account ID
    profile_arn = "arn:aws:bedrock:us-east-1:<ACCOUNT_ID>:data-automation-profile/us.data-automation-v1"
    invocation_arn = bda.invoke_project(
        project_arn=project_arn,
         profile_arn=profile_arn,
        input_s3_uri="s3://your-bucket/input/statement.pdf",
        output_s3_uri="s3://your-bucket/output/",
        blueprints=[
            {
                "blueprintArn": blueprint_arn,
                "version": "1",
                "stage": "DEVELOPMENT"
            }
        ]
    )

    # 5. Poll job status
    final_status = bda.wait_for_job(invocation_arn)
    print("Final status:", json.dumps(final_status, indent=4))

Types of document blueprints

When processing documents, BDA supports five core automation types:

1. Classification: invoice, bank statement, ID card, contract, HR letter, etc.

2. Extraction: Extract entities, fields, tables, metadata.

  • Example: From a bank statement → Date, Description, Amount, Balance.

3. Transformation: Modify or restructure data.

  • Example: Convert Home Address into separate fields -> street, city, ZIP code, etc.

4. Normalization: Standardize data values.

  • Example: Convert multiple date formats (MM/DD/YYYY → YYYY-MM-DD).

5. Validation: Validate extracted fields against rules.

  • Example: Amount must be numeric; dates must match the format; balances must reconcile.

Use cases that illustrate business value

Real-world scenarios where BDA provides significant ROI include:

  • Financial Services: Automate processing of bank statements, invoices, and loan applications, reducing manual labor and speeding up reconciliation or underwriting.
  • Insurance: Ingest and extract data from claims forms, medical reports, and damaged-asset photos.
  • HR / Legal: Process resumes, contracts, and offer letters; extract structured data, including skills, clauses, salaries, and parties.
  • Customer Support: Transcribe and summarize calls, extract intent and sentiment, and feed those insights into CRM or case systems.
  • Security & Compliance: Analyze CCTV footage or meeting recordings to detect key actions, summarize context, and flag compliance issues.

BDA proves itself flexible and powerful, as it supports both standard outputs for basic workflows and fine-tuned custom schemas via blueprints. It is scalable and robust, with projects that enable batch processing and versions (development vs. live) for safe testing. It’s also audit-friendly, providing structured fields with types, normalization rules, and validation logic. 

“Compared with rule-based systems, foundation models achieve better semantic extraction across the board.”

A true key benefit is that BDA is multimodal across formats. Users can use the BDA framework to process documents, images, audio, and video. And, best of all, it’s highly accurate. Compared with rule-based systems, foundation models achieve better semantic extraction across the board. 

Amazon Bedrock Data Automation empowers businesses to transform unstructured, multimodal content into structured, trustworthy, and actionable data. With minimal setup, highly customizable blueprints, and a scalable project-based architecture, BDA helps organizations reduce manual workload and unlock insights faster.

The post Template-based data extraction is dead. Here’s what comes next. appeared first on The New Stack.

Kubernetes teams trust automation to ship code but not to touch CPU, and AI is raising the stakes

Kubernetes teams automate deployments without thinking about it. CI/CD pipelines fire dozens of times a day, autoscaling adjusts replicas in the background, rollback is muscle memory. But there is one category of automation where that confidence vanishes: letting a system change CPU and memory requests on a running workload without a human reviewing it first. 

And as AI inference lands on Kubernetes at scale, that hesitation is becoming hard to ignore, and increasingly expensive.

Why teams trust automation for change but not for constraint

We surveyed 321 Kubernetes practitioners at enterprise organizations earlier this year. The headline finding is one most practitioners will recognize immediately: 82% report high or complete trust in automated delivery controls. But 71% still require human review before applying resource optimization recommendations. Only 27% allow CPU and memory changes to be auto-applied, even within guardrails.

“Deploying code feels additive… rightsizing feels subtractive because you are removing safety margin from a running service, and the failure mode is fundamentally different.”

Those numbers describe a specific asymmetry. The same engineers who deploy to production dozens of times a day without hesitation slow down the moment automation wants to adjust resource allocation. And the survey data make it clear why. Deploying code feels additive. You are shipping new value, the rollback path is well understood, and if something breaks you usually see it right away. Meanwhile, rightsizing feels subtractive because you are removing safety margin from a running service, and the failure mode is fundamentally different.

As one practitioner in the survey put it: “Automated right-sizing carries a unique risk because it directly impacts the underlying stability of the application runtime. Unlike a code deployment that follows a tested path, resource changes alter the invisible contract between the workload and the scheduler.”

When you change resource requests, you change how Kubernetes schedules, prioritizes, and allocates resources. Those effects are not visible the way a code change is. You can’t trace them through a deployment pipeline. And you might not discover that something went wrong until two weeks later, when a traffic spike hits a threshold that didn’t exist at the old values. By that point, three other things have changed too, and proving causation is nearly impossible. The people responsible for those workloads are the same people who get paged at 2 a.m., and they know this.

Why AI workloads raise the stakes

That trust gap existed before inference workloads showed up. What’s changed is the cost of not closing it.

For a long time, teams could absorb the cost of manual oversight. They knew their workloads, had intuition for where the safe boundaries were, and the inefficiency of over-provisioning was a price worth paying for stability. GPU-accelerated inference workloads change that math. GPU compute is significantly more expensive per hour than CPU. The cost of over-provisioning is no longer a rounding error you can absorb quietly. And the workload behavior is less familiar, as inference jobs are bursty in ways teams haven’t built intuition for, traffic patterns shift as models are updated and usage changes, and the resource dimensions involved differ from what teams have spent years learning to tune.

That unfamiliarity compounds with scale. Rightsizing isn’t a one-lever problem the way horizontal scaling is. It involves, at minimum, CPU and memory requests and potentially limits for both, with four dimensions per workload, multiplied across hundreds or thousands of workloads per cluster. The survey data indicates that manual optimization breaks down at around 250 changes a day. Inference workloads push teams past that threshold faster than anything they’ve managed before, because the resource decisions are more frequent and the cost of getting them wrong is higher.

The economic case for automated rightsizing has never been stronger. The organization’s willingness to delegate hasn’t caught up because teams are being asked to trust automation with workloads they don’t yet have a track record with.

What the survey says about closing the gap

When we asked practitioners what would actually increase their trust in optimization automation, 48% said visibility and transparency into how decisions are made, 25% wanted proven guardrails, and 23% needed instant rollback.

Nobody asked for full manual control and very few asked for blind autonomy. What they described is automation that earns trust in stages, and that’s consistent with how the teams furthest along in their automation journey actually got there. They didn’t start with production. They started with a single namespace in a dev environment, observed the system’s behavior, compared recommendations with outcomes, and gradually expanded the scope. Different environments remained at different levels of automation maturity simultaneously, and that was intentional. Production carried more scrutiny than dev.

CI/CD followed the same curve, and the timeline is easy to forget. Most organizations took years to get from running their first automated pipeline to trusting it with production deploys without manual approval on every commit. Kubernetes resource automation is earlier in that same process, and AI workloads are extending the timeline because teams are building trust from scratch with a workload category that doesn’t yet have a track record.

Why automation design matters as much as capability

Some automation architectures deliver meaningful value only with full delegation. The system needs complete control to function the way it was designed to. That’s a form of forced autonomy, and it creates an adoption problem because it asks for exactly the level of trust that most organizations haven’t built yet. Force generally doesn’t work. Teams that feel pushed into a level of delegation they aren’t comfortable with tend to pull back entirely after the first incident.

The alternative is what I’d describe as adaptive autonomy: designing the system to work at every stage of the trust curve. A team still evaluating gets useful recommendations in read-only mode. A team ready to act but wanting boundaries can run guardrailed execution within limits they define. As confidence grows, the system handles more decisions autonomously while humans manage exceptions. And for environments where the track record supports it, closed-loop optimization runs in the background and becomes boring, which is the goal. Each stage is a legitimate operating mode, not a stepping stone you have to rush through.

That design distinction matters more with AI workloads than it ever did with traditional services, precisely because the trust-building process is starting from zero on workloads where the cost of getting it wrong is highest.

“Trust takes a long time to build and a single production incident to undermine.”

The other piece that makes this sustainable is rollout safety. Trust takes a long time to build and a single production incident to undermine. Start with the workloads showing the most headroom between requests and actual usage. Make changes incrementally, small enough that a bad outcome stays contained. Rollback needs to be fast and tied to the health signals the team already monitors. And start with opt-in, not opt-out. Let the teams willing to go first build a track record that others can look at.

The broader pattern

The 71% figure is sometimes read as resistance to automation. I think it’s a more accurate picture of how operational trust actually forms: conditional, earned over time, and moving at different speeds depending on what’s at stake. AI workloads are raising those stakes significantly, which means the path to trusted automation matters more now than it did when the cost of caution was just some unused CPU.

“Most of what gets written about Kubernetes optimization focuses on tooling capability, and the tooling is capable. The harder problem is the human one.”

Most of what gets written about Kubernetes optimization focuses on tooling capability, and the tooling is capable. The harder problem is the human one. If your team is managing AI inference workloads on Kubernetes and your optimization tooling is sitting in read-only mode, the question worth asking isn’t whether to trust the system. It’s whether the system is designed to let you build that trust gradually, starting where the stakes are low and expanding as the evidence supports it, on workloads where getting it wrong costs more than it ever has before.

The post Kubernetes teams trust automation to ship code but not to touch CPU, and AI is raising the stakes appeared first on The New Stack.

GitLab just surveyed 1,500 developers. Here’s why it matters for your codebase.

Minimalist geometric illustration of a solitary person straining against a rope. This perfectly visualizes the core insight that rapid AI coding speed without infrastructure control and governance becomes a major organizational liability.

For the past two years, the conversation about AI-assisted software development has been dominated by speed. A new GitLab survey of more than 1,500 developers and technology leaders found that 60% say AI coding ROI has already exceeded expectations, and 78% report their teams are writing and committing code faster since adopting AI tools. 

But speed without control is a liability.

Most organizations have pursued agentic engineering by adding AI coding tools on top of their existing infrastructure. Coding agents are delivering speed, but that speed isn’t showing up across the full software lifecycle: Only 21% of respondents report productivity gains beyond code generation itself.

“Speed without control is a liability.”

The infrastructure problem runs deeper. Git backends, toolchains, and governance frameworks were built for human-scale concurrency. Agents operate at machine scale, and that mismatch shows up fast. Platform reliability breaks down with millions of agent sessions hitting the same backend, security exposure widens as agents touch dependencies at scale, and cost overruns mount as agents consume tokens inefficiently on infrastructure that wasn’t built for them.

Agentic adoption outpaced governance

The adoption curve for AI coding tools outpaced the development of required guardrails, with 80% of organizations saying they adopted AI tools faster than they developed policies to govern them, and 82% reporting that AI-generated code risks creating a new form of technical debt that their organizations are not prepared to manage.

In practice, that means platform reliability challenges under agent load, security and compliance exposure that widens as agents touch dependencies at volume, and agents operating with artificial confidence because they lack full context. Only 28% of organizations say their software development lifecycle tools are fully integrated with shared data and workflows, which means most teams are trying to govern agent actions across a toolchain that was never designed for them.

Agentic engineering needs agentic infrastructure

Agentic engineering requires two things: agentic coding and agentic infrastructure. Most organizations have the first but lack the second.

Agentic infrastructure spans four areas: the execution layer, the context layer, the governance layer, and the orchestration layer working together.

The first is machine-scale execution. Git backends, CI/CD pipelines, and deployment systems were designed for human-paced development. In the agentic era, they need to handle millions of agent sessions without breaking. When a production incident occurs, the path from symptom back to origin should take minutes, not days.

The second is context that travels with code. As Bastian Stahmer, Business Owner of Vehicle Software Development Platform at Mercedes-Benz, put it on a panel recently, “An agent can only be as good as the context and semantics fed to it.” A context graph connecting code, work items, pipelines, security findings, and production signals is what makes agents genuinely useful at scale and keeps artificial confidence in check.

“An agent can only be as good as the context and semantics fed to it.”

The third is governance built into the flow. Agent actions need to be tied to an identity, logged against a policy, and provable to a reviewer. Low-risk changes move fast, while higher-risk changes trigger review. For Mercedes, operating under automotive regulatory standards that require full traceability and human accountability, GitLab is the control plane where that accountability lives.

The fourth is orchestration. Execution, context, and governance are only as effective as the system coordinating them. The orchestration layer coordinates agent actions across the full software lifecycle according to the policies teams define, determining which agents run, in what order, and how failures and handoffs are managed. Without it, agentic infrastructure is a set of independent capabilities rather than a working system.

What’s next

The next phase of AI in software will focus less on generating code and more on governing it, according to 85% of respondents. That shift reflects how enterprises are maturing their thinking about AI, from a productivity tool to a foundational capability that needs to be trusted, traced, and maintained at scale.

When governance is built into the platform, speed and control are no longer in tension. Traceability becomes a competitive advantage. Context becomes institutional memory. And the codebase, rather than accumulating invisible risk, becomes an asset that grows more reliable over time.

The post GitLab just surveyed 1,500 developers. Here’s why it matters for your codebase. appeared first on The New Stack.

The database storage problem is solved. Here’s what comes next.

Abstract artistic wave pattern with flowing parallel lines in coral and purple, serving as a metaphor for Postgres database data movement and architectural pipelines.

For most of its 30-year history, Postgres has been viewed as a transactional database. Organizations trust it with customer records, financial transactions, and countless other operational workloads. Its reputation was built on reliability, strong transactional guarantees, and a vibrant open-source community that has spent decades refining the database without compromising its foundations.

However, some of the most important innovations in the Postgres ecosystem today have little to do with storing data. They have to do with reducing the need to move it around.

“Some of the most important innovations in the Postgres ecosystem today have little to do with storing data. They have to do with reducing the need to move it around.”

Database innovation has historically focused on performance, scalability, and reliability. Increasingly, the harder problem is interoperability: how operational data can be shared across analytical systems, AI applications, and downstream services without creating yet another pipeline or copy.

Why Postgres keeps showing up

The reality of modern software architecture is that data rarely stays in one place. Information created in operational systems quickly finds its way into warehouses, search platforms, machine learning environments, and AI applications. Every new system solves a legitimate business problem, but it also creates another destination for data and often another copy to maintain.

The costs of this approach extend beyond infrastructure spending alone. Every additional copy introduces latency, creates another potential source of inconsistency, and increases the operational burden of keeping systems synchronized. Many organizations now spend as much effort moving data as they do storing it.

“Many organizations now spend as much effort moving data as they do storing it.”

For many businesses, Postgres serves as the system of record for customer interactions, transactions, application state, and other business-critical information. As organizations expand their analytical, machine learning, and AI capabilities, they are not looking to create another source of truth; rather, they’re looking for better ways to work with the one they already trust.

That shift is changing how Postgres fits into modern architecture. Historically, Postgres was viewed primarily as the place where operational data originated before being copied into downstream systems. Increasingly, organizations want those systems to work more seamlessly with operational data while reducing the pipelines, copies, and synchronization processes required to support them.

Technologies such as logical replication, change data capture, and foreign data wrappers have helped Postgres participate more directly in larger data ecosystems. As a result, organizations are no longer asking only whether Postgres can store their data. They’re instead asking how easily it can connect to everything around it.

That shift, from evaluating databases primarily on storage and performance to evaluating them on interoperability, may be one of the most important changes happening in the Postgres ecosystem today.

AI is exposing old problems

The recent focus on AI has brought renewed attention to data movement. AI didn’t create the problem. If anything, it exposed a limitation that has been quietly growing for years. For decades, organizations built architectures around the idea that data would move between systems through pipelines and periodic synchronization. That model worked because most analytical workloads could tolerate some degree of delay.

AI is changing those expectations. Many AI applications depend on access to current operational context. The challenge is not that organizations lack data. In many cases, they already have it. The challenge is that the data is spread across multiple systems, each with its own copy, latency profile, and synchronization process.

“AI is forcing organizations to confront a broader question: How many copies of the same data are actually necessary? The answer increasingly appears to be fewer than most architectures maintain today.”

As a result, AI is forcing organizations to confront a broader question: How many copies of the same data are actually necessary? The answer increasingly appears to be fewer than most architectures maintain today. As expectations around freshness rise, reducing unnecessary data movement becomes just as important as accelerating it. The underlying challenge is not new. AI has simply made it harder to ignore.

What’s next

The database industry spent decades solving storage. Databases became more reliable, storage became cheaper, and infrastructure became dramatically easier to operate. The next challenge is not where data lives, but how easily it can be shared across systems without introducing additional pipelines, copies, and synchronization overhead. Increasingly, the goal is not simply moving data faster. It is reducing unnecessary movement altogether.

Postgres has a habit of outlasting predictions about its replacement. For years, members of the community have joked that every year is “the year of Postgres.” The joke works because it keeps turning out to be true. 

Three decades after its creation, Postgres continues to adapt to new workloads, new architectural patterns, and new ways of building applications.

That longevity is not an accident. Enterprises continue to rely on Postgres because it provides a stable and trusted foundation for operational data.  While that foundation is unlikely to change, the scope of what organizations expect Postgres to do will continue to expand.  

As new workloads continue to emerge, much of the innovation will come through extensions that expand Postgres’s capabilities without sacrificing the stability that made it successful. In that sense, the future of Postgres may not be about reinventing the database itself, but continuously expanding what can be built on top of it.

The post The database storage problem is solved. Here’s what comes next. appeared first on The New Stack.

Why AI retrieval and ranking need more than vector search

Artistic illustration of a silhouette hiker journeying toward complex, layered mountain peaks under a glowing aurora sky, serving as a metaphor for moving beyond vector search to multi-dimensional AI retrieval architectures.

A recent GigaOm CxO Decision Brief explores how AI retrieval architectures are evolving beyond flat vector databases as organizations combine semantic search, ranking, personalization, and machine learning inference in production systems.

Vector search changed the AI infrastructure landscape by making semantic retrieval practical at scale. By converting text, images, and user behavior into embeddings, organizations could move beyond exact keyword matching and retrieve information based on meaning. But production AI systems rarely stop at vector similarity.

A real-world query often requires multiple signals to be evaluated simultaneously. Semantic relevance may be one factor, but so are structured attributes, business rules, personalization signals, freshness, access controls, recommendation logic, and machine-learned ranking models. As organizations move from AI experimentation to production-scale applications, the challenge is no longer simply finding similar items. It is in combining all of the signals that matter while maintaining low latency and operational simplicity. This is where tensors are attracting increasing attention.

While vectors represent information as a single dimension of numerical values, tensors provide a more general framework for representing and operating on complex, multi-dimensional data structures. They offer more control in how relevance is computed, allowing dense embeddings, sparse features, metadata, and model outputs to be evaluated together within a unified retrieval and ranking process. For organizations building large-scale retrieval systems, this raises an important architectural question: is a flat vector store sufficient, or does the next generation of AI applications require something more expressive?

“Tensors provide a more general framework for representing and operating on complex, multi-dimensional data structures.”

A new GigaOm CxO Decision Brief, “The Tensor Advantage in AI Search,” explores this question in depth.

Among the findings:

  • Production AI systems increasingly depend on combining semantic, lexical, behavioral, and business signals rather than relying on vector similarity alone.
  • Architectural fragmentation between vector databases, search engines, rerankers, and feature stores introduces latency, operational complexity, and synchronization challenges that become more significant as workloads scale.
  • Emerging retrieval models, including multi-vector and late-interaction approaches, place new demands on infrastructure that were not anticipated when first-generation vector databases were designed.
  • Tensor-native architectures provide an alternative approach by treating multidimensional data structures as first-class citizens rather than forcing them into simpler vector abstractions.

The paper also examines the infrastructure, operational, and organizational implications of these architectural choices, including benchmark data, deployment considerations, and the trade-offs engineering leaders should evaluate when planning future AI retrieval systems.

“Retrieval is evolving from a nearest-neighbor problem into a ranking and decision-making problem.”

As AI applications become more sophisticated, retrieval is evolving from a nearest-neighbor problem into a ranking and decision-making problem. Understanding the role tensors play in that transition may be one of the most important architectural discussions facing engineering leaders today.

Download the GigaOm CxO Decision Brief to explore the findings in full.

The post Why AI retrieval and ranking need more than vector search appeared first on The New Stack.

When your data model is the bottleneck: lessons from Medium’s feature store

Abstract neon blue and green wavy lines on a dark background, representing fluid data streams and a database latency bottleneck.

“Keep readers reading” is the not-so-simple goal of Medium’s recommendations system. To predict what’s most likely to appeal to a particular reader at any given time, Medium continuously processes user activity signals (stories read, recommendations shown, follows, likes, etc.). It then immediately correlates that with the steady stream of new articles, which is estimated at millions per month.   

Smart models and good inference logic are required, but that’s not enough. The data must be stored and retrieved quickly enough to remain relevant while the user is browsing. That’s the job of Medium’s feature store. And getting the data model right started to matter a lot as they scaled to 1M operations per second.

Andréas Saudemont, Medium Principal Software Engineer, recently walked through how the team identified the problem and what they built to fix it. If you’d rather watch than read, you have two options: Watch a short version from Monster Scale Summit or an extended follow-up webinar

The feature store and its role in Medium’s recommendation system

The feature store ties it all together, ingesting user activity and internal events and feeding them to the ML models that power recommendations. It’s what enables customization like the “For You” feed that greets logged-in users.

A screenshot of Medium's "For you" page.

Each feature is a property of an entity, usually a user or a story. Some are simple and static, like whether a user holds a paid membership. Others capture interaction history: which stories a user has read, what content they’ve recently been shown, etc.

The following diagram shows a highly simplified view of the Medium feature store architecture:

A diagram showing a a highly simplified view of the Medium feature store architecture.

The problem with a relational features data model

When they built their feature store years ago, Medium used relational features for cross-entity relationships. Unlike regular features, a relational feature can have multiple values for a given entity ID. Each value is defined by a relation ID (the ID of the related entity) and a timestamp recording when the event occurred.

For example, a “story users have read” feature is attached to the story entity type. It relates to the user entity type, and its values indicate whether/when a given user has read that story. 

Andréas shared the following schema diagram to explain the concept:

A schema diagram explaining the relational features data model.

Features sit at the center, each attached to an entity type and defined by name, version, and data type. Non-relational features are simply a feature, an entity ID, and a value. Relational features add a relation ID mapping to another entity type, plus the value itself and a timestamp.

This approach proved suboptimal from a data modeling perspective. Since relational features link two entity types, the data ends up split between two tables: one for the entity IDs and one for the values. That means you can’t get both in a single query. The first query retrieves only entity IDs (not their associated values) and relies on ALLOW FILTERING. A second query then runs for each entity ID to fetch its value. “If we have 1000 entity IDs for which we want to fetch values, then we have to run 1000 queries to fetch these values,” Andréas said.

Overrelying on ALLOW FILTERING made things worse. “This is bad,” Andréas said, referring to monitoring data showing that 90% of rows read via these queries were simply discarded. “This is just data that we don’t need. ALLOW_FILTERING should be an escape hatch, not our design pattern.”

“ALLOW_FILTERING should be an escape hatch, not our design pattern.”

Chart showing that overreliance on ALLOW FILTERING led to 90.2% of rows read via these queries being discarded.

The list feature model

So they reinvented their data model and shifted to a list-based feature model. Instead of splitting data across two tables, everything for a given entity lives in one place and is retrieved in a single query.

Like other features, a list feature is defined by its entity type, name, and optional version. What’s different is the value. While a non-relational feature has a single value, such as true or false, a list feature’s value is a collection of items, each containing a value and a timestamp. Item values can be of any data type; the feature store doesn’t enforce consistency within a list.

Diagram explaining the list feature concept.

For example, consider a user’s reading history. The entity is user, the feature name is reading history, the TTL is 6 months. After that TTL is reached, the data is automatically dropped by the database (since older history isn’t useful for recommendations). The list for a given user is a collection of story IDs and the timestamps at which they were read. The same story can appear multiple times, and multiple items can share the same timestamp.

Example list of a user's reading history, showing a collection of story IDs and the timestamps at which they were read.

A range of operations need to be supported. Create List and Delete List operations run at most a few times per day. Remove List Items with Value, which lets a reader scrub a specific story from their history so it stops influencing recommendations, runs at 1k-10k per second. Add List Items is higher still: every story read and every thumbnail shown to a user generates an event. Get List Items is the top, at 100k-1M operations per second.

Table showing the number of times various operations run per given timeframe.

“The Add List Items, and even more the Get List Items operations, are really the reasons why we need an efficient data store.”

“The Add List Items, and even more the Get List Items operations, are really the reasons why we need an efficient data store,” Andréas said.

Multiple items, one timestamp

Beyond raw efficiency, the new data model also had to support multiple items with the same timestamp. When Medium shows a user four story thumbnails simultaneously, all four presentation events share the same timestamp, but have distinct story IDs. If this isn’t handled correctly, primary key collisions occur.

The team’s solution was a single list_items table that stores everything.

Screenshot of the code for the list_items table which stores everything.

The partition key combines feature_key and entity_id, keeping all items for a given list together. All of user 123’s reading history is stored in one partition, retrieved in one query. The clustering key concatenates each item’s timestamp with an MD5 hash of its value. The hash is what makes same-timestamp items with distinct values possible. 

Relying on MD5 hashes for uniqueness raises its own set of questions, but in practice, the team hasn’t seen collisions. “The values that we are storing are sufficiently distinct, especially when you add the timestamp into the equation,” Andréas said. The table’s clustering order is set to descending so ScyllaDB can optimize for the typical read pattern (most recent N items) rather than leaving the application to sort afterward.

TTL to control storage costs

Storage cost is controlled entirely through ScyllaDB’s native TTL, with no cleanup logic required. Every row expires automatically based on its own timestamp plus the feature’s TTL duration. “We don’t have anything to do regarding that,” Andréas said. “Any row for which the TTL is expired will be considered deleted by ScyllaDB.” 

Storage plateaus for a steady write rate. When a feature is retired, its data drains away on its own. “That’s super useful for controlling our storage and usage costs.”

Chart showing storage usage/costs and number of item insertions against time

Implementing the list operations

Add List Items is a logged batch of INSERTs with atomicity guaranteed: all items land or none do. Each row carries its own TTL calculated from its timestamp, so older items expire sooner. Since items almost always carry a current timestamp, new entries append to the top of the partition, which is exactly where reads will look first.

The code to "Add List Items" - a logged batch of INSERTs with atomicity guaranteed.

Table showing the "list_items" table partition before and after running the Add List Items function.

Get List Items runs as a single-partition SELECT with a minimum timestamp and a row limit. “We run the query on a single partition,” Andréas said. “That’s the maximum efficiency that we can have.” The clustering key handles filtering and ordering directly. Post-processing is not required.

The code to "Get List Items" - a single-partition SELECT with a minimum timestamp and a row limit.

The "list_items" table partition before running the "Get List Items" function, the response received from the function.

Remove List Items with Value is the one operation that couldn’t be reduced to a single query. Because value isn’t part of the primary key, a direct filter isn’t feasible.

Code for the "Remove List Items with Value" function.

A local secondary index built specifically for this case first finds the matching item keys, then a batch DELETE removes them by primary keys.

The code to create a local secondary index which lists items by value.

“Using an index is really faster than a scan because the query is highly selective,” Andréas explained. “We have very few items in a given list that have the same values compared to the total number of items in a list. And thanks to the current structure, using a local secondary index is faster than a global index.”

The "list_items" table partition before and after running the "Remove List Items with Value" function.

Andréas shared another example. Starting with the original table partition, the goal is to delete all items with the value “storyC.” Using the local secondary index, the system first identifies the two rows containing that value. It then issues two DELETE statements using the item keys from those rows, which removes them from the list. The final operation, removing all list items, is even more straightforward.

“We can just drop the partition,” Andréas said, “and ScyllaDB does its magic. It just deletes all the rows for that partition, which means that it deletes all the items for the given list. And bonus point: it’s atomic. It’s either completing successfully or not changing anything at all.

The code for the "Remove All List Items" function.

The "list_items" table partition before and after running the "Remove All List Items" function.

ScyllaDB vs. DynamoDB performance

Medium implemented the list operations on top of both ScyllaDB and DynamoDB. The main goal was to benchmark how both databases compared on their actual production data. “Conceptually they are very close,” Andréas noted, “but they have significant differences in how they operate.”

For AddListItems, P50 latencies were low with both databases: ScyllaDB came in under 1.5ms, DynamoDB under 5ms. “DynamoDB is extremely fast, not as fast as ScyllaDB, but extremely fast at sub 5ms latency,” Andréas commented. Things got more interesting at the P95 and P99 latencies. ScyllaDB held steady at around 5-6 ms P95s, while DynamoDB ranged from 13-45 ms. ScyllaDB’s P99s were steady single-digit milliseconds, while DynamoDB’s ranged from 40- 120 ms.

Graphs showing AddListItem latencies.
AddListItem latencies: The blue line is DynamoDB; the purple line is ScyllaDB

It was a similar story for GetListItems. At P50, ScyllaDB clocked in at 1 ms, DynamoDB at around 3.5 ms. At P95, ScyllaDB held around 5-6 ms while DynamoDB spiked from 30 – 60ms. And at P99, ScyllaDB remained at ~30ms while DynamoDB ranged from 70 ms all the way up to 220 ms.

Graphs showing GetListItem latencies.
GetListItem latencies: The top blue line is DynamoDB; the lower purple line is ScyllaDB

“ScyllaDB is very fast, with very predictable performance, and that’s super important for us.”

One caveat: DynamoDB was running without an extra caching layer. “We expect that could have a significant impact for DynamoDB because of the high cache hit rate that we are seeing on the list,” Andréas said. “But we don’t have the data yet, so we cannot compare them.” His verdict for now: “ScyllaDB is very fast, with very predictable performance, and that’s super important for us.”

Key takeaways

One pleasant side effect of getting the data model right: Medium is now eager to use ScyllaDB for additional feature store workloads. Before, they were holding back because they didn’t want to build on the shaky relational feature foundation.

Reflecting on the path to this point, Andréas left the audience with this parting advice:

“If you have a suboptimal data model, you will have queries that are slow, that will scale badly. And most likely, you won’t be able to optimize that data model. You will have to define a new data model that will be better. So take time to think about your data model before you start the implementation, because once you have production data using your suboptimal data model, it’s too late.”

The post When your data model is the bottleneck: lessons from Medium’s feature store appeared first on The New Stack.

AI retrieval at scale is becoming a systems problem, not a tooling problem

Flat art illustration of a single winding road through a vast night desert landscape, serving as a visual metaphor for an integrated AI retrieval data pathway.

AI retrieval has moved well beyond embeddings and vector search. Early retrieval architectures focused primarily on semantic similarity. Still, production AI applications increasingly demand more from the retrieval layer: combining keyword matching, semantic retrieval, ranking, and real-time signals within a single request path.

Vector databases solved an important problem by making semantic retrieval practical. But production AI systems increasingly require more than retrieval alone. Customer-facing applications such as search, recommendations, and RAG must retrieve, filter, and rank results in real time while serving large user populations under tight latency constraints. 

As systems evolve toward conversational, research-oriented, and agentic workflows, retrieval performance, ranking quality, and architectural simplicity become increasingly important to maintaining relevance at scale.

In recently published research commissioned by Vespa, GigaOm explores how AI search platforms are evolving as organizations move beyond standalone vector search toward more integrated retrieval and ranking architectures. Rather than focusing purely on model quality, the report examines the operational and architectural trade-offs that emerge as AI workloads move into production.

GigaOm’s findings

AI retrieval architectures have become more fragmented over time. What begins as a straightforward search stack often evolves into a collection of loosely coupled systems: lexical search, vector retrieval, feature serving, reranking, synchronization pipelines, and model infrastructure. 

“What begins as a straightforward search stack often evolves into a collection of loosely coupled systems.”

GigaOm’s view is that the operational overhead of connecting and maintaining these layers is becoming a limiting factor in itself, slowing iteration cycles and making every relevance improvement dependent on coordinated changes across multiple systems.

One of the more interesting findings in the report is that consolidation is not framed primarily as a procurement exercise but as an engineering and systems design decision. GigaOm argues that teams increasingly pay for fragmentation through duplicated data movement, synchronization logic, operational maintenance, and cross-system tuning. 

The hidden cost is not simply infrastructure spend but the engineering effort required to keep retrieval pipelines aligned, rather than improving ranking quality, personalization, and user-facing AI capabilities.

“The hidden cost is not simply infrastructure spend but the engineering effort required to keep retrieval pipelines aligned.”

The report also suggests that platform convergence matters because modern retrieval workloads increasingly combine keyword search, vector retrieval, real-time features, and ML-based ranking in the same request path. 

GigaOm highlights architectures that bring these stages closer together to reduce latency, improve data freshness, and simplify experimentation, while acknowledging trade-offs such as concentration risk and migration complexity. 

Rather than recommending wholesale replacement, the report advocates a phased adoption approach, beginning with ranking and validation on production workloads before progressively consolidating retrieval capabilities.

Download a copy of the report.

The post AI retrieval at scale is becoming a systems problem, not a tooling problem appeared first on The New Stack.

The DIY platform trap that’s burning out engineering teams

Geometric vector illustration of a massive, layered blue mountain range, serving as a visual metaphor for platform engineering infrastructure and the mountain of automation complexity.

Platform engineers are some of the most resourceful people in IT. Give them a problem, and they’ll automate their way toward a solution. But what happens when the automation itself becomes the problem?

This is the quiet crisis hiding inside many organizations today. In the race to reduce toil, teams have built what amounts to a mountain of automation. Scripts, layered on blueprints, layered on orchestration workflows, layered on tooling, APIs, GitOps, and infrastructure and label it a “platform.” This isn’t a platform; it’s complexity dressed up in a better outfit.

Trading one problem for another

Here’s the dirty secret about using automation to build your own platform stack: you don’t actually eliminate complexity; you just become responsible for it in a new way.

It starts well enough. You automate a painful workflow, ship it, and you move on to the next fire. But automation doesn’t maintain itself. Over time, the team that wrote it moves on. As they do, the context behind why it was built fades.

Nobody quite remembers what the edge cases were, why that snowflake script was written that way, or the original problem it solved. And when it breaks–and it will break–you’re not debugging an application. You’ll be performing an archaeological excavation of your own infrastructure, to decipher the intent of the team that originally constructed the automation.

When scripts outlive their authors

So you do what engineers do: you automate around it. You add new automation on top of old to address the gaps. Now you’re managing two mountains of automation instead of one. And here’s the impact that rarely makes it into the original business case – the platform team doesn’t get to walk away when it’s “done” because it’s never done.

These engineers can’t be reassigned without your platform decaying beneath the applications and services that make up the business’s backbone. You need a robust team to manage this indefinitely just to keep the lights on. We’re simply trading software costs for people costs. And often, you end up spending more to produce something less scalable and capable than what you had from day one.

“Automation may mask complexity but does not eliminate it, and mountains of automation makes diagnosis and repair exponentially harder when things go sideways.”

This is the real trap. Automation, at its best, is a productivity multiplier. At its worst, it’s lipstick on a pig; all the ceremonies of agility without the true benefits. Automation may mask complexity but does not eliminate it, and mountains of automation makes diagnosis and repair exponentially harder when things go sideways.

What a pre-engineered PaaS actually does

A true Platform as a Service (PaaS) isn’t a collection of automation. It’s a pre-engineered system where the underlying plumbing, services, security, and resilience are already integrated before you ever install and consume it. This is the ‘batteries included’ model where the platform is ready to use on Day 1 based on best practices and proven architectures. This kind of integration out-of-the-box is one of the things that makes a platform trustworthy and predictable at scale.

For example, an integrated platform includes ‘how’ applications are built and deployed is pre-wired out of the box and works consistently across application types. One of the more unique things Tanzu Platform does is build deployment packages, including the base image for developers. This means that when a security problem comes out–like Copy Fail or the flood of AI-discovered vulnerabilitiesthe platform engineer can rebuild and redeploy apps very quickly without reaching back into the software delivery lifecycle (SDLC). They simply “restage’ the application using a single command.

The consistency of deployment packages and base images also enables developer velocity in the every day. When every application is built, packaged, and deployed the same way, developers stop re-solving the same infrastructure problems, and start focusing on the code that actually matters. This is a distinction worth drawing clearly–assembling capable open source tooling like Terraform, ArgoCD, Kubernetes, cert-manager, OpenBao, and Istio gives you powerful building blocks, but it doesn’t give you a platform.

You still own the integration, automation, the opinions, lifecycle management, and the operational model that ties them together. A pre-engineered PaaS handles the myriad of decisions for you. With a PaaS, onboarding a new team or new application isn’t a one-off integration project; it’s a repeatable, predictable process. Standardization is a core outcome of a pre-engineered PaaS, not a side effect, and it’s precisely what makes it possible to push changes faster and with more confidence, regardless of the team, language, or application type.

Security built into the platform

Security works the same way. When your team makes the decision to pull from open-source components and stitch them together, you now own every security gap between them – data at rest, data in flight, and its running state. This seems like a worthwhile investment at first, but as recent research suggests, AI-assisted attacks are on the rise, and platform teams won’t be able to keep up with surging security vulnerabilities in the build-it-yourself model.

A pre-engineered PaaS standardizes the governance and compliance posture across the board. Updates, patches, and fixes from a trusted, first-party vendor mean you’re not reinventing governance from scratch each time you add a new component. The PaaS can help you uniformly and at scale apply the changes in a cascading fashion rather than relying on custom automation.

The calculus starts to shift when you see deployment, security, and onboarding issues in aggregate. Achieving all of this with custom automation means spanning organizational silos, coordinating teams, sustaining headcount, and continuously funding work that never actually finishes.

And worse yet, this work has no meaningful competitive advantage for your organization. Your competitors are working to solve the same problem, but you’re just burning more resources to accomplish the same end result. You own the problem entirely rather than leaning on a trusted, proven vendor. Embracing a PaaS allows you to focus on higher-value, differentiating initiatives for the business.

AI is the forcing function

The conversation around PaaS is urgent again, and AI is why. Code generation can speed up your development cycles, building and pushing features faster, but production delays will persist if you’re still deploying at the same speed as before. 

To avoid eroding the benefits of code generation, you need to deploy applications nearly as fast as they can be coded with AI. This requires streamlining each step of the path to production. In an era where more organizations are exploring the use of autonomous agents, they need a platform that doesn’t take weeks to rotate credentials, days to provision a database, or require access to JIRA’s MCP Server to accomplish their goals.

“To avoid eroding the benefits of code generation, you need to deploy applications nearly as fast as they can be coded with AI.”

The pace of AI innovation itself compounds the problem. Whether it’s shadow AI use, MCP servers, agentic harnesses, this week’s new foundation models, or whatever emerges next, the landscape is evolving fast enough that what’s bleeding-edge today may be table stakes in six months. When you build your own platform, you’re on the hook to evaluate each layer of these new technologies, determine how they fit into your stack, and then integrate them yourself, on top of everything else your platform team is already managing to keep the business going.

Organizations running VMware Tanzu Platform receive those innovations. With Tanzu Platform 10.4, for example, customers gained MCP Gateway, an expanded service marketplace where developers can publish their own MCP servers and services for cross-organization consumption, as well as an agent buildpack to streamline and secure the deployment of agentic AI applications.

These are capabilities that would have taken a DIY team months to evaluate, build, and harden. And this isn’t unique to AI. Every release brings new capabilities across the platform that customers simply inherit, without the integration tax. That’s the compounding return on your investment in a pre-engineered PaaS. The platform keeps moving forward, and so do you.

VMware customers: You’re closer than you think

Platform engineers are uniquely equipped for this moment. They have the pattern recognition, they have seen the technology waves before, they bring their hard-won operational instincts, and the critical thinking skills to know when a system is genuinely resilient versus cleverly disguised complexity.

That’s exactly why their role in curating and operating this next generation of PaaS matters more than ever. Platform Engineers applying these battle-tested experiences using a PaaS will shortcut the tedious automation pitfalls, jumping straight to safely delivering Agentic AI and GenAI application services.

If you’ve already built your stack on VMware Cloud Foundation you’re already in a position to add the value of a true PaaS. VMware Tanzu Platform layers a pre-engineered PaaS on top of your existing infrastructure APIs, running alongside your VMs and containerized workloads, without ripping out what you’ve built and budgeting for alternatives.

With an incremental step, you can leverage what you know and trust, and layer on the only private cloud PaaS for agents that offers direct integration with Private AI services.

The post The DIY platform trap that’s burning out engineering teams appeared first on The New Stack.

The agentic identity crisis: Why your security isn’t ready for the AI revolution

Abstract geometric illustration of a mountain splitting apart with floating rock fragments against a muted blue background, symbolizing fractured legacy infrastructure and shifting security frameworks.

The transition from traditional web applications to agentic ecosystems is more than a change in the UI; it is a fundamental shift in the internet’s threat model. We are moving from a world where “bad input creates bad data” to one where “bad input creates bad actions.” As AI agents evolve from simple chatbots to autonomous conductors capable of calling APIs, reading sensitive files, and sending emails, our legacy security models are cracking under the pressure.

If you are building or deploying AI agents today, you are likely sitting on an IAM problem in disguise, considering that agents are outnumbering humans 144:1. In a recent global Enterprise Management Associates (EMA) survey on agentic, 95% of participants were in production or limited pilot programs using AI agents. Here is how to navigate the shift from human-centric security to the Agent IAM era.

1. What’s the problem? (The identity vacuum)

The core problem is that AI agents currently operate in an Identity Vacuum. In most production environments, agents are given ambient, inherited access. They run as service accounts with broad permissions or, worse, inherit the full permissions of the human user who triggered them.

This creates three critical vulnerabilities:

  • The Action-Based Threat Model: Unlike traditional apps, agents “do” things. If an LLM is tricked via prompt injection, it doesn’t just display a wrong answer; it executes a malicious tool call. 80% report seeing apps act outside of intended boundaries.
  • The RAG Attack Surface: Retrieval-Augmented Generation (RAG) systems are vulnerable to indirect prompt injection. If an agent fetches a document containing malicious instructions, that document becomes the new “master” of the agent, overriding developer guardrails.
  • Non-Human Identity (NHI) Explosion: We are seeing a massive surge in APIs, services, and autonomous agents that lack a centralized source of truth for identity. 39% report unauthorized access incidents with agents, and most teams have no way to revoke an individual agent’s access without breaking the entire service.

2. Why does it matter? (The widening remediation gap)

Anthropic’s Claude Mythos discovery recently highlighted the stakes. The model identified thousands of zero-day vulnerabilities across major OSs and browsers, including bugs that had survived 20+ years of human review.

This matters because AI is now a force multiplier for vulnerability discovery. While AI can find bugs at machine speed, humans still remediate them at a “human pace” (meetings, backlogs, patch cycles). 

“While AI can find bugs at machine speed, humans still remediate them at a ‘human pace.'”

If your IAM infrastructure is homegrown or unmanaged open source, you cannot patch fast enough to keep up with an AI-powered attacker. Identity is the most exposed layer because it is the control plane; if the agent’s identity is compromised, the entire infrastructure is open for lateral movement. SailPoint research reports 33% have seen agents inappropriately handle restricted data.

3. How do I fix the problem? (The agentic IAM blueprint)

Fixing agentic security requires moving the guardrails from the LLM prompt to the infrastructure. You cannot talk an agent into being secure; you must authorize it to be secure. Compounding the agentic problem, the majority of EMA survey participants do not believe their IAM solutions are ready:

  • 62% state not ready for agentic resiliency
  • 49% claim not ready for agentic compliance
  • 62% report not ready for agentic scale
  • 59% disclose not ready for agentic security

“You cannot talk an agent into being secure; you must authorize it to be secure.”

Treat agents as first-class identities

Agents must be treated as first-class non-human Identities. This means:

  • Authentication: Agents should authenticate against an Identity Provider using scoped credentials.
  • Short-lived tokens: Use OAuth2 to issue tokens that are interaction-scoped. If an agent is compromised, the token expires quickly, limiting the window of exploitation.
  • Relationship-based access control (ReBAC): Use a graph-based permission model to define exactly what an agent can touch.

Align retrieval with authorization

In RAG systems, the “view” permission must match the “retrieval” permission. Before an agent fetches a document to place in its context window, the system must check: Does this specific Agent ID have permission to view this Document ID? If not, the document is never retrieved, preventing the agent from ever seeing and being influenced by malicious payloads.

Engineers as conductors

Shift your engineering mindset. Stop trying to hard-code every agent action. Instead, act as a conductor, orchestrating agents through Policy as Code. Use tools to visualize these complex permission chains so you can see exactly how an agent’s relationships resolve to ALLOW or DENY.

4. “Gotcha” problems & how to avoid them

Even with a solid plan, several hidden costs and technical traps often emerge:

  • The inherited access trap:
    • Problem: Developers often give agents Admin rights to simplify development.
    • Fix: Implement Least Privilege Access from day one. If an agent only needs to read Marketing docs, don’t give it access to the whole S3 bucket.
  • The feedback loop delay:
    • Problem: As you add security layers, agent latency increases, leading users to bypass security for speed.
    • Fix: Use high-performance permission engines that can resolve complex queries in milliseconds, ensuring security doesn’t buffer the user experience.
  • The ghost agent problem:
    • Problem: Agents are created for a task, the task ends, but the credentials remain active.
    • Fix: Implement automated lifecycle management. Use Token Chain Revocation so that if a parent orchestrator agent is flagged, all child agent tokens are instantly invalidated.
  • Visual blindness:
    • Problem: Permission models for hundreds of agents become too complex to hold in a human brain.
    • Fix: Use visualization tools to audit your models. If you can’t see the graph, you can’t secure the graph.

Summary: Identity is where you start

Security is a process, not a product. While LLM guardrails and prompt hardening are important, they are easily bypassed. The only hard boundary that stays firm in the face of an autonomous agent is the Authorization Boundary.

Treat your agents as identities, scope their world with ReBAC, and ensure your IAM stack is professionally managed to keep up with the AI-driven pace of discovery. The future of the internet is agentic; make sure your security is too.

The post The agentic identity crisis: Why your security isn’t ready for the AI revolution appeared first on The New Stack.

How the AC/DC framework helps teams govern AI coding agents

Artistic aerial illustration of a four-person rowing crew in a white boat on vibrant blue water reflecting clouds, symbolizing alignment, discipline, and the AC/DC governance framework for AI coding agents.

Much of the conversation around AI coding is still centered on how fast machines can produce code. But code volume is not the same thing as software progress. As teams rely on agents for larger units of work, the harder question is whether they can build a repeatable system to steer, check, and correct machine-produced code before it creates downstream risk.

One useful way to think about that system is through the Agent Centric Development Cycle (AC/DC) framework. At its core, AC/DC defines four stages that govern how agentic development actually works at scale: Guide, Generate, Verify, Solve. Of those stages, Generate, the act of AI agents producing code, gets most of the market attention. But in practice, the framework stands or falls on the strength of the layers around it. If Guide is weak, agents start from the wrong assumptions. If Verify is weak, errors compound invisibly. If Solve is weak, teams inherit a growing queue of problems with no scalable way to address them.

Why verification has moved to the center

For years, modern software delivery was organized around a human pace of work. Developers wrote code in relatively small increments. Teammates reviewed it. The pipeline validated it. Problems were usually caught after the code had already been authored, but before they grew too large to understand.

Agentic development changes those conditions. Instead of a few hundred lines shaped through continuous human interaction, teams may now receive thousands of lines created in longer reasoning loops across multiple files and layers of the stack. At that scale, traditional review practices start to strain. The burden of understanding change rises much faster than the speed of generation.

“If organizations continue to treat verification as a late-stage checkpoint, they will discover that code generation has outpaced their ability to establish trust.”

That creates a governance problem. If organizations continue to treat verification as a late-stage checkpoint, they will discover that code generation has outpaced their ability to establish trust. This is where many teams will feel the first real friction in AI-assisted development: not at the moment of creation, but when they are asked to approve, merge, and maintain what was created.

Guide: Give agents boundaries, not just prompts

The first requirement in an agentic workflow is guidance. Not generic prompt advice, but structured context.

Agents need to understand more than the task in front of them. They need to understand the environment in which that task sits: architectural boundaries, engineering standards, compliance expectations, naming conventions, and the practical constraints that rarely live in a single document. Without that, an agent can produce something that appears correct locally while still being wrong for the broader system.

This is one of the central misconceptions in current AI tooling discussions. Many teams assume stronger models will naturally reduce the need for explicit guidance. In reality, the opposite is often true. The more work delegated to agents, the more important it becomes to define the terrain clearly. Guidance is what reduces avoidable drift before it enters the codebase.

In that sense, the “Guide” stage is not just preparation. It is the first layer of control.

Verify: The layer that turns speed into trust

Verification is where agentic development becomes either manageable or fragile.

AI systems often fail in ways that are hard to spot early: hidden logic flaws, reliability problems, security issues, or maintainability costs that only emerge later. Because these models are probabilistic and context-sensitive, verification cannot be a cursory review step. It has to be a core function of the development cycle.

That means verification has to happen in two places: inside the working loop while the agent is still generating, and again after the agent believes it has finished. The first catches mistakes early and helps steer the next step. The second tests whether the output actually satisfies functional, non-functional, and organizational requirements. 

This changes the role of feedback. Instead of surfacing issues only after a large pull request lands on a human reviewer, verification becomes an active part of shaping the work.

It also needs to be explainable and repeatable. Deterministic analysis, security checks, complexity analysis, and testing create evidence. They show what was checked, what passed, what failed, and why. In enterprise settings, that transparency is the basis for accountability.

“Code quality, in other words, is no longer just a maintainability concern. It is starting to look like an AI infrastructure efficiency variable.”

Code quality increasingly affects the economics of AI-assisted development. In a controlled study Sonar conducted using matched repository pairs with the same external behavior, architecture, dependencies, and test coverage, agents working in the higher-quality codebases used about 7% fewer input tokens, 8% fewer output tokens, and 11% less reasoning effort on average. They also re-read files 34% less often, a useful signal that clearer code reduces uncertainty and enables agents to commit edits more confidently. Code quality, in other words, is no longer just a maintainability concern. It is starting to look like an AI infrastructure efficiency variable.

Solve: Close the loop instead of growing the backlog

A verification layer is only useful if it leads to action.

That is why Solve matters so much in an AC/DC model. When issues are identified, the process needs a systematic way to remediate them, re-check the fixes, and learn from the results. Otherwise, verification becomes a reporting mechanism rather than an operational one. This is especially important in environments where AI is increasing the total volume of code under review. Without a remediation mechanism, every detection system eventually becomes a backlog generator. 

Solve is what prevents that failure mode. It turns findings into an iterative loop. Fixes are proposed, rechecked, and fed back into the next cycle so the system improves over time. In mature workflows, this means developers spend less energy chasing repetitive issues and more energy on architecture, judgment, and higher-order design decisions.

The real shift

The practical takeaway is simple. In an agentic development model, the primary challenge is no longer writing code; it is creating a system that makes generated code trustworthy.

Teams still need strong models and useful tooling, but the real differentiator is everything that surrounds generation: the quality of the context agents receive, the strength of the verification layer, and the ability to remediate issues quickly enough to keep pace with machine output.

The organizations that adapt fastest will not be the ones generating the most code. They will be the ones who can consistently turn that code into software that is understandable, governable, and production-ready.

“In the age of software agents, the real advantage will not come from generation alone. It will come from building the discipline around it.”

In the age of software agents, the real advantage will not come from generation alone. It will come from building the discipline around it.

The post How the AC/DC framework helps teams govern AI coding agents appeared first on The New Stack.

❌