DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Data

Data is at the core of software development. Think of it as information stored in anything from text documents and images to entire software programs, and these bits of information need to be processed, read, analyzed, stored, and transported throughout systems. In this Zone, you'll find resources covering the tools and strategies you need to handle data properly.

icon
Latest Premium Content
Trend Report
Data Engineering
Data Engineering
Refcard #269
Getting Started With Data Quality
Getting Started With Data Quality
Refcard #398
Open-Source Data Management Practices and Patterns
Open-Source Data Management Practices and Patterns

DZone's Featured Data Resources

Locking Down the Enterprise: Data Security Patterns for AI Integrations

Locking Down the Enterprise: Data Security Patterns for AI Integrations

By Balaji Venkatasubramaniyar DZone Core CORE
Every enterprise conversation about artificial intelligence eventually arrives at the same uncomfortable question: what happens to our data once it leaves our perimeter? Whether you are wiring a large language model into a claims processing pipeline, standing up a retrieval-augmented generation (RAG) system for internal knowledge search, or letting an agentic workflow take autonomous actions against production systems, the answer determines whether your AI initiative becomes a competitive advantage or a compliance incident waiting to happen. This article lays out a layered, defense-in-depth approach to securing enterprise data across the AI lifecycle — from data classification and access control, through transit and storage, vendor contracts, prompt hygiene, architecture patterns, and compliance mapping. It is written for architects, technical leads, and engineering managers who are past the "should we use AI" conversation and are now living in the "how do we do this safely at scale" reality. The guidance here is deliberately vendor-agnostic and framework-agnostic. The specific tools you choose — which cloud, which model provider, which vector database — will vary. The principles will not. 1. Why AI Changes the Data Security Calculus Traditional application security assumes a relatively closed loop: your code, your database, your network boundary. Data moves through defined pathways, and you can reason about every hop. AI systems break several of these assumptions at once. The boundary is porous by design. A large language model call is, functionally, an API request to a third party — even when that third party is a trusted enterprise vendor. Every prompt is an egress point. Every completion is an ingress point. Unlike a traditional API integration where the schema is fixed and the payload is structured, prompts are free text, which makes it far easier for sensitive data to slip in unnoticed. The system can be instructed by its input. In a conventional application, data and instructions are cleanly separated — SQL injection exists precisely because that separation sometimes breaks down, and we have spent two decades building defenses against it. In an AI system, the model's instructions and the data it processes often occupy the same channel: natural language. This is the root cause of prompt injection, and it means the data itself can become an attack vector, not just a target. The system can act, not just answer. Agentic AI — systems that call tools, write files, send emails, or modify records — collapses the distinction between "the AI leaked data" and "the AI did something harmful with data." A single compromised or manipulated agent can chain read access into write access, and write access into external communication, all within one interaction. The data footprint compounds. Vector embeddings, cached completions, fine-tuning datasets, evaluation logs, and conversation histories all represent new copies of your sensitive data, sitting in new places, governed by new retention rules that your existing DLP and archiving policies were never built to see. None of this means AI is unsafe to deploy in the enterprise. It means the security model has to be designed deliberately, layer by layer, rather than inherited by default from your existing application security posture. 2. Data Governance and Classification Everything downstream depends on getting this layer right first. If you don't know what data you have and how sensitive it is, no amount of encryption or access control will save you from sending the wrong thing to the wrong place. Classify Before You Integrate Before any AI system touches production data, classify it into tiers. A simple, workable scheme: Public – marketing content, published documentation, anything already externally visible.Internal – operational data with no direct regulatory exposure, but not meant for public release.Confidential – customer PII, employee data, financial figures, strategic plans.Restricted – regulated data categories: PHI under HIPAA, PCI cardholder data, biometric data, data covered by state insurance data security laws, or anything under a specific contractual non-disclosure obligation. Each tier should carry an explicit, written policy on whether and how it may be used with AI systems — including which AI systems (internal, VPC-isolated, or public API) and under what redaction or tokenization requirements. Data Minimization Is a Design Constraint, Not an Afterthought The single most effective control available to you is simply not sending data you don't need to send. This sounds obvious and is routinely ignored under deadline pressure. Practical patterns: Field-level scoping: If a prompt needs a claim status and adjuster name, don't serialize the entire claim record into context. Query for and pass only those fields.Row-level scoping in RAG: Retrieval pipelines should filter at the query layer (based on the requesting user's entitlements) before documents ever reach the context window, not rely on the model to "know" what it shouldn't discuss.Aggregate over raw where possible: If the use case is trend analysis, send aggregated statistics rather than the underlying raw records. Understand Retention and Training-Use Terms This is the question every enterprise security review should ask first, and the one most often skipped: does the AI provider retain my inputs and outputs, and are they used to train or improve models? Enterprise API tiers from major providers typically differ meaningfully from consumer-facing chat products on this point — enterprise agreements commonly include zero data retention (ZDR) options and explicit commitments that customer data is not used for model training. Consumer tiers, free tiers, and browser extensions are a different story and should be treated as such in your acceptable use policy. Don't assume; read the actual data processing terms for the specific tier and product you're using, and get it in writing. Data Lineage for AI-Touched Data Once data has passed through an AI system, it has effectively been transformed and potentially recombined. Maintain lineage records: which source systems fed which prompts, which model version processed them, and where the outputs were stored or acted upon. This becomes essential later for both incident response and regulatory audit. 3. Access Control for AI Systems Treat AI Service Accounts Like Any Other Privileged Identity An AI agent or pipeline that calls internal APIs is a service account. It should be provisioned, reviewed, and revoked exactly like any other service account — with the added scrutiny that its "instructions" can be influenced by untrusted input in ways a traditional service account's code path cannot. Least privilege, scoped by task: A customer-support chatbot that looks up order status needs read access to an orders API — not write access, not access to the full customer database, not admin scopes "just in case."Short-lived credentials: Prefer short-lived, automatically rotated tokens (OAuth client-credentials flows, workload identity federation) over long-lived static API keys.Per-tenant isolation: In multi-tenant SaaS or multi-client environments, ensure the AI system cannot cross tenant boundaries even if a prompt attempts to coax it into doing so — enforce this at the data access layer, not the prompt layer. Enforce Human Entitlements Downstream of the Model, Not Just Upstream A common and dangerous mistake: building a RAG or agentic system where the AI service account has broad access "for flexibility," and relying on the system prompt to tell the model which documents the current user is allowed to see. Prompts are not an access control mechanism. If the underlying retrieval or tool-calling layer can technically reach a document or record, a sufficiently motivated (or simply unlucky) input can potentially surface it. The correct pattern is to filter at the data layer using the actual requesting user's entitlements — row-level security in the database, document ACLs in the retrieval index, and scoped API tokens minted per-request based on the authenticated user, not the service account. Role-Based Access for AI Outputs Re-Entering the System When an agentic workflow's output writes back into production — updating a record, sending a notification, filing a claim note — that write should pass through the same RBAC and validation layer a human-initiated write would. Do not grant an AI agent a privileged bypass "because it's automated." Automation is exactly when you want the guardrails to be strongest, because there is no human in the loop to notice something is wrong before it happens. 4. Secrets and Credential Management This deserves its own section because AI systems introduce new and easy-to-miss places for secrets to leak. Never hardcode credentials in prompts, system prompts, or agent configuration files. It is tempting to embed an API key directly in a tool definition during a proof of concept. That habit does not survive contact with production.Never let secrets end up in agent memory or long-term conversation history. If your architecture includes persistent memory for an agent, explicitly exclude credential material, and audit what actually gets written to that memory store.Use a dedicated secrets manager — Azure Key Vault, AWS Secrets Manager, HashiCorp Vault, or your platform equivalent — and have the AI orchestration layer fetch credentials at call time rather than holding them statically.Rotate aggressively for anything touched by an AI pipeline. Given that prompts and tool definitions are more likely to be copy-pasted into documentation, shared in Slack for debugging, or logged verbosely during development, treat any credential that has been anywhere near an AI pipeline as higher-risk and rotate on a shorter cycle.Watch your logs. Verbose request/response logging — common during AI development for debugging prompts — is a frequent, unglamorous source of credential leakage. Redact before logging, not after. 5. Data in Transit and at Rest The fundamentals here are not AI-specific, but they are easy to underinvest in because AI integrations often move fast and get treated as "just another API call." TLS everywhere, including between internal orchestration services and the AI provider, and between internal services and any vector database or cache.Encrypt at rest, including: The primary data stores feeding your RAG pipeline.Vector embeddings themselves. Embeddings are not inherently anonymous — depending on the embedding model and dimensionality, source text can sometimes be partially reconstructed from vectors, so treat an embedding store with the same sensitivity as the source documents.Prompt and completion logs.Any cached responses (semantic caching layers are increasingly common for cost control and latency, and they represent another copy of potentially sensitive data at rest).Encrypt backups of all of the above, and include them explicitly in your data retention and destruction policies — a backup snapshot of a vector database is a backup of your confidential documents. 6. Vendor and Contractual Controls Technical controls only get you so far if the underlying contract with your AI provider doesn't back them up. Zero Data Retention Agreements Where available, negotiate zero data retention (ZDR) terms — an explicit commitment that request payloads are not retained beyond the time needed to serve the response, and are not logged, cached, or used for any secondary purpose. This is increasingly available as a contractual option from major enterprise AI providers and should be a standard line item in procurement for any AI vendor touching confidential or restricted data. Data Processing Agreements A proper Data Processing Agreement (DPA) should cover: Purpose limitation (data used only to provide the contracted service).Sub-processor disclosure (who else touches your data downstream of the primary vendor).Data residency commitments (does data ever leave a specific geographic or regulatory jurisdiction).Breach notification timelines.Audit rights. Enterprise Tier Versus Consumer/Shared Infrastructure Confirm explicitly whether you are on infrastructure that is logically or physically isolated from other customers, versus a shared multi-tenant consumer product. Ask directly: is my data ever used to train models that serve other customers? Is there any possibility of cross-tenant data mixing in caching or logging layers? Get the answer in the contract, not just in a sales conversation. Vendor Security Posture Review Standard vendor risk management practice applies, but with AI-specific questions added to the questionnaire: What is the model provider's own subprocessor chain?How is prompt injection or jailbreak resistance tested and monitored on their side?What certifications do they hold (SOC 2 Type II, ISO 27001, ISO 42001 for AI management systems specifically)?What is their incident response commitment and SLA for a security event affecting your data? 7. Prompt and Output Hygiene Treat Untrusted Content as Untrusted, Even Inside a Prompt Prompt injection is the AI-era equivalent of injection attacks in traditional application security, and it deserves the same rigor. Any content that originates outside your organization's direct control — an email, an uploaded document, a web page fetched by a tool, a third-party API response — should be treated as untrusted input, not as trusted instructions, even when it is concatenated into the same prompt as your system instructions. Practical mitigations: Clear structural separation between system instructions, trusted context, and untrusted content, using explicit delimiters and, where the platform supports it, distinct message roles.Instruction-following boundaries: Explicitly instruct the model that content within untrusted blocks should be treated as data to analyze, not as commands to follow — and validate this behavior in testing with adversarial inputs, not just happy-path examples.Least-privilege tool access during untrusted content processing: If an agent is currently processing an untrusted document, don't give it simultaneous access to high-privilege tools (sending email, executing code, modifying records) without a human confirmation step in between. Output Validation Before Action Any AI output that will be displayed to a user, stored in a system of record, or used to trigger a downstream action should pass through validation: Schema validation for structured outputs (if you asked for JSON, validate it actually conforms before using it).PII/sensitive-data scanning on outputs, not just inputs — a model can sometimes surface data it was never explicitly asked to reveal, particularly in RAG systems with imperfect retrieval filtering.Action confirmation gates for anything irreversible or high-impact — sending external communications, financial transactions, deleting records — even in a fully agentic workflow. A "dry run" or human-approval step for a defined set of high-risk action types is a small latency cost for a large risk reduction. PII Redaction Pipelines For any workload where the AI system doesn't strictly need to see PII to do its job, run a redaction or tokenization pass before the data reaches the prompt, and a re-hydration pass on the output if needed. This is particularly relevant when using third-party or shared-infrastructure LLM endpoints for tasks like summarization or classification, where the specific identity behind the data is often irrelevant to the task itself. More
How to Prevent Retry Storms With Retry Budgets in Distributed Systems

How to Prevent Retry Storms With Retry Budgets in Distributed Systems

By Uthej Mopathi DZone Core CORE
Retries are one of the simplest ways to make a distributed system appear more reliable. A transient connection failure, overloaded replica, or short-lived network interruption can disappear after another attempt, which is why retry support exists in major RPC frameworks and cloud SDKs. The danger begins when every layer makes the same decision independently. A mobile client retries an API gateway, the gateway retries a service, that service retries another service, and the final dependency retries a database call. The original request has not become more important, but the system has multiplied the work required to fail. AWS describes a five-deep service stack in which three attempts at each layer can drive 243 calls against the database when the deepest dependency is failing. Google’s SRE guidance similarly warns that retries can amplify overload and contribute to cascading failure. When Reliability Logic Becomes Additional Load The common retry policy focuses on a single caller. A request fails, exponential backoff delays the next attempt, and jitter prevents large client populations from retrying at exactly the same instant. Those mechanisms remain important. AWS recommends backoff and jitter because immediate, synchronized retries can worsen overload, while gRPC exposes retry limits, exponential backoff, retry throttling, and server pushback for the same class of problem. The missing property is coordination. Consider three logical layers, each configured for three total attempts. If the lowest dependency rejects every request, a single logical operation can create up to 27 downstream attempts. Adding more independently retrying layers increases that multiplier exponentially. Backoff changes when those attempts arrive; it does not change the fact that separate components are authorizing additional work from the same original operation. A typical Spring service can accidentally create this behavior with perfectly reasonable local configuration: Java @Retry(name = "paymentService", fallbackMethod = "paymentFailed") public PaymentResult charge(PaymentRequest request) { return paymentClient.charge(request); } private PaymentResult paymentFailed(PaymentRequest request, Exception ex) { throw new PaymentUnavailableException(ex); } Nothing in this method indicates whether the incoming request has already consumed retries elsewhere. A gateway may already have retried the service, and paymentClient may apply another retry policy. Local resilience therefore becomes global amplification. A Retry Budget Changes the Decision A retry budget treats retries as limited capacity rather than an unconditional reaction to failure. Google documents two complementary controls in its overload handling: a per-request cap of three attempts and a per-client budget that permits retries only while retries remain below 10% of request traffic. In the example described by Google, the per-client budget reduces retry-driven traffic growth from almost three times the original request rate to roughly 1.1 times under the modeled overload condition. Finagle applies the same general idea through a shared RetryBudget, explicitly describing the budget as protection against the amplifying effect of many clients retrying. For a service chain, the useful abstraction is a request-scoped budget propagated with the operation. An internal header such as X-Retry-Budget can represent remaining retry permits. The header is an application convention rather than a standard HTTP field, its purpose is to ensure that downstream components consume from the same finite allowance. The retry decision can then become explicit: Java boolean canRetry(int remaining, HttpStatusCode status) { return remaining > 0 && (status.value() == 429 || status.is5xxServerError()); } int nextBudget(int remaining) { return Math.max(0, remaining - 1); } A caller starts a logical operation with a small budget, such as two retry permits. Every additional attempt decrements the value before forwarding the request. A downstream service receiving zero can still return a meaningful failure, but it cannot create more retry traffic for that logical operation. This model should not make every 5xx automatically retryable. Retry classification still matters. Validation failures, deterministic application errors, and non-idempotent operations can be unsafe or pointless to repeat. AWS recommends idempotent API contracts when operations may be retried and describes caller-provided request identifiers as a way to recognize duplicate intent. Propagating One Budget Across Service Boundaries Budget propagation belongs close to outbound transport logic so business methods do not manually manipulate retry metadata. A Spring interceptor can read the current budget and attach the decremented value to the next attempt: Java int remaining = retryContext.remaining(); if (remaining <= 0) { throw new RetryBudgetExhaustedException(); } request.getHeaders().set( "X-Retry-Budget", Integer.toString(remaining - 1) ); return execution.execute(request, body); The receiving service extracts the header once and places the value in the request context. Internal HTTP clients and RPC adapters then share that context. This is conceptually similar to distributed context propagation used by tracing systems. OpenTelemetry propagators inject and extract cross-cutting context through carriers such as HTTP headers, although retry-budget metadata can remain a dedicated internal header rather than telemetry baggage. A budget also needs to cooperate with deadlines. A remaining retry permit is useless when the logical request has only a few milliseconds left. Retry authorization should therefore require both budget and time: Java boolean retryAllowed(RetryContext context) { return context.remaining() > 0 && context.deadline().isAfter(Instant.now().plusMillis(100)) && context.lastFailure().isTransient(); } Server feedback should override generic retry enthusiasm. HTTP defines Retry-After so a service can indicate when a follow-up request should occur, including with 503 Service Unavailable, 429 Too Many Requests can also carry Retry-After. A budget answers whether another attempt is permitted, while server feedback helps decide when that attempt is appropriate. Measuring Whether the Budget Is Working Retry budgets are control mechanisms, so observability must expose both logical requests and physical attempts. Finagle distinguishes logical success from individual attempts and publishes metrics for retry budget availability, exhaustion, and request retry limits. Without that separation, retries can hide dependency instability because a successful second attempt makes the logical request appear healthy while infrastructure performs additional work. Useful telemetry should record the initial request count, retry attempt count, budget exhaustion count, retry success rate, response classification, remaining budget, and end-to-end latency. The critical ratio is retry amplification, which is total physical attempts divided by logical requests. A healthy value depends on workload characteristics, but a sharp increase during an incident indicates that resilience logic is becoming a load. Tracing adds the missing causal view. Each attempt can remain a child span of the same logical operation, with attributes such as retry.attempt, retry.remaining, and retry.reason. The resulting trace shows whether an operation failed because a dependency was unavailable, because the deadline expired, or because the shared budget prevented another attempt. That distinction is operationally important as budget exhaustion is often evidence that the system deliberately stopped adding pressure rather than evidence that the retry mechanism malfunctioned. Retry metrics also need to be interpreted alongside service saturation and rejection rates. A rising retry-success rate may initially indicate useful recovery from transient faults, but rising attempt volume combined with increasing backend saturation indicates a different condition. At that point, preserving capacity can be more valuable than pursuing another successful attempt. Google’s overload guidance explicitly recommends allowing failures to propagate when widespread backend overload makes additional retries unlikely to help. Conclusion Retries remain essential for transient failures, but retries without coordination can turn a partial outage into a traffic multiplier. Backoff, jitter, idempotency, deadlines, and server pushback address important parts of the problem that a retry budget adds the missing global constraint by limiting how much extra work one logical operation may create. Propagating that budget across service boundaries converts retry behavior from isolated local policy into distributed load control. The strongest resilience policy is therefore not “retry until success,” but “retry only while the failure is transient, the operation is safe, time remains, and the system can afford another attempt.” More
Exploring the DBMS_DEVELOPER Package: JSON Metadata for Oracle Objects
Exploring the DBMS_DEVELOPER Package: JSON Metadata for Oracle Objects
By arvind toorpu DZone Core CORE
RAG, Vector Databases, and MCP: Wiring Them Together for Production
RAG, Vector Databases, and MCP: Wiring Them Together for Production
By Balaji Venkatasubramaniyar DZone Core CORE
Common Pitfalls in RAG Applications: What to Avoid When Using Vector Search and Embeddings
Common Pitfalls in RAG Applications: What to Avoid When Using Vector Search and Embeddings
By Seshendranath Balla Venkata
Why Real-Time Data Pipelines Are Becoming the Foundation of Industrial AI
Why Real-Time Data Pipelines Are Becoming the Foundation of Industrial AI

I spent the first six months of a project convinced we had a model quality problem. Our anomaly detection system for manufacturing telemetry was missing obvious defects; things a human operator would catch in seconds. We tried bigger models, better embeddings, more training data. Nothing moved the needle. Then one afternoon, while tracing a specific false negative, I noticed the timestamp. The sensor reading that would have triggered a correct alert had arrived 47 seconds after the decision window closed. The model never saw it. Not because the model was bad. Because the pipeline delivered the data too late for the model to act on it. That's when I stopped thinking about model architecture and started obsessing over data delivery. And honestly, everything I've built since has been shaped by a simple realization: in industrial AI, the pipeline IS the product. The model is just the last mile. How Generative AI Changed the Conversation (But Not the Bottleneck) Everyone's building AI assistants, intelligent search, predictive analytics, autonomous workflows. The conversation focuses on foundation models, prompt engineering, inference optimization. Makes sense; that's the exciting part. But in industrial environments (semiconductor fabs, energy plants, discrete manufacturing), the bottleneck isn't model capability. It's whether the right data reaches the model at the right time, in the right shape, with the right lineage attached. I've watched teams spend months fine-tuning a model that was getting stale sensor readings. Months. The model was perfectly capable. It was just blind. This is why I've come to believe that industrial AI success is a data architecture problem first and a model problem second. The reason is not because models don't matter. Instead, it is because a brilliant model on bad plumbing produces confidently wrong answers, which is worse than no answer at all. What Semiconductor Fabs Taught Me About "Real-Time" Here's where my background in semiconductor manufacturing gives me a perspective most streaming architects don't have. In a modern fab (say, a 300mm facility running at 5nm or 3nm process nodes), a single wafer passes through 500+ process steps. Each step generates telemetry: gas flow rates, chamber pressure, plasma power, temperature profiles, film thickness measurements, overlay alignment data. Multiply that by 50 wafers per lot, dozens of lots per day, and you're looking at billions of data points daily. The fab doesn't batch-process this data overnight. It can't. A wafer worth $10,000+ is moving through the line continuously. If a process parameter drifts out of spec and you don't catch it until the nightly ETL job runs, you've potentially scrapped an entire lot. That's half a million dollars gone because your pipeline was "fast enough for batch." Fabs solved this decades ago with a discipline called Fault Detection and Classification (FDC). Every equipment run is analyzed in real-time (within milliseconds of completion). Statistical models compare current sensor traces against known-good profiles. If something looks off, the system raises an alarm before the next wafer enters the chamber. This isn't some exotic research concept. It's running in every leading-edge fab on the planet right now. And the architecture behind it looks remarkably like what we're trying to build in enterprise streaming: FAB FDC ARCHITECTUREenterprise streaming equivalent Equipment sensor streams (SECS/GEM protocol) Apache Kafka / Apache Flink event streams Real-time trace comparison Stream processing with windowed aggregations SPC control charts with Western Electric rules Anomaly detection on feature pipelines Recipe parameter adjustment (APC) Automated model retraining triggers Lot genealogy / WIP tracking Data lineage and event provenance The patterns are the same. The fab version just had higher stakes, forcing better discipline earlier. Why Streaming Isn't "Faster Batch." It's a Different Mental Model. This distinction tripped me up for a while. I kept thinking of streaming as "batch that runs every second instead of every hour." That's wrong, and it leads to bad architecture. Batch assumes data is static until the next scheduled update. You collect, then process, then serve. Streaming assumes data is continuously evolving. Events flow through the platform as they occur. Applications subscribe and react while the underlying process is still unfolding. The practical difference is enormous: Batch thinking: "We'll retrain the model on last night's snapshot." Result: the model is always 8-24 hours behind reality. In a manufacturing context, that's thousands of wafers processed with stale parameters. Streaming thinking: "The feature pipeline receives fresh observations as events arrive." Result: the model's context is minutes old, not hours. Decisions happen while outcomes can still be influenced. Apache Kafka, Apache Flink, and event-driven frameworks like Apache Pulsar make this architecturally possible today. The tooling has matured. The question isn't whether streaming works; it's whether your organization has made the mental shift from "collect then analyze" to "analyze as it flows." The Hidden Engineering Nobody Wants to Talk About Building industrial AI involves way more plumbing than anyone admits during the planning phase. Behind every successful deployment lies a data platform responsible for ingesting, validating, enriching, governing, and distributing information from dozens of independent systems. In manufacturing environments specifically: Equipment comes from multiple vendors (Applied Materials, Lam Research, Tokyo Electron; each with different telemetry formats).Sampling frequencies vary wildly (100ms for some sensors, 1Hz for others, event-based for yet others).Some systems generate structured events while others produce semi-structured logs.Data quality fluctuates depending on operating conditions (a chamber during maintenance produces garbage telemetry that looks like anomalies to a naive model). Before AI can analyze any of this, the platform must reconcile these inconsistencies into a unified representation. Schema registry (Confluent Schema Registry, Apicurio), data quality frameworks (Great Expectations, dbt tests), and format standardization (Apache Avro, Protocol Buffers) do this work. It's unglamorous. Nobody writes blog posts about schema reconciliation. But I've seen more AI projects die from bad plumbing than from bad models. The ratio isn't even close. Why Data Governance Isn't Compliance Anymore. It's Model Quality. This shift snuck up on me. I used to think of governance as something the compliance team worried about: data classification, retention policies, access controls. Important, but not my problem as an architect. Then I watched a machine learning model produce wildly inconsistent predictions because it was consuming two different versions of the same feature; one from the real-time pipeline (current) and one from a batch backfill (stale). No governance framework flagged this because nobody had defined "which version should the model use?" as a governance question. In industrial AI, governance questions become engineering questions: Where did this data originate? (Lineage: Apache Atlas, OpenLineage)Has it been validated? (Quality gates in the pipeline itself.)Which version should the model use? (Catalog: Apache Iceberg's time-travel, Delta Lake's versioning.)Can this information cross regional boundaries? (Compliance-as-code in the streaming layer.) The strongest architectures I've seen integrate governance directly into the event pipeline. Metadata travels with data. Access policies apply at the stream level. Lineage is preserved through every transformation. Not as a separate process; as part of the infrastructure itself. Why RAG Quality Is a Pipeline Problem (Not a Prompt Problem) Retrieval-augmented generation has become the default architecture for enterprise GenAI. Makes sense; you ground the language model in your proprietary knowledge rather than relying solely on its training data. But here's what I keep seeing: teams spend weeks optimizing prompts and chunking strategies while their knowledge base quietly goes stale. Documents update, but embeddings don't re-index. Permissions change, but the retrieval layer doesn't reflect them. Metadata drifts from reality. The language model still generates fluent responses. They're just increasingly grounded in yesterday's (or last month's) context. RAG quality, in my experience, depends more on the freshness and accuracy of the retrieval pipeline than on the generation model sitting on top. A well-maintained knowledge pipeline with a mid-tier model outperforms a frontier model drinking from a stale index. This means treating your RAG pipeline like a streaming system: continuous ingestion, continuous re-indexing, continuous validation. Not a one-time "load the docs and forget." Building for Scale Without Burning Money Industrial AI platforms process enormous event volumes. Millions of messages per minute. Thousands of assets generating telemetry simultaneously. Multiple AI services consuming overlapping datasets. Scaling this naively (just add more brokers, more compute, more storage) gets expensive fast. What I've found works better: Process at the edge when possible. In semiconductor manufacturing, FDC analysis often runs on edge compute at the equipment level (15ms response time vs 800ms round-trip to a centralized system). The same principle applies to any industrial streaming architecture: if the decision can be made locally, don't pay the latency and cost of a centralized round-trip. Tiered storage with hot/warm/cold patterns. Real-time features stay in low-latency stores (Redis, Apache Druid). Recent history lives in columnar formats (Apache Parquet on object storage). Deep history moves to cold archives. Apache Iceberg handles this elegantly with its metadata layer. Backpressure instead of over-provisioning. Rather than provisioning for peak load 24/7, build systems that gracefully handle bursts through buffering and backpressure mechanisms. Kafka's consumer group model does this naturally when configured properly. Observability across the entire pipeline. Not just the model; the pipeline itself. OpenTelemetry for tracing, Prometheus for metrics, distributed tracing that follows an event from sensor to prediction. When something goes wrong (and it will), you need to know where the failure point is in seconds, not hours. What I'd Tell Myself Two Years Ago If I could go back to the start of that project where we spent six months blaming the model: 1. Instrument the pipeline first. Before deploying any model, measure data freshness at every stage. Know exactly how old your model's context is at inference time. If it's stale, the model doesn't matter yet. 2. Treat streaming as a prerequisite, not an optimization. For industrial AI that needs to influence real-time outcomes, batch architectures aren't "good enough for now." They're architecturally incompatible with the goal. 3. Invest in schema discipline early. It's painful and boring. It pays for itself within months. Every team I've talked to that skipped this step regretted it when they tried to add a second or third data source. 4. Governance is architecture, not documentation. If governance policies don't enforce themselves automatically in the pipeline, they don't exist in practice. They're just PDFs nobody reads. 5. The pipeline IS the AI product. The model is important but replaceable. The data infrastructure that feeds it is the durable competitive advantage. Invest accordingly. Industrial AI is maturing quickly. The teams shipping reliable systems aren't the ones with the best models. They're the ones with the best plumbing. And honestly, that's encouraging because plumbing is engineering, and engineering is what we do. I'd love to hear what's worked (or spectacularly failed) in your streaming architectures for AI. The patterns are still emerging, and I think the best ideas are coming from practitioners who've felt the pain firsthand.

By Ajay Kumar Govindaram
Architecting Production AI Across Clouds: Patterns That Decide System Survival
Architecting Production AI Across Clouds: Patterns That Decide System Survival

Most enterprise AI post-mortems do not blame the model. They blame the storage tier that starved the accelerators, the identity policy that over-granted access, the cost model that ignored egress, the forecast that leaked future data, or the region that failed and took a business process with it. The hard part of production AI was never intelligence. It was the engineering discipline around it. This article distills the architectural patterns that decide whether a cloud AI system is trustworthy at scale, spanning infrastructure, identity, cost, operations, the applied domains, low-code assembly, platform selection, and multi-cloud resilience. It is written for engineers who have to keep these systems running, not for a keynote. Infrastructure: The Interconnect Is the Bottleneck Distributed training is a systems problem before it is a machine learning problem. When a job spans many graphics processing units (GPUs), the fabric connecting them (e.g., NVLink within a node, InfiniBand, or a vendor fabric across nodes) frequently caps throughput more than raw compute does. Accelerators wired through an ordinary network idle while they wait to synchronize gradients. Storage is the symmetric constraint. If the file system cannot deliver data at the rate the accelerators consume it, utilization collapses. The pattern is a tiered design: Hot tier: parallel or block storage feeding active training at high input/output operations per second (IOPS).Warm tier: recent data staged for quick promotion.Durable lake: object storage providing petabyte-scale durability, partitioned and lifecycle-managed underneath. Two cost drivers hide from the pricing page: data egress (moving data across regions or out of a provider) and idle warm capacity. Optimizing only the advertised compute line item guarantees a surprise on the invoice. Identity Is the Perimeter In a service-to-service AI architecture, the network perimeter is gone; identity is the boundary. A zero-trust posture, where every request authenticates and receives least privilege, contains the blast radius when a component is compromised. Across providers, identity federation is the load-bearing pattern: a principal authenticates once and is recognized everywhere, so access is granted and revoked centrally instead of reconciled across three identity systems. Policy must travel with the workload; a rule enforced on one cloud and forgotten on another is not a policy. Model authorization is the emerging frontier. As models call tools and take actions, the question moves from who can query this model to what may this model do on a user's behalf. Least privilege applied to an autonomous agent is the boundary between useful and unbounded. Cost and Operations Are a Control Loop Cost management is not a spreadsheet; it is automation. Consistent resource tagging across every cloud is the prerequisite for attribution. On top sit budgets, alerts, and automated remediation that throttles runaway spend before it escalates. Site reliability engineering (SRE) supplies measurable targets. For AI workloads, the golden signals extend beyond latency and errors to accelerator utilization, queue depth, and prediction quality. A model can be fully available and quietly wrong, so define a service level objective (SLO) for output quality, not just uptime. Three techniques earn their complexity: Spot or preemptible capacity plus checkpointing cuts training cost sharply when jobs resume cleanly after reclamation.Predictive scaling anticipates load instead of reacting to it.LLM inference optimization becomes architectural: batch requests, cache frequent responses, route easy queries to smaller models, reserve the expensive model for queries that need it. The Applied Domains Share a Spine, Differ in Physics Vision is byte-heavy. High-resolution images and video streams make the data and network layers dominant. For real-time video, decouple frame capture from analysis and sample frames rather than processing every one. Critically, a business-rule layer, never the model alone, owns consequential decisions. Every extraction should carry a confidence score used as a routing gate: Python def route_extraction(field, threshold=0.90): if field["confidence"] >= threshold: return "auto_process" return "human_review" Language is byte-light but semantically treacherous, and because it replies directly to users, errors are visible. The defining risk of generative systems is hallucination. The strongest architectural defense is retrieval grounding, forcing answers from verified sources with citations: Python def answer(question, knowledge_base): passages = knowledge_base.search(question, top_k=3) context = "\n".join(p.text for p in passages) prompt = f"Answer using ONLY this context.\n{context}\n\nQ: {question}" return model.generate(prompt), [p.source for p in passages] Forecasting is defined by time order. You cannot shuffle a time series into random splits, and the most common failure is data leakage, using information unavailable at prediction time. Test on a fair, time-ordered holdout, and always emit a prediction interval; a point forecast that hides its uncertainty invites overconfident decisions. No-Code and Low-Code: Governed or Ungoverned No-code and low-code platforms collapse build cost from a scoped project to an afternoon, which is why adoption is exploding. The symmetric risk is sprawl: hundreds of ungoverned flows handling sensitive data, owned by no one. Govern with guardrails, not gates. Restrict which connectors and data sources are permitted, assign an owner and an SLO to every production flow, then let builders move freely inside the boundary. The goal is to make the safe path the easy path. Platform Selection Without Self-Deception Vendors all claim to be fastest, cheapest, and most reliable. Benchmark to replace claims with evidence: Latency: report percentiles (p95, p99), never averages that hide the slow tail.Quality: measure on your own representative data, not a public leaderboard.Cost: model total cost of ownership, including transfer, storage, idle capacity, operations, and migration, not the headline compute rate.Reliability: verify the platform meets your recovery time objective (RTO) and recovery point objective (RPO). Combine dimensions in a weighted scorecard whose weights are fixed before scores are seen. Adjusting weights afterward to crown a favorite converts analysis into rationalization. Multi-Cloud Resilience: Design for the Day a Cloud Fails For systems a business cannot lose, a single provider is a gamble. Multi-cloud resilience deliberately places critical workloads so no single provider failure takes the business down, applied only where the cost of failure exceeds the cost of prevention. Predict rather than react. Combine leading signals into a health score and fail over proactively: Python def health_score(latency_ms, error_rate, saturation): latency_factor = max(0, 1 - (latency_ms / 1000)) error_factor = max(0, 1 - (error_rate / 0.05)) saturation_factor = max(0, 1 - saturation) return round(0.4*latency_factor + 0.4*error_factor + 0.2*saturation_factor, 3) Kubernetes makes workloads portable; data replication (with the consistency-versus-availability trade-off decided per workload) keeps data ready on the other side; and a portable foundation of federated identity, uniform policy, and centralized monitoring makes failover routine rather than heroic. The discipline that separates real resilience from a slide deck is rehearsing failure on purpose. An untested failover path is a promise, not a capability. The Judgment Layer Across every layer, value came not from the most powerful component but from the judgment applied to it: matching effort to problem difficulty, keeping humans on consequential decisions, measuring before deciding, building governance in early, and designing for change. Tools will churn; foundation models will make today's designs look quaint. That is precisely why principles outlast product knowledge. The scarce resource in enterprise AI was never intelligence. It was judgment, and judgment does not ship from the cloud.

By VenkataSrinivas Kantamneni
Freshness Is the Missing SLO in Production Vector Search
Freshness Is the Missing SLO in Production Vector Search

The Index Can Be Fast and Still Be Wrong Vector search teams usually define performance with query latency, recall, and throughput. Those measures matter, but they can all look healthy while the system returns a stale version of a document that changed minutes ago. The index is fast. The answer is still wrong. This failure is easy to miss because a vector index is normally downstream from the source of truth. Between a database write and a searchable embedding sit event capture, transport, chunking, model inference, index mutation, and cache invalidation. Freshness is the end-to-end property produced by that entire chain. Freshness Needs a Contract Saying that updates are processed quickly is not a contract. A useful freshness SLO states which source version must be searchable, how long the pipeline may lag, and what the query path should do when that guarantee cannot be met. For example, a service might require 99 percent of committed updates to become searchable within 60 seconds, while deletes must disappear within 10 seconds. The distinction matters because showing old text is inconvenient, but returning deleted or access-revoked content can become a security incident. Capture the Write Without a Dual-Write Gap The first failure appears when application code writes the business row and publishes an indexing event as two separate operations. If the database commit succeeds and the publish fails, the source changes without any durable instruction to update the index. Retrying the request does not reliably repair that gap. A transactional outbox avoids the split. The application updates the entity and inserts an outbox record in the same database transaction. A change-data-capture process then publishes the outbox record asynchronously. SQL BEGIN; UPDATE documents SET body = :body, version = version + 1 WHERE id = :id; INSERT INTO embedding_outbox (event_id, entity_id, source_version, operation) SELECT :event_id, id, version, 'UPSERT' FROM documents WHERE id = :id; COMMIT; Make Every Event Versioned and Idempotent Delivery systems retry. Partitions rebalance, workers crash after writing but before acknowledging, and older events can arrive after newer ones. The index consumer must therefore treat duplicate and out-of-order delivery as normal behavior, not an edge case. Each event should carry an immutable event identifier, entity identifier, monotonic source version, operation, and payload reference or hash. The consumer applies a mutation only when the incoming version is newer than the indexed version. That compare-and-set must be atomic in the index or in a strongly consistent metadata store beside it. Python def apply(event, index, embed): current = index.metadata(event.entity_id) if current and current.source_version >= event.source_version: return "already_applied" if event.operation == "DELETE": index.delete_if_newer(event.entity_id, event.source_version) return "deleted" vector = embed(event.content) index.upsert_if_newer( id=event.entity_id, vector=vector, metadata={"source_version": event.source_version} ) return "updated" Deletes Are First-Class Data Upserts get most of the design attention because they create embeddings. Deletes are more dangerous because there is no new content to process. A delete event must survive the same durable path and carry a version that prevents an older upsert from resurrecting the record later. Keep tombstones long enough to cover the maximum replay and recovery window. If a full rebuild reads a snapshot taken before a delete, the rebuild process must also consume the change stream from the snapshot position forward. Otherwise, the old record can quietly return when the new index is promoted. Model Versions Belong in the Index Schema Fresh source data can still be semantically stale when query and document vectors were created by different embedding models. Store the embedding model identifier, chunking configuration version, and normalization settings with every indexed item. Treat those fields as part of the index schema. A model upgrade should normally create a new physical or logical index generation. Dual-write new updates, backfill historical content, validate retrieval quality, then switch query traffic. Mixing vectors from incompatible spaces in one collection creates a failure that looks like weak relevance but cannot be tuned away. Use Watermarks to Measure What the Pipeline Has Proven A queue-depth metric shows workload, not freshness. The more useful signal is a source-position watermark: the highest committed database position or entity version that the searchable index has fully applied. Compare that watermark with the source head to measure version lag and event-time lag. Parallel consumers complicate this because one partition can race ahead while another is stuck. The global searchable watermark is bounded by the slowest required partition. Reporting the fastest worker hides exactly the stale slice users are likely to hit. Guard Queries When Freshness Matters Some requests know the minimum version they require. A write API can return the committed source version, and a later search request can send that version as a read-your-writes token. The query layer then checks whether the relevant index watermark has caught up. The fallback depends on the product. The service can wait briefly, route to a fresher generation, perform a source-of-truth lookup, or return a clear retryable status. Serving an older result without saying so should not be the default. Python def search(query, minimum_version=None): if minimum_version is not None: if index_watermark() < minimum_version: raise RetryableFreshnessError( "search index has not reached the required version" ) return vector_index.search(query) Rebuild Without Creating a Freshness Blackout Large indexes eventually need rebuilding because schemas, models, or partition layouts change. A safe rebuild uses a snapshot plus a change-stream handoff. Record the snapshot position, bulk-load the snapshot into a new generation, replay every later event, and promote only after its watermark reaches the live index. The promotion itself should be an atomic alias or routing change. Keep the previous generation available for rollback until both correctness and latency checks pass. A rebuild is not complete when bulk loading ends. It is complete when the new generation proves that no committed change was skipped. Operate Freshness Like Availability The dashboard should track source-to-index lag percentiles, oldest unapplied event age, consumer retry rate, dead-letter volume, version conflicts, delete lag, model-version distribution, and watermark gaps by partition. Alerts should be tied to the freshness SLO rather than to queue depth alone. Periodic reconciliation closes the final gap. Sample source entities, compare their versions and hashes with indexed metadata, and repair mismatches through the normal event path. The goal is not to pretend delivery is perfect. The goal is to make drift observable, bounded, and repairable. Test Failure Modes Before Launch Also test partial degradation. If one embedding worker pool is unavailable, confirm that lag remains visible and query guards behave as designed. If the dead-letter path fills, verify that alerts fire before the SLO is exhausted. These exercises turn recovery assumptions into executable evidence and reveal whether the pipeline can repair itself without manual database edits. Freshness behavior deserves fault-injection tests, not only happy-path integration tests. Pause one consumer partition, duplicate a batch, deliver versions out of order, fail an embedding call after the index write, and replay a snapshot across a recent delete. Each test should assert the final indexed version, not merely that the worker returned success. The Missing SLO Production vector search is a replicated data system with expensive transformation in the middle. Once that is clear, familiar distributed-systems rules apply: capture changes durably, version every mutation, make consumers idempotent, preserve deletes, expose watermarks, and rebuild from a known log position. Latency tells you how quickly the index answered. Freshness tells you whether it answered from the world that exists now. A production search system needs both guarantees, because a fast answer from yesterday is still a failure. References Debezium Outbox Event RouterPostgreSQL Logical Decoding ConceptsApache Flink Timely Stream Processing and Watermarks

By Guru Hegde
KV Cache vs Prompt Cache: What's the Difference, and How Are They Related?
KV Cache vs Prompt Cache: What's the Difference, and How Are They Related?

This article was originally published on my blog. For the latest version and future updates, please visit the original post: https://jaketao.com/language/en/kv-cache-vs-prompt-cache/. Every time a large language model generates a token, it draws on the content that came before it. If it had to compute everything from scratch at every step, responses would be much slower. When building an agent, the same set of system prompts, tool definitions, and conversation history is used over and over again. If these were reprocessed each time, latency and computational costs would continually increase. These two types of redundant computation correspond to two concepts that are often confused: the KV cache and the prompt cache. A model’s processing of a single request is usually split into two stages: prefill and decode. The KV cache stops the system from redoing the work on historical token K/V pairs during decoding, and the prompt cache lets later requests reuse the same prefix. In short, the KV cache is the underlying state and inference mechanism. The prompt cache is a strategy or product capability that reuses preprocessing results across requests. Many prompt cache implementations rely on reusing precomputed K/V states. Tip for reading: This text is going to talk about Q, K, V, prefill, decode, prefix matching, and cache breakpoints (also called cache boundaries). You don’t need to know anything about math or APIs to understand this article. When you’re reading, first think of Q, K, and V as “intermediate vectors” in attention calculations. Then, follow along with the two examples: “Beijing weather” and “product manual.” KV Cache: “Intermediate Results” During Model Generation Large models generate content token by token. Whenever a new token is generated, the model has to consider the tokens that have already appeared. For example, in a standard Transformer, each token makes three sets of vectors  —  Q, K, and V  —  at every layer. You can think of Q as “what I’m looking for,” K as “what I have here,” and V as “what information I should extract if I’m selected.” In autoregressive decoding, the Q values of historical tokens aren’t reused in subsequent steps. However, their K and V values are repeatedly queried by tokens generated later. So, the model stores these K and V values  —  this is the KV cache. For example, if you were to ask, “What’s the weather like in Beijing?” During the prefill phase, the model processes the whole question and stores the K and V values for each token at every layer. Once the decoding phase starts, new Q, K, and V values are calculated only for the token just added to the sequence at each step. The model combines the current K and V with the cached history, then performs attention calculations using the current Q on both the historical and current K and V to predict the next token. This way, you won’t have to keep recalculating the K and V of historical tokens. But that doesn’t mean long context is free. For standard full-attention models, the longer the context, the more video memory the KV cache uses, and the more historical K/V pairs usually need to be read at each step. So, long conversations might still feel slow. Attention structures like sliding windows limit the history that can be seen. The KV cache is usually managed by the inference engine, and application developers rarely interact with it directly. It’s mostly used for incremental decoding within a single generation, but the cached K/V state can also be used by the inference framework for cross-request prefix reuse. The latter is often called a prompt cache or prefix cache. Prompt Cache: Eliminating Redundant Processing of Identical Prefixes When people hear the term “cache,” many immediately think of an “output cache,” where a previously answered question is simply returned. But the prompt cache isn’t the same kind of output cache. Even if there’s a cache hit, the model will still regenerate the response. The prompt cache reuses intermediate results from the prefill phase for prompt prefixes, such as K/V states or other similar preprocessing results. A cache hit reduces redundant prefill computations and shortens the delay for the first token. If the API provider charges for cached inputs, it can also lower the cost of repeated inputs. For example, let’s say you give the model a 50-page product manual and ask: Plain Text Product manual → What's the warranty period? A bit later, you ask another question based on the same manual: Plain Text Product manual → What are the requirements for returning an item? The product manual used in both requests is identical, except for the last question. If this common prefix is cached, the second request can reuse the preprocessed results associated with the manual and process only the new question that follows. On the other hand, if you only use this manual once, prompt cache might not be that helpful. For prompt caches that use automatic matching or caching based on breakpoints, the reusable portion should typically consist of a continuous, identical prefix starting from the beginning of the prompt. So, content that changes slowly and can be reused in many ways should go at the beginning, while content that changes frequently should go at the end. For example: Plain Text Long-term stable content: system prompt, tool definitions → Periodically stable content: user configuration, reference documentation, task background → Session content: conversation history, task status → Current request: current time, temporary information, user question This isn’t a fixed classification. The key is to arrange content by stability, but this shouldn’t alter message roles, command priorities, or business semantics. Different service providers may use automatic matching, explicit cache breakpoints, or independent cache objects. Also, keep in mind that minimum length, expiration periods, and billing rules can differ depending on the model. When integrating, it’s a good idea to check the latest model documentation and cache statistics in the response. Two Common Bad Cases: These Approaches Can Quietly Break Cache Reuse Here are two common examples. The code uses Anthropic’s cache_control as an example, but other service providers may use automatic matching, different cache markers, or independent cache objects. So, you can’t simply copy these fields across providers. 1. Dynamic Content Can Mess With Prefix Stability When you’re counting on prefix matching, if the content changes at a certain point, the old prefix following that point usually can’t be reused. So, including a timestamp  —  which changes with every request — in the cache prefix will affect the fixed rules that follow it. JavaScript // ❌ Timestamp is included in the cached prefix and changes every request const system = [{ type: "text", text: `Current time: ${new Date().toISOString()} You are a code assistant. Here are the fixed behavior rules...`, cache_control: { type: "ephemeral" } }] A better approach is to put long-term, stable content at the beginning and set a cache breakpoint at the end of the stable prefix. Dynamic information, like timestamps, should be placed after the cache breakpoint. JavaScript // ✅ Stable content first; dynamic content after the cache breakpoint const system = [ { type: "text", text: "You are a code assistant. Here are the fixed behavior rules..." }, { type: "text", text: "Here are the fixed tool usage instructions...", cache_control: { type: "ephemeral" } }, { type: "text", text: `Current time: ${new Date().toISOString()}` } ] Content like project configurations and reference materials might be somewhere between “long-term stable” and “subject to frequent changes.” You can sort them by stability. If there are multiple cache breakpoints, set breakpoints for stable prefixes of different lengths. You also need consistency beyond just the text: the order of tool definitions, image parameters, and other elements may also participate in prefix matching. 2. Only Caching the System Prompt in Multi-Round Conversations Multi-round conversations usually include the conversation history in every request. If you set the cache breakpoint only at the end of the system prompt and don’t enable automatic caching, the growing conversation history will still need to be processed repeatedly. JavaScript // ❌ Only caches the system prompt; conversation history is outside the cache boundary const request = { system: [{ type: "text", text: "You are a code assistant...", cache_control: { type: "ephemeral" } }], messages: history } You can use Anthropic’s current auto-caching as an example. Enable cache_control at the top level of the request to automatically move the cache boundary forward as the conversation grows: JavaScript // ✅ Automatically cache the prefix of an ever-growing conversation const request = { cache_control: { type: "ephemeral" }, system: [ { type: "text", text: "You are a code assistant..." } ], messages: history } Once enabled, the next round of requests can use the prefix that was cached from the previous round. It processes only the responses, tool calls, tool results, and current question that were added, and writes a new cache prefix for later requests. So, this reduces unnecessary processing of the conversation history. It does not mean that only the last message results in a cache miss. If the service provider doesn’t support automatic caching, you need to follow its rules and place an explicit cache breakpoint at a stable position near the end of the conversation. Setting a cache doesn’t guarantee a hit. When a prefix is encountered for the first time, the system typically has to finish the computation and write it to the cache first. A cache miss may occur if the cache has expired, doesn’t meet the minimum length, the historical prefix has changed, or the cache entry isn’t yet available. As of August 2026, each cache breakpoint in Anthropic will only search for previously written cache entries within the most recent 20 content blocks. A miss may also occur if too many blocks are added during a single Agent cycle. You can’t just look at whether cache configuration is present in the request to determine whether caching really provides benefits. You should check the cache read, write, and hit metrics that the API returns. If latency is a concern, you should also log first-token latency on the application side and evaluate cache effectiveness together with actual costs. Finally, How to Tell the Two Apart ConceptCore FunctionKV cache (Inference Mechanism)Reuses the K/V pairs of historical tokens during generation to avoid redundant calculations at each step.Prompt cache/prefix cache (Cross-Request Reuse)Reuses prefill results with the same prompt prefix across different requests. So, the two are not equivalent, nor are they entirely unrelated. The KV cache is the underlying state and inference mechanism. The prompt cache reuses the pre-computed prefix state for other requests. For application developers, the best approach is to keep the common prefix stable and put timestamps, temporary information, and the current question as far toward the end as possible. References OpenAI: Prompt cachingAnthropic: Prompt cachingHugging Face: CachingvLLM: Automatic Prefix CachingDeepSeek: Context Caching

By Jake Tao
dbt Meets Apache Flink: One Workflow for Data Engineers
dbt Meets Apache Flink: One Workflow for Data Engineers

Data engineers managing batch SQL pipelines on Snowflake, BigQuery, and increasingly Databricks, and streaming pipelines on Apache Flink face a familiar problem: two toolchains, two skill sets, two CI/CD pipelines.dbt is now extending into stream processing. This post explains what that means in practice, why it matters for data engineering teams, and what a concrete implementation looks like with Apache Flink on Confluent Cloud. Data Streaming Meets the Lakehouse Data lakes promised to solve the enterprise data problem. The reality has been messier. Batch pipelines produce stale information, and analytical workloads run hours after the business event occurred. By the time a query runs, the window for action is often already closed. The lakehouse pattern has improved matters. Apache Iceberg has become the dominant open table format, supported across Snowflake, Databricks, BigQuery, and a growing number of query engines. Teams can run SQL analytics directly on data in object storage without duplicating it into a proprietary warehouse. But the lakehouse alone does not solve the real-time problem. Data still arrives as a batch, minutes or hours after the source event. That gap reflects a deeper architectural split. Data streaming with Apache Kafka and Flink is the operational layer: it handles critical SLAs, powers event-driven applications, and keeps business systems running in real time. The lakehouse is the analytical layer: it stores historical data for reporting, ML, and near real-time or batch analytics. These are two distinct workloads with different requirements regarding uptime, data loss, latency, and throughput. They need to coexist without forcing engineers to build and maintain two separate pipelines. How Kafka, Flink, and Iceberg Work Together That is what the combination of Apache Kafka, Apache Flink, and Apache Iceberg addresses. Kafka captures every event at the source and serves as the operational backbone for real-time systems. Flink processes and enriches data in motion, supporting both immediate operational decisions and the preparation of data for downstream analytics. Iceberg stores the result as a governed, queryable table for any analytical engine, whether that is Snowflake, BigQuery, or Databricks. A full treatment of this architecture, including schema evolution, compaction, and catalog integration, is covered here: Data Streaming Meets Lakehouse: Apache Iceberg for Unified Real-Time and Batch Analytics. The question is no longer whether streaming and lakehouse architectures can coexist. They already do. The question is how data engineering teams can work across both without maintaining separate toolchains. That is where dbt enters the picture. What Is dbt? dbt, the data build tool, is an open-source framework for SQL-based data transformation. A dbt model is a SQL SELECT statement saved as a file. dbt infers execution order from how models reference each other using ref(). The standard commands cover the full engineering workflow: dbt run executes the SQL against the target platform, dbt test validates data quality, and dbt docs generate produces a browsable documentation catalog. What made dbt successful is the discipline it brings to SQL work. Before dbt, transformation logic lived in scattered scripts and proprietary ETL tools. dbt replaced that with a code-first, version-controlled workflow with built-in lineage, testing, and documentation. Snowflake and BigQuery are where most dbt adoption lives today. Both are SQL-native and optimized for the ELT pattern dbt was built around. Redshift is a strong third platform in AWS environments. Databricks has seen growing dbt adoption more recently, driven by investments in serverless SQL Warehousing, but its roots are in Spark and Python, making it a newer entrant in the dbt ecosystem. dbt Labs crossed $100 million in ARR in early 2025, with over 5,000 paying customers. Around 90,000 dbt projects are running in production today. The Fivetran and dbt Labs merger, announced in October 2025, created a combined data infrastructure company with nearly $600 million in annual revenue — a clear signal that dbt has moved well beyond a popular open-source tool and into foundational enterprise data infrastructure. dbt Meets Apache Flink: One Workflow for Data Engineers Data engineering teams managing both batch and streaming today operate in two separate realities. Snowflake or BigQuery on one side: dbt models, version-controlled SQL, automated tests, generated docs. Apache Flink on the other: Terraform scripts, custom deployment code, or the Flink console. Skills and practices do not transfer between the two. That separation has a real cost. Streaming pipelines are harder to test, harder to document, and harder to hand over. Many teams compensate by keeping streaming logic minimal and pushing transformation work downstream into the warehouse, which reintroduces latency and undermines the point of streaming. The vision is straightforward: one SQL workflow for both. The engineer who builds dbt models on Snowflake or BigQuery should be able to apply the same approach to an Apache Flink streaming pipeline, without switching tools or rebuilding CI/CD from scratch. Two toolchains mean two testing strategies, two documentation systems, and two skill sets to hire and retain. Governance enforcement becomes inconsistent across the two environments. SQL is the shared foundation that makes this realistic. Flink SQL is mature and production-proven. Snowflake and BigQuery are SQL-native. Apache Iceberg tables are queryable via SQL across multiple engines. dbt wraps SQL with engineering discipline. The model files look the same. The ref() dependency resolution works the same way. Tests and documentation generation work through the same commands. Organizations do not need to hire separate Flink infrastructure specialists. The existing data engineering team can own both sides. Apache Iceberg connects the two worlds at the storage layer. A Flink pipeline writes structured, governed events into an Iceberg table in the organization's own S3 bucket. That same table is immediately readable by Snowflake, BigQuery, or Databricks without any additional ETL step. dbt can model data across the full pipeline: shaping it as it streams through Flink, and transforming it again when it lands in the warehouse for analytics. This is also a direct enabler of the Shift Left Architecture 2.0. The Shift Left approach moves data integration logic closer to the source, applying quality checks, enrichment, and governance in the streaming layer before data lands in the lakehouse. Until now, that required streaming-specific skills that most dbt-native teams did not have. dbt for Flink lowers that barrier considerably. The full architectural detail is covered here: The Shift Left Architecture 2.0: Operational, Analytical and AI Interfaces for Real-Time Data Products. Concrete Example: dbt on Confluent Cloud with Apache Flink The most concrete implementation available today is the dbt-confluent adapter, released by Confluent alongside the confluent-sql Python driver. Both are open source and available on PyPI and GitHub. Data engineers define streaming pipelines as dbt models and deploy them to Flink compute pools using the standard dbt run command. Getting started is a single step: pip install dbt-confluent Three materializations are supported: view for a virtual Flink SQL view over a Kafka topic, streaming_table for a continuous always-current result set, and streaming_source for defining a Kafka topic as a dbt source. Testing is deterministic, using Confluent Cloud's snapshot query capability to return bounded point-in-time results rather than silently passing on timeout. Documentation generation works through INFORMATION_SCHEMA integration, producing the same browsable catalog that Snowflake and BigQuery projects generate. The underlying confluent-sql driver is DB-API v2 compliant, meaning any compatible tool can connect directly to Confluent Cloud Flink: Airflow and Dagster for orchestration, Pandas for snapshot queries, Streamlit for live dashboards, and LangChain for AI agent workflows. For data engineers already working in dbt, this means the skills and practices built around Snowflake or BigQuery transfer directly to the streaming side of the architecture. The Data Engineer Owns Batch and Streaming with dbt The separation between batch and streaming engineering has always been more organizational than technical. Both worlds use SQL. Both require testing, documentation, and reliable deployment. The tools just never bridged the gap, so organizations staffed and operated two distinct engineering disciplines. dbt extending to Apache Flink changes that equation. The data engineer who runs dbt on Snowflake or BigQuery today can apply the same mental model, commands, and CI/CD pipeline to Flink streaming pipelines. No Flink infrastructure specialization required. They write SQL models, define tests, generate documentation, and deploy, exactly as they do for batch. The implication is straightforward. The investment in dbt skills and tooling now extends further into the architecture. Streaming can be adopted incrementally by the same data engineering teams already trusted for batch. One team, one tool, one governance standard, across both operational and analytical workloads. The Flink adapter for dbt is earlier in maturity compared to dbt on Snowflake or BigQuery, and teams should expect to work with an evolving ecosystem. But the foundation is solid, the direction is clear, and the core architectural components are already running in production at scale across multiple industries. The demand from data engineering teams is real and growing.

By Kai Wähner DZone Core CORE
Data Governance for the Agentic Era
Data Governance for the Agentic Era

The modern enterprise generates and consumes unprecedented volumes of data across operational systems, customer interactions, partner ecosystems, cloud applications, IoT devices, and AI platforms. At the same time, AI systems are becoming major consumers of enterprise data, making decisions, generating content, recommending actions, and automating workflows. Poor data quality is no longer just a reporting issue; it is also an AI issue. Inaccurate, incomplete, or poorly governed data can produce biased outcomes, regulatory violations, AI hallucinations, and flawed business decisions. Traditional data governance programs were primarily designed to support business intelligence and regulatory compliance. However, the AI era introduces new requirements around model governance, explainability, lineage, ethical AI, data observability, and autonomous decision-making. Organizations must therefore evolve toward a unified data and AI governance model that ensures data can be trusted not only by humans but also by machines. Poor data governance can result in hallucinating AI systems, biased model outcomes, regulatory violations, security breaches, increased operational costs, customer trust erosion, and incorrect business decisions. Data governance has therefore evolved from a compliance function into a strategic business capability. Enterprises that establish trusted, governed, and accessible data foundations will be better positioned to scale AI initiatives, accelerate innovation, and create sustainable competitive advantages. The basic objectives of data governance are: Enhance the agility of data-informed business decisionsFacilitate seamless knowledge sharing across the enterpriseEliminate ambiguity and foster trust in data assetsIncrease data trust, better decision-making, and faster innovation cyclesImprove compliance posture, reduce data duplication, and increase business agility To fully comprehend these objectives, it is essential to first recognize the critical role that data governance plays within an enterprise's broader data management strategy. This white paper explores the challenges, next-generation data capabilities, modern data architecture, and strategic considerations required to build an AI-ready data foundation. Industry Trends of Data Governance According to Gartner, “Any organization in any industry, especially those with very large amounts of data, can use AI for business value.” According to Statista, by 2027 the global market for big data will be worth $103 billion. According to Gartner, 60% of organizations will fail to realize the value of their AI initiatives due to weak data governance frameworks. By 2028, enterprises will increasingly adopt autonomous, AI‑driven governance systems capable of automated policy enforcement, continuous data quality scoring, and real‑time anomaly detection. Gartner forecasts that AI‑driven automation will reduce manual data stewardship tasks by 40% by 2027. Governance models will shift from centralized to federated and hybrid, ultimately evolving toward autonomous domain‑driven governance. Gartner reports that over 60% of enterprises will adopt federated governance by 2027. The rise of AI‑augmented data mesh as a dominant architecture by 2028 (Thoughtworks). AI Trust, Risk, and Security (AI TRiSM) will become the top governance investment area as organizations confront risks related to hallucinations, bias, and regulatory compliance. Gartner predicts that enterprises implementing AI TRiSM will reduce AI‑related risk incidents by 50% by 2026. With the rapid expansion of IoT, 5G, and edge AI, governance must operate in real time. IDC estimates that 30% of enterprise data will be processed at the edge by 2027. AI platforms will embed governance natively, enabling governed prompt engineering, model access, and data contracts. Gartner predicts that 75% of AI platforms will include built‑in governance controls by 2027. Databricks Mosaic AI, Snowflake Cortex, and Microsoft Azure AI’s Responsible AI Dashboard exemplify this trend. Synthetic data will become a regulated and essential component of AI training. Gartner projects that synthetic data will overshadow real data in AI training by 2030. McKinsey estimates that 50% of AI training datasets will include synthetic data by 2028. Global regulations will mandate transparency, lineage, and automated audits. Gartner states that regulatory pressure will be the top driver of data governance investments through 2030. Data contracts will replace traditional API documentation, enforcing schema, SLAs, lineage, and quality. Gartner predicts that data contracts will reduce integration failures by 40% by 2027. Challenges in Data Governance As enterprises expand into multi-cloud environments and increasingly adopt generative AI, governance challenges continue to multiply. The most common data governance challenges faced by enterprises today are, Data explosion: Data exists across multiple, diverse systems throughout the enterprise. Data is spread across structured data, semi-structured data, unstructured content, streaming data, IoT telemetry, computer vision assets, agent-generated content, and AI-generated outputs. Traditional governance frameworks often lack the scalability and automation required to manage such diversity.Data silos: Data is segmented across various platforms, channels, tools, and business units, making it challenging to access across the enterprise. Most data resides across ERP systems, CRM platforms, legacy applications, cloud-native platforms, data warehouses, data lakes, and SaaS applications. This leads to inefficiency, data duplication, and data inconsistency.Data accuracy, completeness, and timeliness: Ensuring data accuracy, completeness, and timeliness remains a challenge.Data quality: Poor oversight of the quality of data coming into an enterprise, as well as its usage throughout the organization, can lead to poor data quality. Common quality challenges include missing values, duplicate records, outdated information, inconsistent definitions, incomplete lineage, and data drift.Regulatory complexity: Managing regulatory compliance, data security, and data privacy presents significant challenges. Enterprises must comply with GDPR, HIPAA, CCPA, PCI-DSS, the EU AI Act, and industry-specific regulations.Data management: Poor data management strategies can result in an enormous amount of data in a completely unmanageable format.Data leakage: Sensitive business information or customer data may be exposed or leaked, leading to misuse. Unsecured data originating from different data sources can lead to data breaches.AI-specific risks: New AI-era governance concerns include algorithmic bias, explainability requirements, training data provenance, prompt governance, LLM hallucinations, and autonomous agent controls. Next Generation Data Capabilities Governance alone does not create value. Enterprises need enterprise data capabilities that make governance operational while enabling innovation and AI adoption. Modern data ecosystems require intelligent platforms capable of discovering, understanding, protecting, and serving data on a scale. Data processing techniques: Unstructured processing covers entity extraction, concept extraction, sentiment analysis, NLP, ontology, etc. To automate portions of the extraction process, Machine Learning techniques are leveraged. Data intelligent platform: It enables natural language queries, AI-powered recommendations, intelligent search, and context-aware discovery.Data products: Data products provide ownership, accountability, defined SLAs, reusability, and business value measurement.On-demand data services: Provide virtualized access to data across the enterprise through way of composable on-demand data services for both online and offline use. It should provide the ability to query in a federated fashion for both online and offline access.Intelligent metadata management: Digital throws data into enterprise systems at a rate that doesn’t allow SMEs to look at data structures and extract metadata. Automated metadata extraction based on ontology is critical. Modern metadata platforms provide automated discovery, classification, catalog generation, lineage tracking, and semantic enrichment.Data fabric: It provides unified data access, cross-platform integration, federated governance, and policy automation.Data mesh: It enables domain ownership, distributed accountability, product-centric thinking, and decentralized governance. Data observability: It focuses on data health monitoring, pipeline performance, anomaly detection, drift identification, and SLA compliance.Real-time analytics: Multi-channel applications and decision management systems are used to capture interactions for digital processes in real-time scenarios. Data archival: Compliance and performance requirements drive the need for archival of both structured and unstructured data. Principles of Data Governance Architecture principles provide a baseline for decision-making across the enterprise. To guide implementation, enterprise data governance principles are categorized into three strategic domains: Value and ownership, security, privacy and ethics, and architecture and quality. Value and Ownership Data as an asset: Data is an enterprise asset with specific, measurable value to the enterprise and must be managed accordingly.Data is shared: Users have access to the data necessary to perform their duties; therefore, data is shared across enterprise functions and business units. Data stewardship: Governance structure must define the owner and those accountable for data-related decisions that are cross-functional. Define the personnel accountable for leadership activities and assign responsibilities to individual contributors or groups of data handlers. Data trustee: Each data element has an assigned trustee accountable for its quality, lifecycle, and compliance. Security, Privacy & Ethics Principles Data security: Data is protected from unauthorized use and disclosure. Data privacy: Privacy and data protection are considered throughout the entire life cycle of the data. All data sharing will conform to relevant regulatory and business requirementsData integrity: Each party to data must be aware of, and abide by, their responsibilities regarding the provision of source data and the obligation to establish and maintain adequate controls over the use of personal or other sensitive data. Data transparency: Governance decisions, policies, and lineage must be transparently documented and clearly communicated across the enterprise. All data-related decisions must be explained clearly to all personnel how, when, and why they are introduced. Architecture & Quality Principles Common vocabulary and data definitions: Data definitions are consistent across the enterprise and understandable to all users.Fit for purpose: Next-generation information ecosystem needs to have fit-for-purpose tools, as no one technology will satisfy all the workloads and processing techniques - E.g., Text Processing, Data Discovery, Dynamic Data Services, High-Performance Analysis, Streaming Analytics, etc.Data metrics: Critical Data Elements (CDEs) of the Business are managed through a lifecycle-oriented data governance process to ensure data quality, with clear metrics and dashboards. As data will reside in many repositories, integrated metadata lineage and PII protection are important. Key Components of Data Governance In the modern era, data management covers both technical requirements and strategic assets for businesses. Efficient data management Strategies help enterprises make informed decisions, improve customer experiences, and drive innovation. Data governance covers the automation of policies, guidelines, principles, and standards for managing data assets. It ensures data quality, accuracy, and compliance with regulatory requirements, building trust in the data. Data governance must be aligned with EA Governance at the enterprise level to realize the business objectives. Some of the open-source data governance tools are Amundsen, DataHub, Apache Atlas, Magda, Open Metadata, Egeria, and TrueData. These tools offer features like Metadata Management, Data Cataloging, and Collaboration to manage data assets effectively. The major components of data governance are: Data qualityData stewardshipData policies and procedures Data security Metadata management Master data management Data storageData privacy and complianceData metrics The following figure depicts the key components of data governance: Figure 1: Key Components of Data Governance Data Quality It helps ensure the accuracy, completeness, and consistency of data. Data quality management involves identifying and correcting errors, standardizing formats, and maintaining a high level of data integrity. Some of the top open-source data quality tools are: Cucumber, Deequ, dbt Core, MobyDQ, Great Expectations, and Soda Core. These tools help automate data validation, data cleaning, and monitoring. Data Stewardship It is about assigning roles and responsibilities related to data management. Data stewards are designated individuals or teams entrusted with overseeing the appropriate use, integrity, and secure storage of enterprise data. They serve as a vital bridge between IT and business units, ensuring that data conforms to the enterprise’s established quality and consistency standards. Key responsibilities include defining and standardizing data elements, monitoring data quality, and collaborating with IT to resolve any technical challenges. Other key data roles are: Chief data officers (CDOs) lead the data strategy, ensuring data is treated as a valuable business asset. Their goal is to drive executive investment in data compliance, risk reduction, and value creation as data becomes a trusted driver of business outcomes.Data protection officers (DPOs) ensure organizational compliance with data privacy laws like GDPR and CCPA. They oversee the protection of personal data, such as that of customers or suppliers, processed during daily operations. DPOs must have direct access to senior leadership to fulfill regulatory requirements.Data architects design robust yet flexible data foundations that empower users to manage and enhance their own datasets. They ensure data is meaningful, business-driven, and aligned with organizational goals. Their priorities often reflect measurable business outcomes.Data engineers and developers design and maintain data pipelines, ensuring data quality and flow across complex systems. They aim to empower business users while managing access, security, and data product governance.Data scientists extract value from data pipelines to deliver actionable insights. They solve complex problems using statistics, mathematics, and computer science. Their expertise often includes data mining and predictive analytics.Business analysts identify trends, assess risks, and gauge business performance using BI tools like Tableau, Power BI, and Looker. They extract trusted insights from data pipelines and present them through clear, actionable dashboards. Data Policies and Procedures It establishes and enforces policies for how data is collected, stored, shared, and used. As enterprise central data management, Prescribes permitted and prohibited practices at every stage of the data lifecycleEnsures compliance with internal standards and external regulationsAssigns accountability for data stewardship and risk mitigationAligns day-to-day data handling with strategic business objectives Data Security Establishing proper security protocols helps in reducing the risk of data breaches and threats. It also safeguards sensitive information. Implementation of Encryption, access controls, authentication, and intrusion detection systems helps in protecting data across the lifecycle. Top open-source data security tools that are widely used include: Metasploit, OSSEC, OpenVAS, Snort, KeePass, ClamAV. These tools can be integrated into various security strategies to protect against a wide range of cyber threats. Metadata Management It helps in keeping track of data definitions, relationships, and structures. It’s essentially data about data. Metadata functions as the contextual glue that transforms isolated data points into coherent, actionable assets. It captures essential attributes covering: Creation timestampAuthorship and ownershipSource provenanceRelationships to other data elements Metadata strategy should: Adopt a centralized metadata catalog (e.g., Apache Atlas, Collibra)Automate metadata harvesting and lineage trackingIntegrate metadata-driven data quality checks into your pipelinesEstablish governance policies for metadata stewardship and versioningMonitor metadata KPIs like catalog adoption rate and lineage coverage to drive continuous improvement Leading open-source metadata management tools are Apache Atlas, Amundsen, Metacat Data Catalog, Open Metadata, and Marquez. Master Data Management Master data management is a process for ensuring the accuracy, consistency, and completeness of critical data elements, such as customer data and product data, etc. master data is standardized, matched, merged, enriched, and validated according to governance rules. Some of the open-source key players in the MDM area are Talend Open Studio for MDM, AtroCore, and Pimcore. Data Storage It helps determine where and how data will be stored within the enterprise data repository. It covers both structured and unstructured data sources, which include databases, data warehouses, and data lakes. The factors that determine data storage are Performance, scalability, and data retrieval requirements. Some of the key open-source players in the data storage area are Hadoop, LakeFS, Cassandra, and Neo4j. These tools provide scalability, robustness, and performance in managing large data and analyzing large datasets in various applications. Data Privacy and Compliance It ensures adherence to regulations and ethical considerations. Privacy implements controls to prevent unauthorized access and provides control over individuals' personal data. Regulatory frameworks such as the European Union’s General Data Protection Regulation (GDPR) and California’s Consumer Privacy Act (CCPA) impose stringent requirements on how businesses collect, process, and safeguard personal data. Data Metrics Management Defining and implementing robust business metrics and key performance indicators (KPIs) to quantify the enterprise-wide impact of data governance is critical to its success. These measures should be clearly articulated, inherently quantifiable, tracked longitudinally, and applied each year consistently to ensure comparability, accountability, and continuous improvement. Some of the metrics monitoring activities are, Aligning KPIs to strategic goals (e.g., data-quality gains, reduced time-to-insight, compliance rates, cost savings)Leveraging real-time dashboards for ongoing visibilityConducting annual KPI reviews to recalibrate targets and processes as the organization evolves Modern Data Architecture for AI A modern data architecture provides capabilities necessary for analytics, machine learning, generative AI, and autonomous systems. It enables enterprises to manage data as a strategic asset while ensuring governance, security, and scalability. The architecture is a unified, governed, AI-ready data foundation that enables trusted insights, intelligent automation, and autonomous decision-making through reusable data products, continuous observability, and embedded governance controls. The architecture is organized into two structural categories. The first five layers form the primary pipeline, the path data travels, from the moment it is created in a source system to the moment it produces a business outcome. The remaining three layers are cross-cutting disciplines that are applied continuously, at every stage, from ingestion through consumption. A modern AI-ready data architecture provides the infrastructure necessary for analytics, machine learning, generative AI, and autonomous systems. It enables organizations to manage data as a strategic asset while ensuring governance, security, and scalability. Figure 2: Enterprise Data Architecture For AI Data Sources This layer represents the full surface area of enterprise data — every system, channel, partner relationship, and unstructured artifact that generates information the organization can use. This layer groups the ecosystem into four major categories: Operational systems: The systems of record that run the business day-to-day: ERP, CRM, domain platforms, billing, and HR, etc. These remain the backbone of structured, transactional data.Digital channels: Web, mobile, API, and customer portal through which customers and employees interact directly with the enterprise. These channels are not purely a source; they also receive personalized or real-time data back through APIs.Partner ecosystems: B2B integrations, data exchanges, and marketplaces that bring external, third-party data into the enterprise's view.Unstructured and knowledge: Documents, email, video, knowledge bases, and ontologies. This category has grown in strategic importance because it is precisely the content that large language models and retrieval-augmented generation (RAG) pipelines depend on. Ingestion, Integration, and Orchestration This helps to move data from source into the platform reliably, securely, and in the right cadence, like batch, streaming, or on-demand. This layer comprises four capability areas, Data pipelines and orchestration: Engines that sequence and monitor data movement, paired with pipeline observability so failures and delays are visible before they become business problems.API management: Gateways, throttling, versioning, and security policy enforcement for every API-based integration, ensuring that data movement through APIs is controlled rather than ad hoc.Streaming and events: Event hubs and pub/sub infrastructure (e.g., Kafka-style platforms) that support event-driven integration for use cases where near-real-time movement is required.Data virtualization: Query federation that lets consumers query across multiple heterogeneous stores without first physically consolidating the data, reducing duplication and latency for enterprise usage. Core Data Platform (Analytics + AI) This is the heart of the architecture that acts as an AI-ready layer. It provides a unified storage and serving layer. This is the place where data lives and is made available for both traditional analytics and AI workloads from a single, governed foundation. Lakehouse and warehouse: It combines the flexibility of a data lake with the performance and semantic structure of a warehouse, including reusable semantic models that give consistent business meaning to raw tables.Operational data stores (ODS): Supports near-real-time reporting for use cases that cannot wait for a batch cycle.Vector and knowledge layer: Vector databases and ontologies that power agentic AI and semantic search are foundational to GenAI.Feature and model stores: Reusable features, a model registry, and model artifact storage, enabling machine learning models to be built, versioned, and reused consistently rather than recreated per project.Content and document stores: A repository that supports GenAI applications operating directly over enterprise content (contracts, policies, knowledge articles). AI, Analytics, and Decision Intelligence In this layer, the governed data is converted into insight, prediction, and increasingly autonomous action. Descriptive and diagnostic: BI, dashboards, and self-service analyticsPredictive and prescriptive: Machine learning models, optimization, and simulation GenAI and agentic AI: Copilots, task-oriented agents, and RAG pipelines that generate content to take bounded actions on the enterprise's own dataDecision intelligence: Composite decision flows that blend rules engines, analytics, and AI models into a single decision path Data Management and Semantics Layer Makes data trustworthy, findable, and consistently defined. This is applied continuously across every stage of the pipeline rather than as a single processing step. Enterprise data catalog: Technical and business metadata plus a data marketplace, such that stakeholders and systems can discover what data exists and what it means.Business glossary: Shared definitions, metrics, and domain vocabularies that prevent the classic problem of different business units calculating "revenue" or "active customer" differently.MDM and reference data: Golden records for core entities such as provider or product, eliminating duplication and conflicting versions of the truth.Data quality and profiling: Rules, scoring, and remediation workflows that continuously monitor and improve data fitness for use.Lifecycle management: Retention, archival, tiering, and deletion policies that keep the data estate compliant and cost-efficient over time. Agentic AI Governance, Security, and AI TRiSM Protects data and models with policy, privacy, identity, and full traceability. Policy-as-Code: Codified policies that are enforced programmatically rather than documentedLeast-privilege tool scope: Agents should operate with scoped function definitions rather than open-ended enterprise API access. Tools exposed to agents must enforce fine-grained parameter constraints AI TRiSM (Trust, Risk, and Security Management): Model risk assessment, explainability, fairness testing, and ongoing monitoring, addressing the risks introduced by AI/ML modelsIdentity delegation and impersonation: Enterprise agents must pass user identity context (OAuth 2.0 Token Exchange/On-Behalf-Of flow) down to underlying APIs. The agent must never inherit broader database permissions than the initiating user.Privacy and protection: PII/PHI classification, masking, and tokenization to limit exposure of sensitive data.Access and identity: RBAC/ABAC, fine-grained entitlements, and a Zero Trust posture, ensuring access is granted on a least-privilege basisLineage and observability: End-to-end lineage across data, models, and promptsPrompt/Context provenance and non-determinism audit: Every dynamic branch decision made by an agent must log its inputs, system prompts, retrieved context chunks, and seed parameters. This ensures that non-deterministic outputs can be audited post-hoc for compliance, debugging, and root-cause analysis during hallucinations or incorrect tool dispatches.Lineage granularity for vector and RAG workflows: Lineage models must extend beyond tabular source-to-target paths to map vector embedding lineage, tracing an agent’s final action back through the vector search embeddings, semantic chunking boundaries, and original unstructured document versions. Platform Engineering and MLOps/DataOps Dedicated engineering discipline. DataOps: CI/CD for data pipelines, including automated testing and deployment, bringing software-engineering rigor to pipeline changes.MLOps: CI/CD for models, including drift detection and automated retraining, so model performance is managed as an ongoing operational concern rather than a one-time deployment event.Platform engineering: Self-service portals, templates, and guardrails that let data and AI teams provision what they need quickly while staying within approved patterns.Infrastructure layer: Serverless compute, storage tiering, and cost management, ensuring the platform scales economically as usage grows. Business Consumption and Experience In this layer, the value is realized. The components and agents in this layer call back into the AI/Analytics layer in real time to inform what gets built upstream. Line-of-business applications: Domain applications, operations tooling, and customer service platforms through which employees and customers experience the businessCopilots and agents: Embedded copilots and agents inside applications and communication channelsAutomation and orchestration: Business process management (BPM), robotic process automation (RPA), and event-driven automation that act on insight without requiring manual interventionKPIs and value realization: OKRs, business outcome tracking, and benefit tracking that close the loop, measuring whether the solution is delivering value Benefits of Data Governance Enterprises with mature governance capabilities experience higher AI model accuracy, increased data trust, better decision-making, faster innovation cycles, improved compliance posture, reduced data duplication, and greater business agility. It also helps in: Ensuring consistent, uniform data across the enterprise, empowering smarter, more comprehensive decision supportEstablishing data integrity, data accuracy, completeness, trustworthiness, and dependability to achieve higher quality business decisionsHelping teams gain comprehensive decision support by enabling strong governance across the enterpriseDefining clear protocols for evolving data workflows; data governance helps in establishing agility and scalability for both the business and ITReducing duplication of effort and improving productivityMaking better-informed decisions with accurate and reliable dataIncreasing efficiency by introducing the ability to reuse data and data processesLowering the expenses of data management by implementing centralized control mechanisms and reducing the risk of data breachesReducing the volume of data collected and retained, optimizing data storage, and improving data management practicesEnhancing trust in the accuracy of data and the documentation of data-related proceduresEnsuring adherence to data regulations and supporting compliance with the EU’s GDPR, California Consumer Privacy Act (CCPA), Health Insurance Portability and Accountability Act (HIPAA), and the Payment Card Industry Data Security Standard (PCI-DSS) Conclusion Data governance is not a one-time activity, but it’s a journey. It is not optional but mandatory. It enables insight generation and informed decision-making. Effective data governance is a collection of processes, people, policies, standards, and metrics that ensure the efficient and effective use of data, enabling an enterprise to achieve its goals. It helps streamline operations, minimize data risks, enhance decision-making, drive innovation, create data policies, maximize data usage, and improve business efficiency and competitiveness. The modern AI data architecture is a unified, governed, and AI-ready foundation that turns enterprise data into trusted decisions and measurable business outcomes, with governance and AI risk management built in from the first byte rather than added at the end. By implementing data governance best practices, enterprises can ensure that they are managing their data to maximize its value. Acknowledgements The authors would like to thank Tricon Solutions LLC and Gspann Technologies, Inc for giving the required time and support in many ways in bringing up this article. Disclaimer The views expressed in this article/presentation are those of the authors, and Tricon Solutions LLC and Gspann Technologies, Inc. do not subscribe to the substance, veracity, or truthfulness of the said opinion.

By Dr Gopala Krishna Behara DZone Core CORE
Building a 2KB Histogram with Sub-0.2% Percentile Error
Building a 2KB Histogram with Sub-0.2% Percentile Error

The Problem: Tracking Request Latency Without Slowing Things DownFor a cloud data warehouse, performance is not just about average query time. What often matters more is tail latency, predictability, and the ability to pinpoint where things go wrong. In a cloud-native data warehouse like Databend, a single request may pass through multiple stages: SQL planning, distributed execution, remote storage, Raft logging, and state machine apply. Tail latency in any one of these stages can affect the query stability users actually experience. That means we need a way to continuously track latency distributions inside the system — lightweight enough to stay off the hot path, accurate enough to be useful, and cheap enough to run everywhere. This article walks through the design of base2histogram, the lightweight histogram library we built for that purpose. Consider the lifecycle of a single Raft log entry. It passes through several stages, each with its own latency profile: Received → written to storagePersisted to local diskReplicated to remote nodesAcknowledged by a majority quorumCommitted → applied to the state machineA histogram is a natural fit here: put latency on the x-axis and request count on the y-axis, and you get an immediate view of where time is being spent. This kind of visibility helps you identify bottlenecks and fix the right part of the system. But there is a catch: collecting metrics must not get in the way of doing actual work. The histogram needs to be: O(1) to record: No sorting, no rebalancing, and nothing that can stall a hot pathTiny in memory: A system may run hundreds or thousands of histograms at onceQueryable for percentiles: P50, P95, P99Let's walk through how we designed a histogram that meets all three requirements. Recording: Getting Samples Into Buckets Why Log-Scale BucketsMost requests cluster around a typical latency, with a few outliers on both ends. This often produces a log-normal distribution: take the log of the latency values, and the shape becomes a classic bell curve. The signature shape is a peak at lower values, followed by a gradual long tail to the right. To build a histogram, we divide the x-axis into buckets and count how many samples fall into each one. The key question is how to size those buckets. Equal-width buckets work well for a normal distribution, but latency is often log-normal. The data only looks roughly uniform on a logarithmic scale, so the buckets should grow on a log scale, not a linear one. The simplest version is to make each bucket twice as wide as the previous one:[0,1), [1,2), [2,4), [4,8), [8,16), ...Why powers of 2? Because multiplying by 2 is cheap on a CPU, and mapping a value to its bucket takes a single leading-zero-count instruction. If we simulate a log-normal workload and plot bucket counts with the bucket index on the x-axis — effectively applying a log transform — the result is a clean bell curve: This is great for storage: 65 buckets cover the entire u64range. But the resolution is poor. The last bucket spans half of all possible values, so everything that lands there becomes a blur. A Tempting Fix We Passed OnAn obvious improvement is to use a smaller growth factor, such as 1.1× instead of 2×. That gives us more buckets and finer resolution: The problem is cost. Finding the right bucket for a value l means solving for the smallest x where 1 + 1.1 + 1.1^2 + ... + 1.1^x >= l, which requires floating-point logarithms. That is real overhead on a hot path. We wanted to stay in the world of integers and bit operations. The Trick: Float-Like EncodingHere is the idea that makes the design work: keep bucket sizes roughly exponential, but encode each bucket using a fixed number of bits — a parameter we call WIDTH. Think of a bucket's lower bound as a tiny floating-point number. The MSB position gives the exponent, which tells us which bucket group the value belongs to. The next few bits give the offset within that group. With WIDTH=3, the default configuration, a bucket boundary looks like this in binary: Plain Text 00..00 1 xx 00..00 | MSB <- significant The leading 1selects the group. The two bits that follow select the bucket within the group. Here is what the first few groups look like. Each bucket is fully described by just 3 bits: Plain Text WIDTH = 3: range bucket index bucket size [0, 1) 0 0b0 ..... 000 1 [1, 2) 1 0b0 ..... 001 1 [2, 3) 2 0b0 ..... 010 1 [3, 4) 3 0b0 ..... 011 1 [4, 5) 4 0b0 ..... 100 1 [5, 6) 5 0b0 ..... 101 1 [6, 7) 6 0b0 ..... 110 1 [7, 8) 7 0b0 ..... 111 1 [8, 10) 8 0b0 .... 1000 2 [10, 12) 9 0b0 .... 1010 2 [12, 14) 10 0b0 .... 1100 2 [14, 16) 11 0b0 .... 1110 2 [16, 20) 12 0b0 ... 10000 4 [20, 24) 13 0b0 ... 10100 4 [24, 28) 14 0b0 ... 11000 4 [28, 32) 15 0b0 ... 11100 4 [32, 40) 16 0b0 .. 100000 8 [40, 48) 17 0b0 .. 101000 8 [48, 56) 18 0b0 .. 110000 8 [56, 64) 19 0b0 .. 111000 8 The pattern is simple: Each group contains 2^(WIDTH-1) = 4 bucketsThe two bits after the MSB select the bucket within the groupIt behaves like a 3-bit float: 1 implicit leading bit + 2 fractional bits Bucket sizes still grow roughly logarithmically, but computing the bucket index is now just a matter of extracting the top WIDTH bits — a handful of integer and bit operations. Recording a sample is O(1). Walk-through with latency = 42: Plain Text value = 42 (binary: 0b101010) MSB position: 5 group: 5 - 2 = 3 2 bits after MSB: 01 (from 1[01]010) offset in group: 1 Bucket index: 4 + (3 × 4) + 1 = 17 Tuning WIDTH: The Precision–Memory KnobWIDTH controls how many buckets each group contains: 2^(WIDTH-1). The number of groups is capped at 64, so the histogram still covers the full u64range. Increasing WIDTH gives each group more buckets, improving resolution at the cost of memory. Here is the trade-off: WIDTH Buckets Mem/slot Buckets per group 1 65 520 B 1 2 128 1.0 KB 2 3 252 2.0 KB 4 (default) 4 496 3.9 KB 8 5 976 7.6 KB 16 6 1920 15.0 KB 32 At the default WIDTH=3, one histogram uses 2 KB and records every sample in O(1). That covers the write path. Now let's look at the read path. Percentile Estimation: Getting Answers OutOnce we have collected the counts, we want to query percentiles: at what latency have 50% of requests completed (P50)? What about 90% (P90) or 99% (P99)? Locating the Right BucketThe basic idea is simple. For P50, count the total number of samples, take 50% to get a target rank p, then scan the buckets from the beginning and accumulate counts until you pass p. That gives you the target bucket. But a bucket spans a range, not a single point. We still need to estimate where inside the bucket the percentile falls. Here are a few options, from rough to more accurate. All error numbers below come from a log-normal distribution that models API latency, using WIDTH=3 and 1,000,000 samples. Midpoint: return (min + max) / 2. Many histogram libraries do this, including iopsystems/histogram. It is a blind guess: it ignores how samples are distributed within the bucket. P50 P95 P99 midpoint 5.018% 7.732% 4.861% Uniform interpolation: assume samples are evenly spread across the bucket, then interpolate linearly:estimate = min + (max - min) × rank / countThis is better than midpoint because it uses the target rank within the bucket. But the assumption is still rough: log-normal data is skewed, even inside a single bucket. Trapezoid Interpolation (Our Approach)Uniform interpolation treats density inside a bucket as flat. In reality, density is often sloped: higher on the side closer to the peak of the distribution. If we can infer the direction and steepness of that slope, we can replace the rectangle with a trapezoid and get much closer to the true value. Each bucket stores only a count, and we do not want to add any extra fields. So where does the slope information come from? From the neighboring buckets. The densities of the left and right buckets tell us how the density is likely to slope through the current bucket. Here is the recipe. Compute the average density of the left bucket, d0 = c0/(x1-x0), and treat it as the density at that bucket's midpoint, m0. Do the same for the right bucket: d2 = c2/(x3-x2) at midpoint m2. Then assume density changes linearly from m0 to m2. Over this short range, this is a reasonable approximation. It gives us the slope k. Inside the target bucket, the density now forms a trapezoid: a sloped line with slope k, anchored so that the density at the target bucket's midpoint (x1+x2)/2 equals the bucket's own average density d1 = c1/(x2-x1). For a linear function, the midpoint value is equal to the average over the interval. To estimate the percentile, we solve for the x-position where the trapezoid area from x1equals the target rank.Same distribution, same buckets — here is how the results compare: P50 P95 P99 midpoint 5.018% 7.732% 4.861% trapezoid 0.000% 0.080% 0.086% That is two orders of magnitude better, with zero additional storage. The three-bucket layout: Variable Meaning x0, x1, x2, x3 Boundaries of the three adjacent buckets w0, w1, w2 Bucket widths: w0 = x1-x0, w1 = x2-x1, w2 = x3-x2 c0, c1, c2 Sample counts in each bucket rank How many samples into the target bucket the percentile falls Plain Text d0 = c0 / w0 -- left bucket density d1 = c1 / w1 -- target bucket density d2 = c2 / w2 -- right bucket density Midpoints of the left and right buckets: m0 = (x0+x1)/2, m2 = (x2+x3)/2. Slope: Plain Text k = (d2 - d0) / (m2 - m0) Then solve for the x-position where the trapezoid's cumulative area from x1equals the target rank. The whole calculation uses only three counts and their bucket boundaries. Nothing else is stored, and nothing else is needed. Benchmarks: Seven Distributions, Six WIDTH SettingsWe tested the algorithm across seven representative distributions, each with 1,000,000 samples, using trapezoid interpolation. The rows to focus on are LN-API and LN-DB at W=3. These are the real-world latency cases under the default 2 KB configuration: Plain Text | W=1 W=2 W=3 W=4 W=5 W=6 | ------------------------------------------------------------------ | Uniform P50 0.108% 0.028% 0.012% 0.018% 0.019% 0.002% | P95 2.317% 1.988% 1.035% 0.475% 0.005% 0.005% | P99 4.290% 4.129% 3.706% 1.486% 0.298% 0.162% | | LN-API P50 2.281% 0.182% 0.000% 0.000% 0.000% 0.000% | P95 20.256% 3.963% 0.080% 0.040% 0.040% 0.000% | P99 11.951% 3.594% 0.086% 0.000% 0.029% 0.000% | | Bimodal P50 1.381% 0.394% 0.394% 0.197% 0.197% 0.197% | P95 3.918% 0.172% 0.012% 0.028% 0.038% 0.008% | P99 1.521% 1.344% 0.543% 0.078% 0.016% 0.014% | | Expon P50 1.012% 0.000% 0.145% 0.145% 0.145% 0.000% | P95 10.989% 0.200% 0.000% 0.000% 0.033% 0.033% | P99 18.665% 4.574% 0.824% 0.022% 0.022% 0.022% | | LN-DB P50 2.018% 0.034% 0.000% 0.000% 0.000% 0.034% | P95 2.027% 0.368% 0.039% 0.006% 0.019% 0.026% | P99 3.764% 1.066% 0.187% 0.007% 0.003% 0.062% | | Sequent P50 0.095% 0.000% 0.000% 0.000% 0.000% 0.000% | P95 2.271% 1.967% 1.011% 0.496% 0.000% 0.000% | P99 4.272% 4.118% 3.696% 1.521% 0.305% 0.169% | | Pareto P50 10.127% 1.899% 0.633% 0.633% 0.633% 0.000% | P95 9.239% 0.272% 0.000% 0.136% 0.000% 0.000% | P99 3.517% 0.879% 0.231% 0.093% 0.046% 0.046% | | ------------------------------------------------------------------ | Buckets 65 128 252 496 976 1920 | Mem/slot 520 B 1.0 KB 2.0 KB 3.9 KB 7.6 KB 15.0 KB | Mem total 1.0 KB 2.0 KB 3.9 KB 7.8 KB 15.2 KB 30.0 KB What each distribution models: Uniform (uniform distribution): synthetic benchmarksLN-API (log-normal σ=0.5): API and microservice latencyBimodal (bimodal distribution): cache hit/miss — 90% fast path around 500 μs, 10% slow path around 50 msExpon (exponential distribution): network and I/O waitsLN-DB (log-normal σ=1.0): database query latency with a wider tailSequent (sequential): adversarial worst casePareto (Pareto distribution α=1.5): heavy-tailed workloads, such as request sizesFor the latency distributions we care about most — LN-API and LN-DB — WIDTH=3 delivers sub-0.2% error with only 2 KB of memory. Summary 2 KB memory: WIDTH=3, 252 buckets of u64, with P50/P95/P99 error under 0.2% for log-normal latency workloadsO(1) recording, O(buckets) queryingTrapezoid interpolation delivers over 10× better accuracy than midpoint, with zero extra storageWIDTH is tunable: from 520 B for minimal tracking to 15 KB for maximum precisionA histogram may be a small piece of infrastructure, but it supports a much larger goal for Databend: making cloud data warehouse performance more observable, easier to reason about, and easier to optimize. When a system can continuously record distributions such as P50, P95, and P99 at very low cost, engineering teams can trace tail latency much faster — whether it comes from storage, the network, Raft, the execution pipeline, or the query itself. For users, that ultimately means more stable queries, more predictable performance, and a clearer path to cost optimization.

By bingxi Wu
Freshness as a First-Class Schema Concern: Modeling Data Staleness Across 83 Data Sources
Freshness as a First-Class Schema Concern: Modeling Data Staleness Across 83 Data Sources

I am not a developer, and I built a public reef atlas with AI agents. It pulls from 83 data sources that each update on their own schedule, some daily, some weekly, some once a decade. The hardest problem in the whole build was staleness, harder than the ocean science and harder than the frontend: how do you build a schema that tells the truth about how old each piece of data actually is, when the sources age so differently? The agents did more than write the code. They walked me through each schema decision as we went, explaining every tradeoff until I understood it well enough to make the next call myself, which is the only reason I can write it up now. It is a problem any app that blends live feeds with slow-moving records runs into, so here is how it showed up in the codebase and how the schema ended up solving it. The Lie That Is Easy To Tell by Accident Early on, every card in the atlas just showed a number. Coral cover: 32 percent. Fishing pressure: high. A user looking at that card has no way to know if the coral cover number is from a survey last month or a survey from 2010. Both render identically and feel equally current, which is exactly the problem: a UI that shows a number without its provenance is quietly asserting that all of its data is equally fresh. For us, that assertion was false in a way that mattered. A dive site can look improving on a stale 2010 baseline and be declining today. So the real fix was a schema decision. Freshness needed to be a first-class field on every data record, present on everything, rather than a caveat a human remembers to add in the copy later. Three Data Shapes Once I actually mapped our 83 sources with an agent, they sorted into 3 distinct freshness shapes, and each one needed its own contract. Live. Data with an automated ingest running on a schedule, where "updated" has a real, checkable timestamp. NOAA Coral Reef Watch thermal stress data refreshes daily at 06:30 UTC through a GitHub Actions cron job, no API key required, which made it the cleanest source to model against. Global Fishing Watch fishing pressure and IUCN Red List species status update weekly. For this shape, the schema stores an ISO timestamp and the UI is allowed to say the word "live," because it is actually true. Snapshot. Data from a real survey with a real date attached, but no automated pipeline behind it, because the source organization itself does not publish on a schedule. A lot of coral cover falls here. NCRMP, the NOAA National Coral Reef Monitoring Program, does not expose an API, so its numbers update when a report gets published, not on any cadence we control. For many of our locations, that means only 2 coral cover data points exist, a baseline around 2010 and a current reading from 2024. That is a before and after. The schema has to carry a surveyDate, and the UI has to show how many years old that survey actually is, because a 2-year-old survey and a 14-year-old survey should not look the same on the page. Presence. Data that confirms a species was observed somewhere, sourced from GBIF and OBIS, but carries no freshness claim and no population trend at all. It just says: this animal has been recorded here. A presence record has no trend that can go stale, so it carries no date at all and gets its own visual treatment, kept clearly apart from the numbers that do age. What This Looks Like as an Actual Component The pattern that made this maintainable was building one shared component, DataFreshnessLabel, with a discriminated union type instead of 3 different optional props bolted onto one interface. TypeScript type LiveProps = CommonProps & { variant: "live"; source?: string; updatedAt?: string; }; type SnapshotProps = CommonProps & { variant: "snapshot"; surveyMethod: string; surveyDate?: string; }; type PresenceProps = CommonProps & { variant: "presence"; source?: string; }; export type DataFreshnessLabelProps = LiveProps | SnapshotProps | PresenceProps; The discriminated union does the enforcement work that a code review would otherwise have to do by hand. What it makes mandatory is the freshness shape itself: every value has to declare whether it is live, snapshot, or presence, and a snapshot will not compile without a surveyMethod. That is the whole reason to model it as a union, so the compiler checks the provenance contract at the call site instead of trusting a reviewer to remember it. The survey date itself is deliberately optional, because some sources give a method and a rough vintage but no exact day, and I would rather model that gap than invent a precise date. What the union still guarantees is that a dateless snapshot renders as a snapshot. The date passes through a fmtDate helper that returns a literal dash when it is missing, so the label reads Snapshot · AGRRA · surveyed —, an explicit admission of unknown vintage. There is no shape in the union that renders as a bare, confident number, so the failure the article opened with cannot happen by accident. Each variant also gets its own color and its own copy, on purpose. Live is emerald with a pulse dot. Snapshot is amber, and if the survey is more than 2 years old, the component computes that itself and appends "(X years ago)" directly onto the label, so the staleness is not something a reader has to go dig for. TypeScript function yearsAgo(iso?: string): number | null { if (!iso) return null; const d = new Date(iso.length === 10 ? iso + "T00:00:00Z" : iso); if (Number.isNaN(d.getTime())) return null; const years = (Date.now() - d.getTime()) / (365.25 * 24 * 3600 * 1000); return Math.floor(years); } Freshness Has To Reach the Classification Logic Too, Not Just the Label The label solves the display problem. It does not solve the harder problem, which is that our core feature, classifying every reef as Improving, Stable, or Declining, is a derived value built on top of these mixed freshness inputs. The classification function pulls the worst thermal stress alert on record and the best coral cover reading on record, then applies thresholds: TypeScript // alertRank 3 is NOAA's first bleaching alert level (alert-1); "change" is the // internal state key that renders to the public label "Declining". if ((bestCover !== null && bestCover < 25) || alertRank >= 3) { return "change"; } That single function is quietly reading from both a live daily feed (thermal stress) and a snapshot that might be 4 years stale (coral cover), and producing one confident looking label. If I had not separated freshness at the schema level first, this function would have no way to distinguish "coral cover crashed last month" from "coral cover was measured once in 2010 and we are still using that number." Because the freshness contract is settled upstream in the schema, this function stays a plain threshold check. Every consumer of the data reads the same explicit field instead of re-deriving staleness on its own, so the rule for how old a number is lives in exactly 1 place. The Honest Number, in the End After auditing all 83 sources against this 3-shape model, the honest count came out smaller than I expected, and it forced a distinction I had been blurring. How often a source ingests is a different axis from which freshness shape it carries. 8 of the 83 ingest on a real automated schedule: NOAA thermal stress daily, Global Fishing Watch fishing pressure, IUCN status, the biodiversity feeds from iNaturalist, GBIF, and OBIS, and the AGRRA and MERMAID survey ingests. Ingesting on a schedule is not the same as carrying the Live freshness shape, though. The GBIF, OBIS, and iNaturalist feeds refresh often, yet every record they produce is still Presence, because a fresh pull of occurrence data does not make any single sighting newly true, so it carries no staleness claim at all. Coral cover is a snapshot for most locations, because the science itself does not move faster than a report cycle, though AGRRA now feeds live multi-year coral cover for the Caribbean through its public data explorer. Species sightings were, for a while, a snapshot that was quietly synthetic, meaning the backfill process had generated one plausible sighting per site to avoid empty states, which is its own lesson about how staleness bugs can hide inside data that looks populated. That has since moved to a real weekly iNaturalist and GBIF ingest. None of that would have surfaced if freshness had stayed a caveat in the copy instead of a field the schema enforces. If you are building anything that blends live feeds with slow survey data, model the freshness shape first, and make it a required part of the type rather than an optional afterthought, so every label reads from it. The display work gets much simpler once the schema is the thing that knows how old each number is. Scuba Season is a free, nonprofit reef atlas at scubaseason.fun.

By Josie Leung
Prompt Caching: Overriding Tokenization for Faster and More Cost-Effective AI
Prompt Caching: Overriding Tokenization for Faster and More Cost-Effective AI

As Large Language Models (LLMs) become increasingly integrated into enterprise applications, optimizing response time and reducing operational costs have become critical priorities. One of the most effective techniques for achieving both is Prompt Caching. Instead of processing identical prompt segments repeatedly, prompt caching allows AI systems to reuse previously computed prompt representations, minimizing redundant computation. While tokenization converts text into tokens that the model understands, prompt caching goes a step further by reusing the processing of unchanged token sequences, resulting in faster inference, lower latency, and reduced API costs, especially in applications with repetitive system prompts or recurring contextual information. How Prompt Caching Works Think of prompt caching as a “memory shortcut” for AI models. Every prompt is first tokenized, but when the same prompt prefix appears again, the model doesn’t need to process those tokens from scratch. Instead, it retrieves the cached computation and only processes the new or modified portion of the prompt. How Prompt Caching Works This mechanism is particularly valuable in AI assistants, enterprise chatbots, coding copilots, document analysis platforms, and Retrieval-Augmented Generation (RAG) systems where a significant portion of the prompt remains unchanged across multiple requests. Best Practices to Maximize Prompt Cache Efficiency To fully leverage prompt caching, organizations should design prompts strategically. Keep system instructions consistent, place static context before dynamic user inputs, avoid unnecessary formatting changes, and modularize prompt templates. These practices increase cache hit rates, reducing both processing time and infrastructure costs. Monitoring cache performance metrics, such as cache hit ratio, latency improvements, and token savings, helps teams continuously optimize AI workloads while maintaining response quality. Business Benefits and Real-World Impact Prompt caching delivers measurable business value beyond technical optimization. Organizations can reduce AI inference costs, improve application responsiveness, support higher request volumes, and enhance the overall user experience. Development teams also benefit from more predictable performance and scalable AI architectures. As enterprise AI adoption grows, prompt caching is becoming an essential optimization technique for building efficient, reliable, and cost-effective generative AI solutions. Where Prompt Cache Is Stored: Understanding the Architecture Where a prompt cache is stored depends entirely on which level of the caching architecture you are referring to. To understand where it lives, it is helpful to divide prompt caching into its two primary forms: Provider-Native Caching (Model-Level) When you use built-in prompt caching features from providers such as OpenAI, Anthropic (Claude), Google (Gemini), or DeepSeek, the cache is managed internally within the provider’s cloud infrastructure. What is Stored The cache does not store text or responses. Instead, it stores KV Tensors (Key-Value pairs). These are the raw, mathematical attention states that the model's neural network calculated during the "prefill" phase of your prompt Where Will it Live? GPU VRAM / High-Speed RAM: Because these tensors must be accessed instantly to keep latency ultra-low, they are stored directly in the high-speed volatile memory (VRAM) of the AI chips (GPUs/TPUs) or ultra-fast host system memory in the provider's data centers. Internal Distributed Storage: Since GPU memory is highly constrained and expensive, providers use advanced, proprietary cache-eviction systems. If a cache prefix isn't used for a few minutes (the Time-to-Live or TTL), it is automatically evicted (deleted) from the GPU memory to make room for other users Who Has Access? The provider manages this entirely behind the scenes. You cannot download, inspect, or manually move these KV tensors; the system simply checks the memory automatically during your API call and applies a discount if it finds a match. Application-Level Caching (User-Controlled Layer) If you are building your own caching layer in front of the LLM API to save even more money by bypassing the LLM entirely for repeat queries, you get to choose where it is stored In-Memory Databases (Most Common) Platforms like Redis or Memcached are the industry standard. Because they store data directly in RAM, they can fetch cached prompts in microseconds Vector Databases (For Semantic Caching) If you want to detect "semantically similar" prompts (e.g., matching "How do I reset my password?" with "I forgot my password"), the cache stores the text embeddings. This is stored in vector databases like Pinecone, Milvus, Qdrant, Weaviate, or pgvector (PostgreSQL) Relational / NoSQL Databases (For Archive/Backup) Standard databases like MongoDB, DynamoDB, or PostgreSQL are used to persistently store historical prompt-response pairs, though they have slightly higher retrieval latency than Redis Building a Semantic Cache With Redis involves upgrading from traditional "exact-match" caching to vector-based similarity caching. Instead of storing raw text, you store the mathematical representation (embeddings) of prompts. When a new prompt comes in, you convert it to an embedding and ask Redis to find the "nearest neighbor" (most similar prompt). If the similarity score exceeds your defined threshold (e.g., 95% similar), it's a Cache Hit. Here is the step-by-step guide to building a semantic cache using Python, Redis Stack (which includes vector search), and an embedding model (like OpenAI's). Prerequisites Redis Stack: You must use Redis Stack (or Redis Enterprise), as standard Redis does not support vector search. You can run it locally via Docker: docker run -d -p 6379:6379 redis/redis-stack-server:latest. Python Libraries: Install the required clients. pip install redis openai numpy: Redis also has a dedicated library called redisvl (Redis Vector Library) built specifically for this, which abstracts a lot of the boilerplate. Note: Redis also has a dedicated library called redisvl (Redis Vector Library) built specifically for this, which abstracts a lot of the boilerplate. The workflow follows four steps: Embed: Convert the incoming user prompt into a vector embedding. Search: Query Redis using a K-Nearest Neighbors (KNN) vector search. Evaluate: If the highest similarity score is above your threshold (e.g., > 0.92), return the cached response. Fallback and store: If no match is found, send the prompt to the LLM, return the response to the user, and store the new embedding and response in Redis Conceptual Python Implementation How the logic flows using standard redis-py and OpenAI: Python import redis import numpy as np from openai import OpenAI from redis.commands.search.query import Query # 1. Initialize Clients redis_client = redis.Redis(host='localhost', port=6379, decode_responses=True) openai_client = OpenAI(api_key="YOUR_API_KEY") # Configuration THRESHOLD = 0.95 # 95% similarity required for a cache hit INDEX_NAME = "prompt_cache_idx" def get_embedding(text): """Convert text to an embedding vector.""" response = openai_client.embeddings.create( input=text, model="text-embedding-3-small" ) return np.array(response.data[0].embedding, dtype=np.float32).tobytes() def check_semantic_cache(prompt_text): """Search Redis for a semantically similar prompt.""" query_vector = get_embedding(prompt_text) # Construct a KNN Vector Search Query in Redis q = Query(f"*=>[KNN 1 @prompt_vector $vec AS score]")\ .return_fields("response", "score")\ .sort_by("score")\ .dialect(2) res = redis_client.ft(INDEX_NAME).search( q, query_params={"vec": query_vector} ) if res.docs: # Redis returns distance (0 is perfect match). Convert to similarity. similarity = 1 - float(res.docs[0].score) if similarity >= THRESHOLD: print(f"✅ Cache Hit! (Similarity: {similarity:.2f})") return res.docs[0].response print("❌ Cache Miss.") return None def store_in_cache(prompt_text, llm_response): """Store the new prompt and response in Redis.""" prompt_vector = get_embedding(prompt_text) # Store as a Redis Hash doc_id = f"cache:{hash(prompt_text)}" redis_client.hset(doc_id, mapping={ "prompt": prompt_text, "response": llm_response, "prompt_vector": prompt_vector }) # Optional: Set a Time-To-Live (TTL) so the cache clears old entries redis_client.expire(doc_id, 86400) # 24 hours Best Practices for Production Use a library: Instead of writing the raw vector math and RediSearch queries yourself, use RedisVL (pip install redisvl) or LangChain's Redis Cache integration. They have built-in SemanticCache classes that handle index creation and threshold tuning with just 3 lines of code. Tune your threshold carefully: A threshold that is too low (e.g., 0.80) will cause "false positives" (returning an answer to a question that is only vaguely related). A threshold too high (e.g., 0.99) defeats the purpose, acting almost like an exact-match cache. Test with 0.92 to 0.95 as a baseline. Filter by user/tenant: If you are building a multi-tenant app, make sure to add metadata tags (like user_id or tenant_id) to your Redis hashes. Your vector query must pre-filter by the user_id, so User A doesn't accidentally get a cached response meant for User B. Cost Savings by Major Provider LLM providers apply discounts specifically to input tokens that hit the cache (output tokens are always billed at the standard rate) Real-World Impact and Key Benchmarks Enterprise scale: One of the big Tech companies, like TikTok, has reported cutting their AI agent inference costs by 50% with minimal code adjustments. Agentic architectures: For complex, long-running agentic workflows (where a system prompt and conversation history are repeatedly sent over dozens of steps), prompt caching typically achieves 78% to 81% total cost reductions because the massive system instructions only need to be processed once. Break-even point: On platforms like Anthropic (which charge a 25% premium to write to the cache), you only need to hit the cache twice on a given prompt prefix to break even and start saving money. Every subsequent read is essentially 90% off. In addition to saving money, prompt caching dramatically improves user experience by skipping the heavy "prefill" computation. It reduces Time-to-First-Token (TTFT) by 50% to 85%, meaning long documents or extensive chat histories return responses in a fraction of a second instead of causing a noticeable delay. Take Action: Build Smarter AI Applications Prompt caching is no longer an optional optimization—it’s a competitive advantage for organizations deploying AI at scale. If you’re building enterprise AI applications, evaluate where repetitive prompts exist and redesign your prompt architecture to maximize cache utilization. Small changes in prompt design can lead to significant savings in cost, latency, and compute resources.

By Ravi Ranjan Shahi
Replacing JSON With Protobuf in Your Microservice Mesh: A Zero-Downtime Migration Blueprint
Replacing JSON With Protobuf in Your Microservice Mesh: A Zero-Downtime Migration Blueprint

When engineering teams build distributed systems, they naturally reach for REST over HTTP/1.1 with JSON payloads. JSON is readable, universally supported, and trivially easy to debug with any browser or proxy tool. For early-stage services handling modest traffic, that convenience is a genuine engineering asset. But as microservice topologies scale toward hundreds of nodes handling tens of thousands of concurrent requests, text-based serialization frequently evolves from a minor convenience into a measurable architectural bottleneck. CPU utilization climbs, p99 latencies widen, and intra-zone bandwidth costs quietly compound across every internal service hop. Transitioning internal service-to-service communication to Protocol Buffers (Protobuf) over HTTP/2 via gRPC is one of the most effective and high-leverage responses to this problem. This article breaks down exactly why JSON degrades at scale, how Protobuf's binary wire format addresses those root causes, and how to execute a zero-downtime migration without breaking your running services. The Hidden Cost of Text-Based Serialization at Scale To understand why JSON degrades at high throughput, you have to look past network bandwidth and examine CPU behavior directly. JSON is a text-based, schema-less format. Every time a microservice ingests a JSON payload, the runtime must allocate memory on the heap, parse raw strings, map keys to internal structs via reflection, and convert values to their respective data types. At low volumes, this parsing overhead is negligible. At enterprise scale, it compounds into a real problem across two distinct dimensions. 1. CPU-Bound Allocation and GC Churn In languages with managed memory runtimes, such as Go, Java, and Node.js being the most common in microservice architectures, parsing thousands of large JSON strings per second causes significant garbage collection pressure. Each incoming payload generates a burst of short-lived string allocations on the heap. The garbage collector is forced to run more frequently to reclaim this memory, and in runtimes that use stop-the-world collection phases, this directly spikes p99 tail latencies. The problem is not that JSON parsing is intrinsically slow on a single call. The problem is that at scale, thousands of calls per second accumulate into sustained allocation pressure that the GC cannot absorb cleanly. 2. Network Payload Bloat JSON payloads are structurally verbose because every single message must explicitly include field names as strings. Consider this representative internal service message: JSON { "transaction_id": "tx_9988112233", "account_status": "ACTIVE", "retry_count": 3 } On the wire, this payload consumes roughly 85 bytes. More than half of those bytes (over 50) are dedicated purely to transmitting key metadata: the strings "transaction_id", "account_status", and "retry_count". These keys carry no runtime information that the receiving service doesn't already know from its own code. They are structural overhead repeated on every single message. Multiply this across millions of internal RPC calls through a service mesh and you are looking at gigabytes of redundant key data transmitted intra-zone every day. That's bandwidth you are paying for and CPU cycles you are spending to parse, without gaining any informational value. The Mechanics of the Binary Shift: Why Protobuf Moves the Needle Protocol Buffers eliminate text overhead by relying on a strict Interface Definition Language (IDL) and a highly compressed binary wire format. Instead of transmitting field names, Protobuf assigns each field a unique integer tag. When a message is serialized, the keys are stripped out entirely. The wire representation of any field is just its integer tag combined with a wire type identifier, followed by the raw data bytes. The equivalent of the JSON example above looks like this as a .proto definition: ProtoBuf syntax = "proto3"; message AccountTransaction { string transaction_id = 1; string account_status = 2; int32 retry_count = 3; } The same AccountTransaction message with the values tx_9988112233, ACTIVE, and 3 serializes to approximately 24 bytes on the wire — a reduction of roughly 72% compared to the JSON equivalent. Varints and Length-Delimited Encoding Two specific encoding techniques drive most of that size reduction. Varints (Variable-Length Quantities): Standard integers occupy a fixed 4 or 8 bytes regardless of their actual value. Protobuf varints use the most significant bit as a continuation flag, meaning small integers consume fewer bytes than large ones. The value 3 in the retry_count field above occupies exactly one byte on the wire. For the high-frequency small counters and status codes typical in microservice messages, this is a consistent win. Length-delimited encoding: Strings and nested messages are encoded with an explicit byte-length prefix followed by the raw byte block. The parser reads the tag, reads the length, and copies the exact memory block directly. There is no tokenization, no string-splitting, and no key-to-field mapping via reflection. This direct memory copy approach is what makes Protobuf deserialization significantly faster than JSON parsing in practice. Benchmarks from the go_serialization_benchmarks project (available on GitHub) consistently show Protobuf outperforming standard library JSON by 4–8x in throughput on typical message shapes. Architectural Trade-Offs: When to Move and When to Wait Migrating to Protobuf is not a universal improvement. It introduces distinct operational trade-offs that teams should evaluate honestly before committing. MetricJSON over HTTP/1.1Protobuf over HTTP/2 (gRPC)Human readabilityNative — clear text in proxy logsRequires compiled schemas or tooling like grpc-curl or protoscope to inspectSchema enforcementOptional — JSON Schema is separate from the formatMandatory — enforced at build time via protoc compilationNetwork efficiencyLow — verbose string keys on every messageHigh — packed binary tag-value pairs, no key transmissionCPU utilizationHigh — heap allocation, reflection, and string parsingLow — direct memory copies and varint arithmeticDebugging overheadLow — any HTTP tool worksHigher — binary streams require schema-aware toolingSchema registry costNone — ad hoc contract managementReal — .proto files must be versioned and distributed across teams The debugging and schema-management costs deserve emphasis because they are frequently underestimated. In a JSON-based system, any engineer can inspect a live request in a proxy log or with curl. In a Protobuf system, you need the compiled schema available to decode what is on the wire. Teams that invest in a proper schema registry and standardize on tools like grpcurl absorb this cost smoothly. Teams that don't will find debugging production issues significantly harder. The Edge vs. Mesh Topology Split The most pragmatic migration approach keeps JSON at the public API boundary while adopting Protobuf exclusively for internal service-to-service traffic. The API Gateway acts as the translation layer: it terminates public-facing REST/JSON requests from browsers and mobile clients, validates the incoming payloads, and transforms them into strongly-typed Protobuf messages before routing them across the internal service mesh. Public consumers never see binary formats. Internal services get the full efficiency benefit. This topology preserves external interoperability while capturing the performance gains where they matter most, which is inside the mesh, where requests fan out across many hops. Executing a Zero-Downtime Migration The core challenge in any serialization migration is that you cannot atomically redeploy every service simultaneously. Services must continue communicating during the transition. The following phased approach handles this safely. Phase 1: Dual-Stack Services Update each internal service to accept both JSON and Protobuf requests simultaneously, using the Content-Type header to distinguish them (application/json vs. application/x-protobuf). This is the strangler fig pattern applied to serialization. No existing traffic breaks, and you can validate Protobuf behavior against live traffic without fully cutting over. Phase 2: Canary Routing Once dual-stack services are deployed, route a small percentage of internal traffic, start with 1–5%, to the Protobuf path. Monitor p99 latency, error rates, and deserialization failure metrics at the canary boundary. This is the moment where schema mismatches and field mapping errors surface, and it is far better to find them at 1% traffic than at 100%. Phase 3: Full Cutover and JSON Deprecation After the canary validates correctly over a sufficient observation window (typically one to two release cycles), shift all internal traffic to Protobuf. Maintain the JSON code path for a deprecation period to support any lagging consumers, then remove it once all services confirm clean Protobuf-only communication. Mapping JSON Structures to Proto3 When moving from a schema-less JSON environment to a typed Proto3 environment, data structures need explicit definition. Here are the most common mapping decisions. Primitive and Complex Types Numbers: Map floating-point values to double or float. Map integers to int32, int64, or uint32. If values can be negative and small (common for status codes or offsets), use sint32 or sint64, which apply ZigZag encoding to make negative varints more compact.Arrays: Represent repeated values with the repeated keyword.Maps: Use the native map<string, string> syntax. Note that map fields cannot be marked as repeated. Bootstrapping Proto Definitions From Existing Payloads When you are migrating an existing system with dozens or hundreds of active message models, writing .proto definitions by hand from legacy JSON schemas is tedious and error-prone, especially when the source payloads contain deeply nested objects, polymorphic arrays, or inconsistent field naming conventions. A practical shortcut during the early scaffolding phase is to use a JSON-to-Protobuf converter utility. You feed in a representative sample payload, and it generates a baseline .proto definition that matches the field names, infers appropriate types, and assigns initial field numbers. The output is not final. You will still need to review type choices, apply sint32/sint64 where appropriate, and add optional markers for nullable fields, but it eliminates the mechanical first pass and lets engineers focus on the decisions that actually require judgment. This is particularly useful when onboarding a new team member to the migration or when tackling a legacy service whose JSON schema was never formally documented. Handling the Absence of Native Nulls Proto3 does not have a native null state for primitive types. Unset fields default to their zero value — empty string "" for strings, 0 for integers. In systems where an unset field and a zero-value field carry different semantic meaning, this distinction matters. Two approaches address this. The first is the optional keyword, which wraps the primitive in a field-presence tracker that lets the receiver distinguish "this field was not set" from "this field was set to zero": ProtoBuf syntax = "proto3"; message PaymentRecord { string payment_id = 1; optional int32 discount_percentage = 2; // Distinguishes "no discount" from "0% discount" } The second is Google's well-known wrapper types, which provide nullable primitives at the cost of a more verbose message structure: ProtoBuf import "google/protobuf/wrappers.proto"; message ExtendedTransaction { string id = 1; google.protobuf.StringValue middle_initial = 2; // Nullable string } For most use cases, optional is the cleaner choice. Wrapper types are useful when you need to nest nullable primitives inside repeated fields or maps. Managing Schema Evolution Without Breaking Running Services In a distributed environment with independent deployment cycles, schema changes are inevitable and dangerous if handled carelessly. Protobuf addresses this through strict backward and forward compatibility rules, but only if you respect two absolute constraints. Never change field numbers. The binary parser maps incoming bytes to fields purely by tag integer. If you change a field number on a deployed message, existing services will misread the data silently and without error. Never change the wire type for an existing tag. If a field needs to change from int32 to string, you must deprecate the old tag and introduce a new field with a new field number. Beyond those hard rules, backward compatibility allows you to add new fields freely. A service that receives a message with an unknown field number will simply ignore it. This means services can be updated independently and out of order without breaking communication, which is a critical property in a rolling deployment environment. Graceful Deprecation in Practice When phasing out an existing field, mark it with the deprecated option rather than deleting it. This preserves binary compatibility for services still reading the field while alerting downstream teams through compiler warnings: ProtoBuf message UserContext { string user_id = 1; string legacy_token = 2 [deprecated = true]; // Superseded by session_hash; remove after Q3 cutover string session_hash = 3; } Do not reuse the field number after deprecation. Reserve it explicitly using the reserved keyword to prevent future developers from accidentally reusing a tag that old binary data may still contain: ProtoBuf message UserContext { reserved 2; reserved "legacy_token"; string user_id = 1; string session_hash = 3; } Concrete Implementation: Deserializing Protobuf in Go The following example shows a typical internal Go service handler receiving and deserializing a Protobuf message using the current v2 API (google.golang.org/protobuf/proto). Note: the v1 package (github.com/golang/protobuf) is archived and should not be used in new code. Go package main import ( "fmt" "log" "time" "google.golang.org/protobuf/proto" pb "path/to/generated/pb" // Pre-compiled .pb.go output from protoc ) func processPayload(rawBytes []byte) (*pb.AccountTransaction, error) { transaction := &pb.AccountTransaction{} // Unmarshal reads binary data directly into the struct without string parsing if err := proto.Unmarshal(rawBytes, transaction); err != nil { return nil, fmt.Errorf("deserialization failed: %w", err) } if transaction.GetTransactionId() == "" { return nil, fmt.Errorf("missing required field: transaction_id") } return transaction, nil } func main() { // This binary slice is the wire encoding of: // transaction_id: "tx_9988112233", account_status: "ACTIVE", retry_count: 3 // Generated via proto.Marshal on the populated AccountTransaction struct sampleBinaryPayload := []byte{ 10, 13, 116, 120, 95, 57, 57, 56, 56, 49, 49, 50, 50, 51, 51, 18, 6, 65, 67, 84, 73, 86, 69, 24, 3, } start := time.Now() tx, err := processPayload(sampleBinaryPayload) if err != nil { log.Fatalf("processing failure: %v", err) } fmt.Printf("Processed transaction %s in %v\n", tx.GetTransactionId(), time.Since(start)) } The key difference from JSON unmarshaling is in what proto.Unmarshal does not do: it does not tokenize strings, does not map keys via reflection, and does not allocate intermediate string representations. It reads the tag, determines the field type from the compiled schema, and copies raw bytes directly to the target struct field. At high throughput, that distinction in allocation behavior is what drives the difference in GC pressure and tail latency. What This Migration Actually Solves, and What It Does Not Protobuf is not a solution to every distributed systems problem. It will not fix poorly designed service boundaries, reduce round trips caused by chatty interfaces, or compensate for network topology problems. What it specifically addresses is the serialization and deserialization overhead on hot paths where internal services are exchanging high volumes of structured messages. The teams that see the clearest wins are those where profiling has confirmed that serialization CPU time is a meaningful contributor to request latency, and where payload sizes have made bandwidth a real infrastructure cost. If your p99 latency problems trace to database queries, downstream API calls, or lock contention, the Protobuf migration will have minimal impact on those numbers. Start by profiling your highest-traffic internal endpoints. Measure serialization time as a fraction of total request time. Measure payload sizes across a representative sample of production traffic. If the data shows serialization is a genuine bottleneck, the migration is well-justified. If it is not, the operational investment in schema management and tooling upgrades may not pay off on the timeline you need. For the services where it does make sense, the gains are real and durable. Lower CPU utilization, reduced GC pressure, smaller payloads across every internal hop, and strongly typed contracts enforced at build time; these compound over time as traffic grows. Summary The path from JSON to Protobuf is not about chasing a trend. It is a deliberate architectural decision to eliminate serialization overhead on hot internal paths by replacing text parsing with direct binary memory operations. The practical steps are straightforward: audit your highest-traffic internal endpoints, define your .proto schemas with careful attention to field numbering and null semantics, deploy dual-stack services to enable a phased cutover, and establish tooling for schema versioning before your team's first production deployment. The operational costs are real but manageable. Binary streams require schema-aware debugging tools, .proto files need disciplined version management, and the reserved keyword must become part of your deprecation workflow. Teams that treat schema governance as a first-class concern alongside their code absorb these costs smoothly. For distributed systems where internal traffic volume makes serialization overhead measurable, the migration consistently delivers: lower tail latency, reduced bandwidth spend, and contracts that fail loudly at compile time rather than silently at runtime.

By Bansidhar kadiya

Monthly Top Data Experts

expert thumbnail

Brian O'Neill

Technical Writer,
Cloudmersive

A Technical Writer and Media Content creator with a passion for communicating complex ideas.
expert thumbnail

Fawaz Ghali, PhD

Fawaz Ghali is an independent applied AI technologist with over 25 years of experience spanning AI research, higher education, and industry delivery. He works at the point where enthusiasm has faded, tools have been tried, and AI initiatives are expected to deliver real value. Holding a PhD in Computer Science, Fawaz has led and contributed to applied AI, data engineering, and distributed systems across academia and industry. He has published 45+ peer-reviewed papers and delivered over 300 talks worldwide, focusing on what actually works once AI meets real data, real constraints, and real organisational pressure. Fawaz speaks and teaches independently, without vendor affiliation or sales agendas. His sessions are direct, evidence-based, and deliberately free of marketing, product promotion, or speculative claims, offering audiences clarity, critical evaluation, and hard-earned insight grounded in practice rather than hype.

The Latest Data Topics

article thumbnail
Jakarta Batch in Practice: Reliable Chunk-Oriented Processing for Enterprise Workloads
Jakarta Batch gives enterprise apps a standard model for long-running data processing with jobs, steps, readers, processors, writers, checkpoints, and tunable execution.
September 29, 2026
by Otavio Santana DZone Core CORE
· 584 Views
article thumbnail
The Warning That Never Stops the Agent
Deepagents tracks real session cost but only shows a toast. Nothing stops the loop from spending past a limit. A before_model hook that can jump to "end" closes that gap.
September 29, 2026
by Ninaad Rao DZone Core CORE
· 441 Views
article thumbnail
Beyond Screenshots: Building Replayable Production Diagnostics for Hard-to-Reproduce Bugs
Capture privacy-safe production event timelines to reconstruct failures, correlate backend activity, and diagnose bugs that screenshots cannot explain reliably.
September 28, 2026
by Uthej Mopathi DZone Core CORE
· 421 Views · 1 Like
article thumbnail
Prompt Caching Doesn't Save Money on Turn One
Cache writes cost 1.25x the input price, and reads cost 0.1x. So a fresh conversation's first turn is more expensive with caching on.
September 25, 2026
by Ninaad Rao DZone Core CORE
· 1,071 Views · 1 Like
article thumbnail
Locking Down the Enterprise: Data Security Patterns for AI Integrations
Learn how to secure enterprise data in AI systems using data classification, access controls, encryption, vendor controls, prompt security, and output validation.
September 25, 2026
by Balaji Venkatasubramaniyar DZone Core CORE
· 1,297 Views
article thumbnail
How to Prevent Retry Storms With Retry Budgets in Distributed Systems
Retry budgets coordinate retries across service boundaries, preventing transient failures from escalating into system-wide traffic amplification.
September 23, 2026
by Uthej Mopathi DZone Core CORE
· 1,698 Views · 2 Likes
article thumbnail
Exploring the DBMS_DEVELOPER Package: JSON Metadata for Oracle Objects
Learn how Oracle Database 23ai’s DBMS_DEVELOPER package uses JSON metadata and ETags to simplify database schema documentation, migration, and change tracking.
September 18, 2026
by arvind toorpu DZone Core CORE
· 2,165 Views
article thumbnail
RAG, Vector Databases, and MCP: Wiring Them Together for Production
This article offers a practical walkthrough for engineers moving past the "RAG demo" stage into systems that hold up in production.
September 18, 2026
by Balaji Venkatasubramaniyar DZone Core CORE
· 2,892 Views
article thumbnail
Common Pitfalls in RAG Applications: What to Avoid When Using Vector Search and Embeddings
RAG is easy to launch and hard to keep reliable. Here are the most common failure modes, their causes, and the Databricks-specific fixes.
September 17, 2026
by Seshendranath Balla Venkata
· 2,564 Views
article thumbnail
Why Real-Time Data Pipelines Are Becoming the Foundation of Industrial AI
Real-time data pipelines enable trustworthy industrial AI through continuous context. They ensure the right data reaches the model at the right time.
September 16, 2026
by Ajay Kumar Govindaram
· 2,768 Views · 1 Like
article thumbnail
Architecting Production AI Across Clouds: Patterns That Decide System Survival
In production, enterprise AI rarely fails at the model. It fails in the architecture around it. Here are the cross-cutting patterns that work.
September 16, 2026
by VenkataSrinivas Kantamneni
· 2,730 Views
article thumbnail
Freshness Is the Missing SLO in Production Vector Search
Standard metrics can look healthy while an index still serves stale data, because freshness depends on the entire pipeline, not just query speed.
September 15, 2026
by Guru Hegde
· 2,323 Views
article thumbnail
KV Cache vs Prompt Cache: What's the Difference, and How Are They Related?
KV cache avoids recomputing historical token states during generation, while prompt cache reuses identical prompt prefixes across requests to reduce latency and cost.
September 15, 2026
by Jake Tao
· 2,331 Views · 1 Like
article thumbnail
dbt Meets Apache Flink: One Workflow for Data Engineers
dbt meets Apache Flink: one SQL workflow for data engineers across Snowflake, BigQuery, Databricks, and real-time streaming pipelines on Confluent Cloud.
September 15, 2026
by Kai Wähner DZone Core CORE
· 1,839 Views
article thumbnail
Data Governance for the Agentic Era
This article explores how modern data governance and AI-ready architecture help enterprises manage data quality, risk, compliance, and AI at scale.
September 14, 2026
by Dr Gopala Krishna Behara DZone Core CORE
· 2,290 Views · 2 Likes
article thumbnail
Building a 2KB Histogram with Sub-0.2% Percentile Error
It uses float-like encoding for O(1) bucket indexing and trapezoid interpolation for accurate percentile estimation — with no floating-point math on the recording path.
September 14, 2026
by bingxi Wu
· 1,084 Views · 1 Like
article thumbnail
Freshness as a First-Class Schema Concern: Modeling Data Staleness Across 83 Data Sources
How I modeled data freshness as a first-class schema concern across 83 sources, so the atlas never lies about how old its numbers are.
September 14, 2026
by Josie Leung
· 1,450 Views
article thumbnail
Prompt Caching: Overriding Tokenization for Faster and More Cost-Effective AI
Prompt caching allows AI systems to reuse the processing of unchanged token sequences, resulting in faster inference, lower latency, and reduced costs.
September 11, 2026
by Ravi Ranjan Shahi
· 3,459 Views
article thumbnail
Replacing JSON With Protobuf in Your Microservice Mesh: A Zero-Downtime Migration Blueprint
JSON hurts at scale. Protobuf cuts payload size by ~72%, reduces CPU overhead, and enforces typed contracts. However, it needs careful schema management.
September 11, 2026
by Bansidhar kadiya
· 3,084 Views · 2 Likes
article thumbnail
Improving Repeated Analytics Workloads With Databricks Disk Cache
Databricks disk cache speeds up repeated reads from curated Parquet or Delta tables, but it works best with good table design and partitioning.
September 11, 2026
by Harsh Patel
· 2,308 Views
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • ...
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×