AgileLog: A Forkable Shared Log for Agents on Data Streams
arXiv:2604.14590v1 [cs.DC] 16 Apr 2026
Shreesha G. Bhat, Tony Hong, Michael Noguera, Ramnatthan Alagappan, Aishwarya Ganesan University of Illinois Urbana-Champaign Abstract. In modern data-streaming systems, alongside traditional programs, a new type of entity has emerged that can interact with streaming data: AI agents. Unlike traditional programs, AI agents use LLM reasoning to accomplish highlevel tasks specified in natural language over streaming data. Unfortunately, current streaming systems cannot fully support agents: they lack the fundamental mechanisms to avoid the performance interference caused by agentic tasks and to safely handle agentic writes. We argue that the shared log, the core abstraction underlying streaming data, must support creating forks of itself, and that such a forkable shared log serves as a great substrate for agents acting on streaming data. We propose AgileLog, a new shared log abstraction that provides novel forking primitives for agentic use cases. We design Bolt, an implementation of the AgileLog abstraction, that uses novel techniques to make forks cheap, and provide logical and performance isolation.
1
unstructured streaming data [43–45]. Agents can also use LLM capabilities to generate contextually relevant test events and inject them into streams for testing purposes [31, 79]. Agents, however, introduce new problems for streaming systems. First, agents, unlike traditional tasks, are exploratory in nature: they explore many steps and paths to accomplish a task [59, 84]. Further, with the ease of building agents, many agents would operate on the system simultaneously [49, 84]. Combined, these two aspects cause agents to place significant load, creating performance interference for other workloads, which the system must mitigate. Second, writes performed by agents can be incorrect because LLM-informed actions can be inaccurate [78, 84, 114]; this causes correctness issues for applications consuming the data. Thus, the system must isolate and validate agentic writes before allowing them to take effect. Further, agents may explore many write paths and choose one. The system must thus safely allow such exploration. Finally, to enable coding and testing agents to build and test stream-processing applications, the system must provide sandboxes with realistic data. Unfortunately, today’s streaming systems lack mechanisms to meet these needs. The above problems are not specific to streaming systems; agents create similar issues for any data system they interact with [84]. To address some of these problems, a few recent databases [6, 12, 48], object stores [10, 11], and lakehouses [122] provide forking as a primitive to create isolated copies of the data system on which agents can safely operate. Inspired by these systems, we argue that, shared logs, the core storage abstraction underlying streaming data, must also support creating isolated forks of itself to better support AI agents operating on streaming data. With such a forkable shared log, each agent can operate on its own fork, while traditional applications operate on the main shared log, enabling performance isolation. Forks also enable safe handling of agentic writes: an agent’s writes can be isolated on a fork, and then integrated after validation into the main log. Similarly, an agent can explore many write paths in parallel on different forks, isolated from each other and the main log. Finally, each fork naturally is a coding/testing sandbox with real data. Based on this, we propose AgileLog, a new shared log abstraction that offers forking as a core primitive. A fork in AgileLog is a cheap, logically separate, and performanceisolated child copy of the main shared log that can be read and appended (just like its parent), and in turn, itself be forked. Besides being the first forkable shared log, a key novelty in AgileLog is a new form of forks that we call continuous forks. The usual notion of forks in prior forkable data systems is
Introduction
Shared logs [35, 51, 70, 86] are the fundamental building blocks that underpin data-streaming systems [8, 19, 75, 105]. Typically, upstream sources ingest data into the shared log, which orders and makes the data durable. Many downstream applications then consume the data from the shared log and process it for many purposes like real-time analytics [99], ML inference [129], search [126], and others [33, 60]. With the advances in reasoning capabilities of large language models (LLMs), a new kind of entity has emerged that can interact with streaming data: AI agents. Agents differ from “traditional” entities in how they operate. The behavior of a traditional application interacting with streams is defined in advance by programmers: it follows fixed logic to produce and consume records, process the consumed data, and generate outputs. In contrast, AI agents can accomplish high-level tasks on streaming data, specified in natural language. Rather than following fixed instructions, the agent uses LLM reasoning to determine on-the-fly what sequence of steps will help achieve its goal. The agent then exercises its ability to invoke external tools [84, 111] to execute the LLM-informed steps on streams. Today, many practical streaming systems allow AI agents to read and write streaming data [14, 41, 102, 120]. Agents interacting with streaming data unlock a variety of use cases. For example, agents allow users who do not write code to run ad-hoc data-analysis tasks on streaming data specified in natural language [79, 103, 108]. Similarly, agents can use LLM intelligence for ambiguous tasks on 1
that the parent and the child are disconnected from each other at the fork point: while the parent and child share the state up to the fork point, after the fork, the writes on the parent are not visible to the child and vice versa. However, this is insufficient for agents acting on real-time, streaming data. Consider an agent performing streaming analytics on a fork. For the agent to keep producing up-to-date results, the fork must continue to see the real-time data from the parent log that is ingested even after the fork point. For this purpose, AgileLog offers continuous forks (or cForks). A cFork shares the history with its parent up to the fork point but, importantly, continuously inherits all further appends on the parent as well. A cFork can also be appended to, but those records remain private to the fork. cForks thus provide a unique unidirectional write isolation: records ingested into the parent are visible to the child but not the other way around. Thus, agents performing writes can do so on a cFork, safely isolated from the parent, and consumers of the parent will not see those records. A key property of cForks is that the records appended on a cFork are linearizably interleaved with the inherited parent records. This is useful for correctly interleaving agentic writes on a fork with non-agentic writes on the parent. In use cases like testing, agentic writes are synthetic and thus remain private to the cFork forever. However, in use cases where agents produce actual data, the writes need to be integrated into the main log. AgileLog thus provides a way to promote a cFork (after necessary validation) as the parent. Promote is also useful with exploration: agents can explore different write paths on different cForks and finally promote one. In addition to cForks, AgileLog also offers a (regular) severed fork, where the child and parent are disconnected after the fork point. Overall, AgileLog’s primitives help satisfy the needs of various agentic use cases over streaming data. We build Bolt, an implementation of the AgileLog abstraction. Bolt must satisfy two basic requirements. First, creating forks must be cheap and quick. Second, forks must be isolated in performance: agentic tasks on child forks should not interfere with workloads on the parent. Since forks must be cheap, any design that copies data to create a fork is a nonstarter. To avoid the copy, one could host a fork on the same set of storage servers that host the main shared log so that the fork and the parent can share the same underlying data. This design, however, will suffer from performance interference. We instead realize that the recent “diskless” shared-log architecture [47, 72, 133] offers a promising foundation for Bolt. Diskless shared logs use stateless brokers that make records durable on cloud object stores (e.g., S3) instead of local disks. A fault-tolerant metadata layer then sequences the durable records, and maintains the log metadata: an index that maps log positions to shared-storage objects. Bolt adopts this diskless architecture to make forks cheap and performanceisolated. Specifically, Bolt creates a fork with zero-data-copy by instantiating a fork’s metadata to be the same as that of the parent log, making the fork point to the same objects
on shared storage as the parent. Bolt then serves reads and appends to the fork on a separate broker; because the parent and forks are hosted on separate brokers and because cloud object stores scale well, Bolt cleanly isolates the performance of the parent and the forks. While the diskless architecture provides a good base, Bolt must address important challenges. First, even just copying metadata to create a fork can be slow. Bolt makes fork creations truly low-latency by avoiding even metadata copies via a new hierarchical log index technique. Another major challenge is to implement cForks correctly and efficiently. A cFork must continuously inherit records from the parent and must linearizably interleave them with its own appends. This must be efficient: even with many cForks, there should be little impact on the parent’s performance. Bolt implements cForks by carefully sequencing the metadata of parent’s new records into the child’s metadata, without data copies. Bolt optimizes this idea with new techniques like tail-only updates and lazy-tail propagation. The end result is that a parent log can have many cForks with little to no performance impact. Our experiments show that Bolt can create forks quickly. Bolt also effectively isolates the performance of workloads on the parent log from agentic tasks. Bolt’s techniques help maintain the parent log’s high performance even with 100s of cForks. We build three real agents powered by LLMs: an ad-hoc analytics agent for IoT data, a stream-processor testing agent, and a supply-chain-management agent. Bolt provides performance isolation and enables safe handling of agentic writes in these applications. In contrast, Kafka, a popular shared log for data-streaming, suffers from interference (e.g., 14× and 130× higher mean and p99 latencies), and consumer failures when agents produce problematic records. Contributions. This paper makes four contributions. • We articulate how a forkable shared log serves as a better substrate for agents interacting with streaming data. • We present AgileLog, the first forkable shared log. AgileLog offers a novel form of fork called continuous forks and primitives for integration and exploration of agentic writes. • We build Bolt, an AgileLog implementation that realizes cheap and performance-isolated forks by adopting a diskless architecture. It uses novel techniques like hierarchical log indexes, tail-only updates, and lazy-tail propagation. • We show that AgileLog benefits real agentic applications.
2
Background
We describe the role of shared logs in data streaming, and explain the trend of AI agents interacting with streaming data. 2.1
Shared Logs and Data Streaming
Shared logs [34–36, 51, 70, 86, 92] offer an abstraction of a durable and linearizably [67] ordered sequence of records. Shared logs expose a simple API. Clients can append records, upon which the records are ordered and made durable. Clients 2
can read records at given positions in the sequence. Shared logs are the core storage abstraction underlying data-streaming systems [36, 74, 75, 132, 141]. These systems support many applications like fraud monitoring [33, 95], real-time analytics [99] and search [126], and live inference [83, 129]. In all these applications, upstream sources ingest data into the shared log. Downstream applications then consume the data from the shared log and process it. Shared logs have gained significant attention in research and many research implementations [35, 51, 70, 85, 86] exist today. Many practical shared logs exist as well. Kafka [27] is perhaps the most widely used, but others [28, 30, 61, 98] are also popular. 2.2
tinuously fetching new records, while point-in-time queries require access only up to a specific point in the stream. Real-Time Context Access. As many applications become agentic, they require the latest events happening in an organization to get real-time context [50, 55, 71, 110] to make accurate decisions [42, 123]. For example, an agentic orderfulfillment application requires access to real-time inventory status [55]. As in the previous use case, agents may iteratively probe and read streams to construct the required context. Agentic Stream Processing. Stream processors are longrunning programs that consume records from streams, act on them, and continuously write outputs to other streams. Traditionally, stream processors are hand-coded programs (e.g., Flink jobs [2] or Pulsar functions [3]). However, LLMpowered agents can also act as stream processors, particularly for tasks over unstructured, heterogeneous data. For example, an agent can act as a content-moderation processor to identify inappropriate images [45]. Here, the agent would invoke the LLM on each image from the input stream and write its reasoning and decision to an output stream. Downstream consumers (either traditional or agentic) then act on the output stream. Similar examples of agentic stream processing for customer support [44], supply chain [56], and fraud-risk analysis [43] exist as well. Unlike prior use cases, where agents only read streams, here, they both read and write to streams.
AI Agents Interacting with Streaming Data
Recent improvement in LLMs’ reasoning abilities [65, 134] has enabled the widespread adoption of AI agents. AI agents are systems that couple LLMs’ reasoning with the agency to take actions, such as invoking external tools, maintaining state, and coordinating with other agents [111, 138]. The ability to invoke external tools, in particular, has enabled AI agents to interact with data systems. With this ability, AI agents today can interact with databases [48, 84, 89, 115], object stores [10, 11], lakehouses [122], and warehouses [32, 125, 128]. They can perform a variety of data tasks like retrieval, analysis, and manipulation [38, 49, 54, 84, 97]. Adoption of agents for data tasks is rapidly growing; for example, a recent survey shows that many companies now use agents for data tasks and that a vast majority of databases within organizations are created and operated upon by AI agents [49]. Unsurprisingly, agents have also started interacting with streaming data systems. Today, many practical systems support agentic access to streaming data [14, 41, 102]. They do so via the Model Context Protocol (MCP) [26, 68]: each system provides an MCP server through which agents can read from and write to data streams [1, 13, 20, 79, 80, 107].
3
Agents on Streams: Use Cases and Problems
3.1
Real Use Cases
Agentic Coding & Testing of Stream Applications. Instead of having agents themselves operate on streams, one could now use AI coding agents to develop (regular) applications that interact with streams [13, 80, 121]. Agents can synthesize stream processors or streaming SQL from prompts [80]. To build the application, the coding agent interacts with streams: it repeatedly reads the streams (to infer schema and understand the data) and iteratively fixes the code. Such iterative development existed even with hand-coded stream applications [16], but the rate of such iteration will grow with agents. Agents can also be used to test streaming applications. LLMs excel at test generation [23, 39, 96] and thus agents with access to code can generate contextually relevant test cases [17]. Agentic testing is already applied to semantic testing of stream processors: the agent generates and injects test events into the stream, and checks if a stream processor behaves correctly [31, 79, 106]. For example, agents can inject synthetic transactions to test if a fraud-detection model [33, 95] catches evolving fraud patterns [37, 69]. Such testing can be applied to hand-coded programs or during iterative agentic development. Agents also enable schema testing, where events with new schemas are injected to check if processors can handle them. Further, agents can also perform “whatif” counterfactual testing [84]. With LLM aid [82], agents can do what-if tests on real-time data by simulating and injecting different event sequences and observing how downstream outputs change. Testing agents both read and write streams, but the written data is synthetic.
AI agents operating on streaming data enable an array of use cases. We now present these use cases, which we compiled by analyzing real scenarios that practical systems aim to support. Agentic Data Analytics. Agents can analyze streaming data, enabling non-programmers (e.g., sales personnel) to “talk” to data via natural language [38, 48, 54]. Agents can construct on-the-fly dashboards, answer windowed streaming queries, and compute metrics over time [103, 108], as well as handle ad-hoc questions [79] like “what are the trending products in the last 24 hours?” or “show revenue impact of the latest feature deployment” [103]. In these scenarios, with the help of an LLM, the agent decomposes tasks and iteratively determines next steps. For example, based on LLM interaction, an agent may first probe streams to identify contents, sample records to infer schema, then read records for analysis from the target streams. Dashboards and streaming-query tasks require con3
3.2
Agents on Streams: Problems
corner cases. For instance, in the fraud-detector testing use case, the agent must be able to interleave the generated fraudulent test-events within a realistic transaction stream. Similarly, coding agents can produce more accurate code with realistic data. However, today, creating such isolated yet realistic sandboxes with production streaming data is not possible.
Need for Performance Isolation. On the surface, AI agents may appear to be yet another set of clients interacting with streaming data. However, agents have distinguishing characteristics than usual applications. As identified by recent work [59, 84], agentic tasks are exploratory and speculative in nature: agents generate multiple courses of action to accomplish a task. This exploration may occur within a single agent or via an orchestrator spawning sub-agents, each exploring a distinct hypothesis or path. In either case, these paths can be partial attempts at the task, probes to understand the data, suboptimal solutions, or validation of prior steps. While such exploration helps improve the overall accuracy of the agent, it leads to a large number of requests being issued, potentially with suboptimal access patterns [117, 140], which places significant load on the underlying system [62, 63, 84]. Given the ease of building and deploying agents, many agents will operate on a system simultaneously, multiplying this load. This will negatively interfere with traditional production applications, especially latency-critical ones. However, current streaming systems do not provide mechanisms to isolate the performance of traditional workloads from agents.
4
A Forkable Shared Log Abstraction
To better support agents operating on streaming data, we argue that the shared log, the core storage abstraction underlying streaming data, must support creating isolated forks of itself. AgileLog is a shared log abstraction that offers such forking capability. A fork in AgileLog is a cheap, logically separate, performance-isolated child copy of the main shared log. With AgileLog, each agent can operate on its own fork, while traditional workloads operate on the main or root log. This provides performance isolation for workloads on the main log. AgileLog also enables safe handling of agentic writes. Writes performed by an agent on a fork are isolated from the root log, which can be validated before allowing them to take effect on the root log. Further, AgileLog enables simultaneous exploration of different write paths on separate forks. Finally, each fork acts as a sandbox with real data. This section first describes the AgileLog abstraction (§4.1) and then how AgileLog satisfies the needs of use cases from §3.1 (§4.2). The next section (§5) describes the implementation of the AgileLog abstraction that enables forks to be created cheaply and ensures logical and performance isolation.
Need for Safely Handling Agentic Writes. Allowing agents to directly perform writes to a data system can be risky [78, 84, 114, 115]. This is because LLMs can generate inaccurate actions, causing agents to write incorrect data to streams. This, in turn, can lead to incorrect downstream computations based on those writes. Thus, the system must isolate agentic writes from the original stream and validate them (e.g., by a human in the loop or a “reviewer” agent [115, 116]). Only after such validation, the agentic writes must take effect on the stream and consumers must be able to see them. However, current streaming systems do not provide mechanisms to do this. Further, an agent may explore many write paths either because of its inherent exploratory nature or because it uses subagents to explicitly explore different paths. Take the content moderation example. Here, many sub-agents, each powered by a different LLM [64], may explore different ways to analyze the input and produce the output. It must thus be possible to explore these different paths in an isolated manner. Eventually, when a path is chosen as the desired one (e.g., based on result accuracy), it must be possible for the writes in that path to become part of the actual stream. However, today’s streaming systems do not offer such support for exploration.
4.1
AgileLog Abstraction, Interface, and Fork Semantics
An AgileLog instance has a root log, which can be forked to create child copies. Each child can be appended and read (just like its parent), and can itself be forked. Figure 1 shows AgileLog’s interface. AgileLog augments the append and read calls with two new calls for forking: cFork and sFork; these return another AgileLog instance, which can be further forked to create deeper forks. Promote enables writes on a fork to take effect on its parent and squash deletes a fork. Continuous Forks. Typically, a fork means that the parent and the child will be disconnected from each other at the fork point, and data modifications that happen either on the parent or the child will remain private to them. Forks provided by prior databases [4, 5, 12, 48] offer this regular fork semantics. With streaming systems, live data keeps flowing in and agents need to operate on the live stream. Thus, it is insufficient to provide the regular fork, where the child stops seeing new data ingested on the parent after the fork point. Take the real-time streaming query or dashboards examples from the agentic data-analytics use case. To keep producing up-to-date results, the fork where the agent runs must continue to see the appends on the parent even after the fork point. Thus, AgileLog supports a novel form of fork that we call continuous forks or cFork. A cFork shares the history with the parent
Need for Realistic Sandboxes. Coding and testing agents require sandboxes. Testing agents require injecting test events, which must remain isolated from the production stream. Today, agents, for this purpose, create separate synthetic streams. While this provides isolation, testing is done purely over synthetic data. However, practitioners often desire testing using real data [15, 18, 57, 124]. With streaming data, testing is most effective when executed against realistic production data which carries inherent temporal context that helps uncover 4
(a) continuous forks w/o writes
interface AgileLog: // Traditional shared-log API calls. Position append(Record r); List<Record> read(Position from, Position to); // Continuous fork; indicate if this fork is promotable. AgileLog cFork(promotable = false); // Severed fork; optionally can fork from a past offset. AgileLog sFork(optional Position past); bool promote(); // Promote this (promotable) cFork. void squash(); // Delete this fork.
…
A
B
C
D
E
fork
…
A
B
C
D
E E
…
Figure 1: AgileLog Interface.
A
B
C
D
(b) continuous forks with writes …
A
B
C
X
D
root
…
A
B
C
D
E
fork
…
D
Z
A
C
root fork
E
streaming queries, dashboards, real-time context, coding agents
testing agents, agentic stream processing
(c) severed forks w/o writes
(d) severed forks with writes
…
A
B
…
A
B
C
…
A
B
C
fork root
D
fork
…
A
B
P
Q
R
fork
…
A
B
C
D
E
root
…
A
B
C’
D’
E’
fork
point-in-time queries, analytics over past events
log up to the fork point, but it also continuously inherits new appends at the parent after the fork point. While appends in the parent are visible to children, children may want to insert their own records into their forks. Take the testing use case; here, the agent simulates fraud scenarios by injecting fraudulent transactions. By operating on a cFork, the agent can see the original transaction stream and also inject fraud events. However, these events must remain private to the child. cFork provides this required isolation: writes on children forks remain private to them and consumers of the parent will not see them. Thus, cForks enable a unique form of isolation that we call unidirectional write isolation: writes on the parent are visible to the children, but not the other way around. This is in contrast to regular forks provided by prior data systems, where the isolation is bidirectional. Since a cFork inherits records from its parent and also has its own records, how should these records be ordered on the cFork? AgileLog guarantees that appends on a cFork are linearizably [67] interleaved with those on the parent. That is, if an append A finishes on the parent and then B is appended to a cFork, then B is guaranteed to appear after A in the cFork. In some use cases, appends on a cFork remain private to it forever (e.g., a cFork created for testing). However, in some cases, the agentic writes must be reflected on the main log; to enable this, AgileLog allows a cFork to be promoted as the parent (as we discuss below). If such promotion is desired, then the cFork must be created with the promotable flag set. Figure 2(a) and (b) show cFork semantics. In 2(a), the cFork acts as a live read-only copy of the parent. In 2(b), in addition, records are inserted in the live copy (e.g., Z on green fork) that are linearizably interleaved with the parent records. Severed Forks. AgileLog also offers regular forks via a sFork call, where the child is “severed” from the parent after the fork point. By default, a severed fork is created from the current log tail of the parent (at the instant sFork is called); however, it can also be created from a past offset of the parent. In either case, a severed fork shares the parent’s history up to the fork point and it stops seeing further parent updates. Some use cases may not perform writes on a severed fork as shown in 2(c), where the fork acts as a read-only snapshot of the parent. Some use cases write to a severed fork as shown in 2(d). The new records on the fork could be entirely unrelated to the parent’s data (like the yellow fork in 2(d)); or, they could be some perturbations of the parent values (like the green fork).
B
fork
E
(e) promoting a continuous fork
(i)
…
…
D
X
E
…
D
E
validated promote
root
testing agent: what-if counterfactual testing
D
X
E
root
… D
X
…
D
E
D
Y
…
agentic stream processing
E
(ii) …
yellow fork chosen
D
X
E
root
E
agentic stream processing that explores multiple writes paths
Figure 2: AgileLog Primitives. The yellow (upward) and green (downward) arrows are the fork points at which the yellow and green forks were created from the (purple) root log. Writes on the forks are shown in a darker shade. Gray boxes show use cases where a particular primitive is useful.
Squash. Squash deletes a fork and no further operations can be performed on it. For example, it can used to dispose unused sandboxes. AgileLog disallows squash on the root log. Promote. To support use cases where agentic writes must be reflected on the parent, AgileLog offers a promote API. A promote call on a cFork (created with the promotable flag) of a parent makes that fork become the parent itself. Future operations that refer to the parent will now essentially occur on the promoted child and ones that refer to the child are disallowed. sForks or non-promotable cForks cannot be promoted. cFork and promote together enable safe integration of agentic writes. First, agentic writes can be isolated by performing them on a cFork. The cFork can then be validated and promoted. Since AgileLog guarantees linearizable interleaving of agentic writes on the cFork with the parent log’s records, after promotion, the parent log will have the records in the correct order. If validation fails, the cFork is squashed without any problems to the main log or consumers operating on it. One option instead of using a cFork would be to have the agents write to a temporary log, validate the writes there, and then append to the main log. However, this allows only noncontextual, stateless checks of the current agentic writes (e.g., if the schema of the records is correct). In many cases, however, validation requires state: the current agentic writes must be validated along with the records in the main log before the fork and other records on the main log after the fork (ingested by non-agentic producers). cForks and promote enable such stateful validation. Specifically, the cFork will contain the previous records and the writes from non-agentic producers linearizably interleaved with the current agentic writes. Thus, the cFork has the required temporal context for validation. Validation can be done, for instance, by running a copy of the stateful consumer on the cFork to check if it produces desired 5
results. If so, the cFork is promoted; otherwise it is squashed. Even if only stateless validation is required, cFork and promote provide a neat API to validate and reflect agentic writes on the main log, instead of having to manage temporary logs. Figure 2(e)(i) shows how cFork and promote safely handle agentic writes. The agent performs its writes on the yellow fork, which is promoted as the parent after validation. Creating a promotable cFork introduces some restrictions on its parent. These restrictions arise because, after promotion, the parent will have additional records: ones that were inserted into the cFork. Thus, allowing reads on the parent beyond the fork point (before a promotion) could make those reads invalid (after a promotion). For this reason, AgileLog does not allow reads on the parent beyond a promotable cFork’s fork point until the fork is promoted or squashed. For example, in 2(e)(i), consumers on the parent cannot read entries D and beyond. However, once the cFork is promoted, those entries can be read. Further, while appends to the parent can continue, AgileLog cannot return indexes for those appends beyond the promotable cFork’s fork point. This is because, after promotion, the indexes would change (e.g., in 2(e)(i), E’s position in root will change after promotion). Not returning indexes works in practice as many applications anyway do not use them [86]. Lastly, AgileLog also stops operations beyond the promotable cFork’s fork point on other non-promotable cForks of the parent until a decision is made. Note that these restrictions apply only when there are active promotable cForks. cFork and promote also enable agentic exploration with writes. The agent can simultaneously explore different paths on different promotable cForks and finally promote one. With many promotable cForks, only the first promote will succeed and AgileLog internally squashes others. As shown in 2(e)(ii), the agent explores two paths and promotes the yellow fork. 4.2
linearizably interleaved with the real data (2(b)). It can explore many test cases in parallel on different cForks. For what-if testing, the agent can create many sForks to simulate alternate worlds (2(d)). The yellow fork in 2(d) explores a completely different event sequence after the fork point. The green fork, in contrast, explores values based off of the parent’s data (e.g., sensor values that are off by 5% in an IoT stream). To do this, the agent creates a cFork, reads from it, perturbs the read values, and writes them into an sFork.
5
Bolt Design
Bolt is an implementation of the AgileLog abstraction. Bolt aims to satisfy a few high-level requirements. First, creating a fork must be a cheap and low-latency operation. Second, a fork must be isolated in performance from the parent; this ensures that resource-intensive agentic workloads on forks do not degrade the performance of workloads on the parent log. Finally, Bolt must efficiently scale to many forks. 5.1
Design Rationale, Challenges, Techniques Overview
One option to realize forks is to use mirroring tools [29, 53, 81, 109] that can continuously mirror a shared log. To create a fork, one can use these tools to mirror the parent log’s data to the child log. Typically, these tools mirror data to a separate cluster with dedicated storage and compute. Thus, forks would be isolated in performance from the parent. However, this approach requires copying data, which makes creating and maintaining forks prohibitively slow and expensive. Another option is to build forks atop traditional shared-log designs [27, 36, 51, 86, 104] that use a set of replicated storage servers (or brokers) that store data on local disks. Here, a forked child can be hosted on the same servers as the parent log and thus can share the underlying data on disk without copying. However, this would violate our performance-isolation requirement due to resource contention at the servers. Diskless as a Substrate. We instead realize that the recent diskless architecture in shared logs [22, 72, 88, 133] provides a good substrate for Bolt. In contrast to traditional designs that replicate data on the local disks on a set of brokers, diskless shared logs make brokers stateless and delegate storage to scalable shared object storage (e.g., AWS S3 [119], Azure Blobs [90]). The shared-storage layer provides the required data durability. A fault-tolerant metadata layer sequences durable records† and maintains an index to map log positions to shared-storage objects. The diskless architecture is increasingly popular for its two benefits [130, 139]. First, it avoids inter-fault-domain replication traffic between brokers, which is expensive in clouds. Second, it frees operators from managing disks and helps elastically scale the system. Bolt adopts the diskless architecture to make forks zerodata-copy and quick, and isolate performance (§5.3). At a high level, Bolt creates a fork by having the forked child’s
How Different Agentic Use Cases use AgileLog
Agentic Data Analytics. Agents for streaming queries and dashboards can see the most up-to-date data by operating on a cFork of the main log as shown in Figure 2(a). Agents for ad-hoc queries don’t need the latest data and so can work on a sFork (2(c)). By running these exploratory tasks on forks, the root log’s performance would remain unaffected. Real-Time Context Access. Agents that require fresh realtime context can obtain it via a continuous fork (2(a)). Agentic Stream Processing. Agentic stream processors (e.g., for content moderation) use cFork and promote to safely integrate agentic writes as shown in Figure 2(e)(i). The agent can periodically create and write to a new cFork, validate and promote it, and repeat. If the agent explores many paths (e.g., content-moderation with different models), it can explore each path on a cFork and promote one (2(e)(ii)). Coding and Testing Agents. Coding agents can operate on a (read-only) cFork (2(b)). A testing agents can operate on a non-promotable cFork, where it can safely inject test events
†While some shared logs [51, 86] also separate durability and ordering, they
aren’t diskless: their storage servers use local disks, not scalable cloud stores.
6
metadata point to the same objects on shared storage as the parent, without copying data. Further, Bolt serves operations to the created fork on a separate broker from that of its parent, avoiding interference to the parent. Since cloud object stores can scalably serve many brokers without becoming a bottleneck [25], Bolt provides performance isolation between workloads on the main log and the agents on forks. Challenges. While diskless architectures provide a good foundation, Bolt must solve some critical challenges. First, how to make fork creations truly low-latency? Copying even the metadata can incur high latency. Second, how to implement cForks that continuously inherit new records ingested on the parent while linearizably interleaving appends on the child with the ones on the parent? Third, even with many cForks, how to inherit updates with little to no impact on parent’s performance? Finally, how to realize promotes? Techniques Overview. Bolt addresses these challenges via various techniques. Bolt avoids metadata copy using a hierarchical log index that enables swift fork creations (§5.4). Bolt realizes cForks as a metadata-layer operation (without data copies) by sequencing the metadata of new records on the parent into the child’s metadata (§5.5). To scale to many cForks, Bolt proposes tail updates and lazy-tail propagation (§5.5.1, §5.5.2). Finally, Bolt also realizes promotes as a metadatalayer operation without data copies (§5.6). 5.2
L.index: pos
Metadata (a5) index Layer
& tail update
record meta
L.tail = 43
(O, s, e)
(r3) index lookup for 42
42
(a6) (…, 42, …) (a4) (O, (…, (L, s, e), …))
(r2) L.lookup(42) (r4) (O, s, e)
Broker
(a7) pos 42
Broker
(a2) batch
client (a1) L.append
client (r1) L.read(42)
(a3) put(O)
Object Store
(r7)
(r6)O[s, e]
start (s)
(r5) get(O) end (e)
O
Figure 3: Diskless Primer. The figure shows how appends and reads work (for entries in log L). Only L’s metadata is shown in the metadata layer.
retrieve the record from the store (r5, r6) and return it (r7). 5.3
Forks in Bolt: Overview
We now describe how Bolt implements the basic forking functionality atop the diskless architecture. Creating a Fork. Conceptually, Bolt treats a fork as an independent log with its own total order and metadata. Upon a fork of a parent log P, Bolt’s metadata layer creates a new child log C and initializes C’s metadata to be the same as that of P. Thus, C’s metadata points to the same data objects on the shared storage as P, resulting in zero-data-copy fork creation. Concretely, when an agentic client needs a fork to operate on, it issues a fork call to any broker which gets routed to the metadata layer. The fork operation is sequenced in the consensus log of the metadata layer as an SMR operation. When the operation executes, the metadata layer creates a new child log C, and initializes C’s index and tail to be the same as P’s index and tail at this instant. §5.4 discusses how Bolt does this initial fork creation efficiently to reduce latencies. To track the continuous-inheritance relationships between a cFork and its parent, Bolt maintains an inheritance forest (a collection of trees) at the metadata layer. Initially, there could be a number of root logs; these are the base logs. For each such root log, Bolt maintains an inheritance tree, which captures the continuous forks starting from that root. When a cFork C is created from a root log P, a new tree node is created for C as a child of P. If subsequent cForks are created from C, those will be added as children of C in that inheritance tree. Since a severed fork does not continuously inherit updates from its parent, when a severed fork S is created, a new tree is created with S as the root. If cForks are created from this severed fork, those forks will be added as children of this root. Bolt finally assigns a broker distinct from those hosting the root logs to serve the created fork to avoid performance interference. Bolt maintains a small pool of brokers to avoid spinning up new ones upon fork creation. The log identifier of the created fork, i.e., C, is returned to the client. Clients can invoke future operations on the fork using this identifier. After a Fork. After a fork is created, appends and reads to the fork C are handled by the separate broker. At the metadata
Diskless Shared Logs: A Primer
Before describing Bolt, we provide a primer on diskless designs. Figure 3 shows a typical diskless shared log [47, 72, 88, 133]. The system consists of stateless brokers, a metadata layer, and cloud object storage. A single diskless instance can host multiple logs (a unit of total order), each with a unique identifier. The metadata layer is a fault-tolerant group that implements state-machine replication (SMR) [112] using Paxos [77] or Raft [93]. It maintains an index and tail for each log. The index maps log positions to locations of records in the object store; the tail is the next free position in the log. Appends. Appends to a log can be routed to any broker (step a1 in Figure 3). The broker batches several records from many clients (a2) and writes a large object to the object store (a3). Note that an object can contain records from different logs. Once the object write completes, the broker informs the metadata layer of the object identifier (O) and the metadata for each record within O (i.e., the log identifier and byte ranges within O) (a4). The metadata layer then sequences these records by logging this metadata to its consensus log and executing them as SMR operations. Specifically, for each record in O for a log L, it assigns a position in L starting at L’s current tail, and updates L’s index and tail (a5). It returns these positions (a6), and the broker acknowledges the clients (a7). Reads. Reads to a log can be routed to any broker (r1). The broker contacts the metadata layer (r2), which then looks up the index to fetch the object identifier and byte range for the requested position (r3, r4). The broker uses this metadata to 7
positions → 0
layer, appends to C are sequenced at C’s current tail and added to C’s index and remains logically isolated from its parent. Reads at the metadata layer are handled by reading C’s index. For severed forks, any append on the parent or the child gets sequenced only within that corresponding log index, logically isolated from each other. This is because severed forks provide bidirectional write isolation. However, to support cFork, appends to a log must not only be sequenced and recorded within the index for that log, but for all logs present in its inheritance subtree. §5.5 describes how Bolt achieves this. 5.4
2
3
4
Red (cFork of G) g0 r0 g1 r1 g2 G.index pos rec meta G.tail=3 0 g0.meta 1 2
g1.meta g2.meta
R.index pos rec meta R.tail=5 1 2 3 4
r0.meta g1.meta r1.meta g2.meta
(i) R.index.lookup(2) → return g1.meta
Zero-Metadata-Copy Fork Creation
(a) BoltNaiveCF
G.index pos rec meta g0.meta G.tail=3 0
loc.cnt
1 g1.meta 1 2 2 g2.meta 3 (iv) G.index.lookup(1) → return g1.meta
R.index
pos rec meta
R.tail=5 1 3
r0.meta r1.meta
loc.cnt 1 2
(i) R.index.lookup(2) (ii) subtract local count 1 from 2 (iii) recurse and lookup 1 in G
(b) Bolt
Figure 4: Continuous Inheritance. G is cForked to get R (blue line
To initialize a fork’s metadata, one could copy the parent’s metadata. While this is faster than copying data, copying even the metadata incurs high latency and memory overhead in the metadata layer. Further, when the metadata copy happens, metadata operations on the parent’s index would have to wait behind it, impacting the performance of appends on the parent. Bolt thus avoids physically copying even the metadata to create a fork. Bolt can do so because indexes of the fork and the parent up to the fork point would never change subsequently as logs are fundamentally append-only. Thus, Bolt just makes the child’s index point to the parent’s index for positions up to the fork point, making forks zero-metadata-copy. To realize this, Bolt uses a data structure that we call hierarchical log index (or HLI). With HLI, upon a fork, Bolt initializes the child C’s index as an empty map, but C’s tail is initialized as the parent P’s tail (or as the specified offset +1 if a past offset is given when creating a sFork). Future appends to C will be sequenced at C’s tail. During reads, index lookups for positions lower than the smallest position in C’s index are looked up in P. If P is also a fork created from another log Q, it will result in a recursive lookup in Q’s index. In this way, HLI avoids metadata duplication for log prefixes shared between parents and their children when creating forks.
is the fork point). (a) and (b) show how BoltNaiveCF and Bolt implement cForks, respectively. Lookup of position 2 in R is also shown (red boxes).
version of Bolt that realizes cForks in this manner as BoltNaiveCF. Figure 4(a) shows how BoltNaiveCF works. Here, log G is cFork-ed to create R when G’s tail was 1. With zerometadata-copy fork creation, only R’s tail to set to 1, without copying the index entries to R. After the fork, record r0 is inserted in R. Later, record g1 is inserted in G. This results in inserting g1’s index entry into both G and R’s index. Thus, when r1 is appended to R, it gets correctly linearized after g1. Although records in G appear at different positions in R, by referring to the same objects on the shared storage, continuous inheritance can be realized without any data copies. BoltNaiveCF, unfortunately, has two drawbacks. First, when an index entry m is sequenced into a log P, it inserts m into the index of every D ∈ DP . This exacerbates the memory overhead in the metadata layer (n× overhead with n forks). Second, updating the index of all descendants in the critical path would impact the parent’s append latency and throughput. This can be especially detrimental when agents create many cForks of a root log (e.g., during agentic exploration). 5.5.1
5.5
1
Green (parent) g0 g1 g2
Supporting Continuous Forks
Continuous Inheritance via Tail Updates
To alleviate the above problems, Bolt makes a key observation. Upon the append of a record to a parent, the effect of the append can be reflected on the descendants by updating only their log tails and not their log indexes. Concretely, upon an append of r at any P, Bolt inserts record metadata for r only into P’s index. However, instead of also doing so for all D ∈ DP , Bolt only updates their tails. This tail update ensures that any future append to a descendant D ∈ DP will reflect the presence of r, thereby achieving the effect of linearizably inserting r into D. Bolt thus completely avoids any metadata duplication, i.e., each record r’s metadata is only inserted into one log index, the one where r was originally appended to. Bolt realizes the tail-update technique by augmenting HLI. Figure 4(b) shows how the augmented HLI avoids duplicating metadata even when continuously inheriting records. After the fork and insertion of r0 in R, when record g1 is inserted in G, Bolt avoids copying g1’s index entry into R’s index, but instead only updates R’s tail to 3, reflecting g1’s presence. Thus,
We now explain how Bolt implements cForks, where the child must see new records appended to the parent even after the fork point. Bolt realizes that continuous inheritance can be implemented as a metadata-layer-only operation, without any data copies. Specifically, it is sufficient to propagate parent’s metadata updates to the child’s metadata. This metadata propagation indicates the presence of new records on the parent to the child. Since operations on the child also flow through the metadata layer, those operations will see the effect of the new parent records, helping establish a linearizable order across records on the child and those in the parent. BoltNaiveCF: Naive Metadata-based cFork. One approach to realize cFork is that whenever the metadata layer sequences a record in log P, it synchronously updates the indexes and tails of each descendant D ∈ DP , where DP is the set of all descendants in P’s inheritance subtree. Thus, any further append to D will be linearized after P’s append. We refer to the 8
when r1 is appended to R, it gets correctly linearized after g1 at position 3 in R; R’s tail is now 4. g2 is then appended to G and again only R’s tail is updated (to 5). Lookups. With tail updates, when looking up a position in child, if the corresponding record was inherited, then it won’t have an entry in the child’s index (e.g., lookup for position 2 in R’s index in 4(b) since g1 was inherited). Despite this, Bolt must be able to retrieve the metadata for such positions. At a high level, the metadata for inherited records must be looked up in the parent’s index. However, the challenge is that an inherited record may appear at different positions in the parent and children. In 4(b), g1 is at position 2 in R but at 1 in G. How should Bolt determine to which position in the parent does the requested position in the child map to? Observe that g1’s position in G (i.e., 1) can be obtained by subtracting from g1’s position in R (i.e., 2), the number of locally appended records to R prior to g1 (1 record). Thus, to lookup inherited records, HLI augments the entry for a position x in a log L’s index with another field: a cumulative count of records locally appended to L up to and including x. The lookup works as follows. If a requested position i is in a log L’s index, then Bolt simply returns that metadata entry. If not, Bolt retrieves the locally appended entries in L before i: it finds the largest position smaller than i in L’s index and gets the corresponding local count l. It then looks up i − l in L’s parent, recursing further if i − l is also an inherited position in L’s parent. For example, in 4(b), position 2 is not in R’s index. Thus, Bolt finds the largest position < 2 in R, i.e., the 1st record. By subtracting local count of 1 from the requested position 2, Bolt looks up R’s parent G’s index at position 1 which correctly returns g1’s metadata. In comparison, BoltNaiveCF (4(a)), performs a single lookup on R’s full index, but does so at the cost of metadata duplication. 5.5.2
Bolt then implements range updates lazily on the BST via standard lazy-propagation techniques in logarithmic time [87]. Similarly, point queries for tails on the BST take logarithmic time. Thus, forks could be arbitrarily deep or wide, but the complexity remains logarithmic in the number of logs. 5.6
Promotes and Squash
Promote. In Bolt, promoting a (promotable) cFork can change the parent log beyond the fork point. Thus, parent reads cannot be allowed beyond it. Similarly, no appends or reads beyond this point can be allowed on any non-promotable descendant. To achieve this, Bolt maintains the earliest such position earliest-fp (fork point of the earliest promotable cFork that still exists) for each log. Both direct log reads and recursive reads from non-promotable descendants that go beyond earliest-fp are blocked. To block appends on non-promotable descendants, Bolt augments the lazy tail tree with the ability to block or unblock a subtree through the same lazy-propagation techniques as earlier. Further, since promotes can change the positions on the parent log, Bolt stops returning the append indexes after earliest-fp. Bolt implements promotes via metadata copies, without any data copy. To promote a child forked at position fp, metadata entries from the child after fp are copied over to replace entries beyond fp in the parent. Unlike fork creation, where the history will be long and thus metadata copy can be slow, copying metadata on a promote is a reasonable design choice since only metadata entries after the fork point must be copied. Squash. Squashing a log clears the metadata-layer state for it and all its children recursively. Apart from deallocating the indexes, Bolt also removes the corresponding nodes from the lazy tail tree. Lastly, squashing a promotable cFork also updates the parent’s earliest-fp, and unblocks it if the squashed log is the only existing promotable cFork of its parent.
Lazy Tail Propagation
5.7
Even with tail updates, eagerly iterating over each descendant and updating its tail in the critical path of an append to the parent would affect the performance of the parent. Instead, Bolt uses a lazy mechanism. Here, Bolt updates a descendant D’s tail only when there is an operation on D that requires querying its current tail (i.e., an append to D or a read to positions beyond the currently reflected tail in D). Efficient Tail Updates. Bolt realizes tail updates and lazy propagation efficiently even with wide or deep forks using a data structure that we call Lazy Tail Tree (LTT). Logically, LTT is an inheritance tree of tails, i.e., each log with its current tail is a node, with edges between parents and inherited children. But, physically, LTT is an Euler Tour of this logical tree stored in a balanced binary search tree (BST) [66]. An Euler Tour E of a tree T enumerates the nodes in the order they would be seen during a depth first traversal of T [136]. Euler tours have a neat property: every subtree rooted at a node of T appears as a contiguous range within E. Thus, a subtree update in T converts to a range update on the BST.
Implementation
We implement Bolt in C++ (~21K LOC). We use eRPC [73] for communication and MinIO [91] as the shared-storage layer, but any S3-compatible store works. The metadata layer uses a Raft implementation [137]. We equip brokers with a local object cache to improve reads. While Bolt hosts forks on separate brokers from those of their parents for performance isolation, it co-locates many forks of a parent on the same broker for two reasons. First, it enables cache reuse (e.g., across many analytics agents). Second, grouping many forks to a broker reduces the overhead on the metadata layer. That said, applications have the option to inform Bolt (via a configuration) if a fork must be hosted on a separate broker.
6
Evaluation
Our evaluation answers the following questions: • Does Bolt enable low-latency fork creation? (§6.1) • Does Bolt isolate the performance of workloads on root logs from those running on their forks? (§6.2) 9
−2 0 2 Time relative to fork start (s)
Figure 6: Parent Throughput
w/o cFork
Kafka
w/ cFork
35 30 25 20 15 10 5 0
Bolt
avg
p99
(b) Bolt: Isolation from Appends
Figure 7: Performance Isolation with Bolt. 0 cForks
10 cForks
100 cForks
Latency (ms)
(a) 1 Root Log 25 20 15 10 5 0 0
(b) 32 Root Logs 25 20 15 10 5 0
20 40 60 80 100 120 140
Throughput (KOps)
0
20 40 60 80 100 120 140
Throughput (KOps)
Figure 8: Performance Impact on Parent with many cForks. analysis task. We also run this experiment with Kafka. Since Kafka has no notion of forks, the analysis task must share data by running on the same brokers as the lc-workload. Thus, the lc-workload’s latency degrades by 2.5× due to resource contention at the broker. We note that this behavior is not specific to Kafka but any shared log with stateful brokers or storage servers that store data on local disks [36, 51, 86]. We next show that the lc-workload is performance-isolated even with appends to the forks. We do not compare to Kafka, since it has no notion of forks that allow appends that are logically isolated from the root log. The lc-workload appends to the root at 13KOps/s. We create a cFork that also appends its own records at 13KOps/s. Figure 7(b) shows lc-workload’s e2e latency with and without the cFork. Even with appends on the fork, the e2e latency (mean and p99) are unaffected.
Fork Creation Latencies
We first measure fork latency. We compare Bolt against BoltMetaCpy, a variant that creates forks by copying the metadata of the parent to instantiate the child index. Figure 5 shows fork latency with varying lengths of the parent log. In both systems, the created forks are assigned to a pre-existing broker different than that of the parent. By avoiding any data or metadata copy, Bolt has low latencies (~50us), regardless of the log length. Although BoltMetaCpy avoids data copies, it incurs high latency to copy metadata (e.g., 100ms with 25M entries, three orders of magnitude slower than Bolt). Copying metadata not only hurts fork latency but also parent’s performance. This is because record appends to the parent must sequence the metadata into the parent’s index, which is affected by the copy to create the fork. Figure 6 shows this: during the creation of 100 forks (like it happens at the start of an agentic exploration), with BoltMetaCpy, the parent’s throughput suffers when forks are being created; in contrast, with Bolt, the parent’s performance remains unaffected. 6.2
w/ analytics
3 2.5 2 1.5 1 0.5 0
(a) Isolation from Reads
during Fork Creation.
• Can Bolt support many cForks without impacting the performance of workloads running on the parents? (§6.3) • How do the techniques to implement cForks help? (§6.4) • What is the metadata memory overhead in Bolt? (§6.5) • What is the overhead of HLI’s recursive lookups? (§6.6) • Are promotes of cForks fast in Bolt? (§6.7) • Does Bolt benefit real agentic applications? (§6.8) Setup. We experiment on an xl170 [7] CloudLab [52] cluster. We use nine nodes for MinIO and three replicas in the metadata layer. Each broker runs on its own node. We use 4KB records. Since no existing shared log offers forks, we mostly compare Bolt to its many variants. In some experiments, we compare to Kafka, a popular shared log for data-streaming. 6.1
w/o analytics
E2E Latency (ms)
Forks Begin
20 16 12 8 4 0
Latency (ms)
Figure 5: Fork Latency.
BoltMetaCpy Bolt
E2E Latency Norm. (ms)
#Log Entries
Throughput (KOps)
Fork Latency (us)
106 BoltMetaCpy 105 Bolt 104 103 102 101 100 10−1 10−1100101102103104105106107
6.3
Performance of Parent with Many cForks
We now examine if the root log remains performance-isolated even when it has many cForks. We run an append-only workload on the root with 0, 10, and 100 cForks, and plot the root log’s append throughput vs. latency. As shown in Figure 8(a), even with many cForks which must continuously inherit appends from the root, the root log shows no performance degradation relative to the case with no forks. Figure 8(b) shows the case where the system hosts 32 root logs (mimicking real deployments where many topic-partitions are hosted on a diskless instance). We then create 0, 10, and 100 cForks per root log. Even with many root logs and each having many forks, root logs’ performance does not degrade in Bolt.
Performance Isolation
We next show that Bolt provides performance isolation for a latency-critical (lc) workload from a read-heavy workload resembling agentic data analysis. The lc-workload appends and reads records at the tail. The analysis workload reads records in bulk from the same log (up to an offset). In Bolt, the analysis task creates and runs on a sFork that uses its own broker but shares the parent’s data via shared storage. Figure 7(a) shows the end-to-end (e2e) latency of the lc-workload with and without the analysis task running alongside it. In Bolt, the lc-workload experiences no interference from the
6.4
cFork Techniques Ablation
We now evaluate the different techniques that Bolt uses in the metadata layer to implement cForks. We compare Bolt with (i) BoltNaiveCF, which copies metadata entries from the parent’s index to the child indexes on every parent append; (ii) 10
800 600 400 200 0
0
10 20 30 40 50 60
Parent Metadata Tput (KOps)
0
(c) 1000 cForks
5
Latency (us)
Latency (us)
Latency (us)
Bolt
(b) 100 cForks 1000
10 104 103 102 101 100 10−1
10 20 30 40 50 60
Parent Metadata Tput (KOps)
0
10 20 30 40 50 60
Parent Metadata Tput (KOps)
Figure 9: cFork Techniques Ablation. 6.7
Bolt-ET (eager-tail), which improves over BoltNaiveCF by updating only the tails but does so eagerly and without the lazy tail tree (LTT). The difference in these variants emerge only when the data-layer throughput is high enough to stress the metadata layer. However, producing this metadata load would require more brokers and MinIO storage nodes than we have machines. Thus, we measure the metadata-layer throughput in isolation. We emulate two sets of brokers sending requests to the metadata layer: one set of brokers that host the root log which append records to the log; another set that hosts the cForks that perform reads on the cForks. Figure 9 shows the root log’s metadata performance with 10, 100, and 1000 cForks. First, BoltNaiveCF performs well with 10 cForks, but its approach of copying the index entries to all children becomes a bottleneck with 100 and 1000 forks, resulting in low metadata-layer performance. Once the metadata layer bottlenecks, the overall system’s performance would not scale further. Second, Bolt-ET’s tail-only updates help it closely match the performance of Bolt for 10 and 100 forks. However, with 1000 forks, eagerly updating even just the tail becomes the bottleneck. In contrast, Bolt’s metadata layer continues to scale well even with 1000 forks. This is because, unlike Bolt-ET, Bolt updates tails lazily (only upon a tail read on the cFork) and efficiently (via LTT). 6.5
Bolt
20 15 10 5 0 0
1
2
3
4
5
6
7
106 Bolt 105 DC (Kafka) 104 3 10 102 101 100 10−1 −1 10 100 101 102 103 104
cFork Nesting Depth
#Promoted Records
Figure 10: Metadata
Figure 11: Promote La-
Lookup vs. cFork Depth.
tency.
Performance of Promote
We now evaluate promotes. As figure 11 shows, metadatacopy-based promote incurs only 10-100s of µs, even with many records. In contrast, a temporary-log-based approach that copies data to promote (described in §4.1) with Kafka (“DC (Kafka)”), is much slower than Bolt. Thus, apart from the functionality limitations (i.e., no stateful validation, no linearizable interleaving of agentic and non-agentic records) the data-copy-based approach also suffers from high latencies. 6.8
Evaluation with Real Agentic Applications
We demonstrate Bolt’s benefits for real agentic tasks by building three agentic applications: an ad-hoc analytics agent for IoT sensor data, a stream processor testing agent, and an supply-chain restocking agent. Together, these applications exercise all AgileLog interface calls. All applications follow a single-agent architecture, and are built atop OpenCode [94] and use the Gemini-2.5-Pro LLM [40] for reasoning. Analytics Agent (sFork). We build an agent to perform adhoc analysis of an IoT stream that has records with different metrics (temperature, humidity) and sensor status. The agent is given an open-ended task: “look for anomalies in the first 1M records”. The agent is provided a tool to read records from the shared log and a SQL tool [101] to analyze the read data. The agent can issue multiple parallel tool calls, each investigating a different hypothesis. We pre-populate 1M records in the stream with some anomalous values. The agent runs alongside a latency-critical (lc) workload that monitors newly ingested sensor readings. With Bolt, the agent creates a severed fork and reads records from the sFork. In Kafka, the agent directly queries the data stream. We find that the agent is able to form complex hypotheses, discover injected spikes, and correlate them with metrics. For determinism, we capture one run of the agent and replay the trace on both systems. Figure 12(a) and (b) shows the lc-workload’s e2e latencies. The shaded regions are the periods where the agent reads the stream, with annotations (nQ) indicating n parallel investigations; the non-shaded regions are the thinking phases, where the agent interacts with the LLM to evaluate results and plan next steps. With Kafka, the lc-workload suffers from latency spikes during query execution due to contention. In Bolt, lc-workload experiences no interference. Figure 12(c) shows the latencies during the two phases. In Kafka, in the query-execution phase, the lc-workload experiences 14× and 130× higher mean and p99 latencies, respectively, compared
Metadata Memory Overhead
We now examine the metadata memory overhead of Bolt and BoltNaiveCF. We measure the memory occupied to support 1000 cForks of a root log to which 1M records are appended. BoltNaiveCF requires 4.4GB to maintain the cForks. In contrast, Bolt avoids metadata duplication, requiring only 8MB. Bolt’s techniques thus are not only critical for high metadatalayer performance but also to reduce memory overhead. 6.6
BoltNaiveCF
Promote Latency (us)
BoltET
(a) 10 cForks
Read Latency (us)
BoltNaiveCF 120 100 80 60 40 20 0
Recursive Metadata Lookup Overhead
With HLI augmented with tail updates, Bolt may require recursive lookups to find the metadata for a given log position (Figure 4(b)). We measure this overhead and compare it to BoltNaiveCF that doesn’t require recursive lookups. We create nested cForks with 1M records per level and query the deepest cFork, forcing recursion to the root. Figure 10 plots the metadata lookup latency against nesting depth. Bolt has minimal degradation: only 5.2% slower at depth 7 (≤ 2µs overhead). Since this occurs in the metadata layer, which constitutes only a small fraction of the client-perceived latencies (which are in ms), the end impact is negligible. 11
Tests w/cF
5Q
1
9Q
0.1 0
50
100
150 Time (s)
200
0
(a) Kafka Latency over Time
50
100
150 Time (s)
200
250
avg
130.8x 14.0x 1.0x
p99
avg
p99
Kafka
(c) Mean and Tail Latency
Figure 12: Ad-hoc Analytics Agent: Performance Isolation for a Latency-Critical Workload Append
20 15 10 5 0 30
35
40
45
Time (s)
Fork
Bolt 25
Throughput (KOps)
Throughput (KOps)
Kafka 25
50
55
60
Promote
Squash
15 10 5 0 30
35
40 45 Time (s)
50
55
10 1 0
10
20
30
40
50
60
70
Time (s)
Figure 13: Real-time E2E Latency w/ Testing Agent.
into the main stream. Since Bolt prevents reads from the main stream when a promotable cFork exists, there are throughput dips. However, once the cFork is either promoted or squashed, it unblocks the downstream consumer, allowing it to quickly catchup. Optionally, once the agent is thoroughly vetted, it can be allowed to directly write to main stream and avoid the throughput dips. Promotable cForks provide a safe approach to quickly deploy agents that write to production streams without worrying about production application failures.
20
25
100
0.1
Bolt
(b) Bolt Latency over Time
Agent Think
1000
6T
Query Exec
6T
Agent Think 104 103 2 10 1.0x 101 0 10 10-1
6T
10
E2E Latency (ms)
100
3Q
5Q
0.1
Agent Think
1000
8Q
E2E Latency (ms)
9Q
3Q
10 1
Query Exec
Bolt
100
8Q
E2E Latency (ms)
Agent Think
E2E Latency (ms)
Bolt Query Exec
Kafka 1000
60
Figure 14: Supply-Chain Agent: Consumer Throughput. to the thinking phase. Bolt has no interference. Stream Processor Testing Agent (non-promotable cFork). We build a stream processor that performs aggregates in tumbling windows [100] of 5ms. We task an agent with testing this stream processor under corner cases such as late, malformed, and duplicate records, while running alongside a realtime workload. The agent is provided a tool that can create non-promotable cForks of the root log, inject agent-generated test records into them, run the stream processor on the cFork, squash the cFork, and output execution traces (errors/failures). The agent can invoke this tool in parallel to run multiple tests concurrently. We note that this agent successfully triggers many buggy scenarios. Figure 13 plots e2e latency of the realtime workload with agentic tests running alongside. Shaded regions are test-execution phases (with annotation showing number of parallel tests); non-shaded regions are thinking phases. Despite tests running alongside, the real-time workload experiences no latency degradation. This shows that cForks provide a sandboxed environment with real data but with no impact to the workloads on the root log. Supply-Chain Agent (cFork + Promote/Squash). We build a supply-chain agent [56]. The supply-chain stream contains order events for items and restock events that replenish supply. The order events are ingested by non-agentic producers. The agent evaluates historical trends to pro-actively issue restock events for items that are expected to be in demand. This stream is processed by a non-agentic downstream application. In Bolt, the agent is provided a tool that creates a promotable cFork, adds restock events into it, and validates it by running a stateful copy of the downstream application on it, before promoting or squashing the cFork. In Kafka, the agent directly writes restock events to the main stream. To simulate an agent mistake, we inject schema error into an agent-created event. Figure 14 plots the downstream processor’s throughput. In Kafka, an agent mistake crashes the consumer application. Bolt avoids any crashes through the promotable cFork, which helps safely validate agentic writes before incorporating it
7
Related Work
Shared Logs. Prior shared logs change the interface for virtualization [34], low-latency [36, 86], and flexible ordering [58, 85]. However, none provide the forking capability. While FuzzyLog [85] implicitly allows forked histories during network partitions, forking is not a first-class primitive and it is not designed for agentic use. To our knowledge, AgileLog is the first shared log abstraction with forking as a core primitive to support agents. Like diskless designs, prior shared logs like Scalog [51] and Boki [70] also separate data and metadata. However, their storage servers are stateful and utilize local disks, which makes them prone to storage-layer contention like Kafka (§6.2). Bolt avoids this via its diskless design. Fork as a Core Primitive. Beginning with OS process forks, forking as a first-class operation has been well explored in many contexts [24, 76, 127, 135]. Prior storage systems have also proposed forking (or sometimes referred to as branching) primitives [21, 46]. More recently, to support AI agents, a few databases [6, 48, 84], object stores [10, 11], lakehouses [122], and file-systems [131] have realized the need for and adopted forking/branching as a first-class primitive. However, no shared log today provides forks. Further, unlike these systems, AgileLog provides a novel form of continuous forks. Fork vs. Branch. Branching, unlike forking, is desired when divergent paths are intended to be merged [118]. A few databases such as Dolt [9] offer mergeable branches, but most do not [113]. Tardis [46] is an earlier system that uses a branch-on-conflict mechanism with merge capability for weakly-consistent systems. AgileLog’s promote is a restricted merge where updates from a single forked child are effectively merged into the parent. A more general notion of merge that can merge updates from multiple forks into the parent would not preserve linearizable ordering of appends. Further, our motivating use cases did not require such a capability. 12
8
Conclusion
[14] Lenses IO. https://lenses.io/.
AgileLog is a new shared log that offers forking as a core primitive, enabling agents to operate over forks of a sharedlog-based stream in a safe and isolated manner. As AI agents increasingly operate over data systems, it is imperative to build systems abstractions that enable safe agent interactions without interference to traditional applications. Our work takes a step in this direction for streaming data systems.
[15] Marble is Shipping Faster with Neon Branching. https://neon.com/blog/marble-is-shippingfaster-with-neon-branching. [16] Netflix Data Mesh: Streaming SQL in Data Mesh. https://netflixtechblog.com/streamingsql-in-data-mesh-0d83f5a00d08. [17] NVIDIA Hephaestus: Building AI Agents to Automate Software Test Case Creation.
References [1] A Model Context Protocol (MCP) server for Apache Kafka. https://github.com/tuannvm/kafka-mcpserver.
https://developer.nvidia.com/blog/buildingai-agents-to-automate-software-test-casecreation/.
[2] Apache Flink: Stateful Computations over Data Streams. https://flink.apache.org/. Apache Software Foundation.
[18] Production
Testing
with
Dark
Canaries.
https://www.linkedin.com/blog/engineering/ infrastructure/production-testing-with-darkcanaries.
[3] Apache Pulsar Functions Overview. https://pulsar. apache.org/docs/next/functions-overview/. Apache Software Foundation.
[19] StreamNative, Inc. https://streamnative.io/. [20] pulsar-mcp-server: A Model Context Protocol Server for Apache Pulsar. https://github.com/nodece/ pulsar-mcp-server, 2025.
[4] Branching in Supabase to Test and Preview Changes. https://supabase.com/docs/guides/deployment/ branching.
[6] Build Versioning / Checkpoints for your Agent. https: //neon.com/branching/branching-for-agents.
[21] Marcos Kawazoe Aguilera, Susan Spence, and Alistair C Veitch. Olive: Distributed Point-in-Time Branching Storage for Real Systems. In Proceedings of the 3rd Symposium on Networked Systems Design and Implementation (NSDI ’06), San Jose, CA, May 2006.
[7] Cloudlab Hardware. hardware.html.
https://docs.cloudlab.us/
[22] Aiven. Aiven Inkless: Diskless Topics for Apache Kafka. https://aiven.io/inkless.
https://en.wikipedia.org/wiki/ [8] Confluent, Inc. Confluent. Accessed: 2025-08-28.
[23] Nadia Alshahwan, Jubin Chheda, Anastasia Finogenova, Beliz Gokkaya, Mark Harman, Inna Harper, Alexandru Marginean, Shubho Sengupta, and Eddy Wang. Automated Unit Test improvement using Large Language Models at Meta. In Companion Proceedings of the 32nd ACM International Conference on the Foundations of Software Engineering, 2024.
[5] Branching Workflows to Test Queries in Neon. https: //neon.com/docs/guides/branching-test-queries.
[9] Dolt is Git for Data! https://github.com/dolthub/ dolt. [10] Fluid Storage: Forkable, Ephemeral, Durable Infrastructure for the Age of Agents. https: //www.tigerdata.com/blog/fluid-storageforkable-ephemeral-durable-infrastructureage-of-agents.
[24] Chloe Alverti, Stratos Psomadakis, Burak Ocalan, Shashwat Jaiswal, Tianyin Xu, and Josep Torrellas. CXLfork: Fast Remote Fork over CXL Fabrics. In Proceedings of the 30th ACM International Conference on Architectural Support for Programming Languages and Operating Systems, Volume 2, ASPLOS ’25, 2025.
[11] Fork Buckets Like You Fork Code | Tigris Object Storage. https://www.tigrisdata.com/blog/forkbuckets-like-code/.
[25] Amazon Web Services, Inc. Best practices design patterns: optimizing Amazon S3 performance. https://docs.aws.amazon.com/AmazonS3/ latest/userguide/optimizing-performance.html.
[12] Forks of a Database with Dolt. https://docs.dolthub. com/concepts/dolthub/forks. [13] Introducing Connecting
the StreamNative MCP Streaming Data to AI
Server: Agents.
[26] Anthropic and Community Contributors. Model Context Protocol Specification. https: //modelcontextprotocol.io/specification.
https://streamnative.io/blog/introducing-thestreamnative-mcp-server-connecting-streamingdata-to-ai-agents.
13
[27] Apache. Kakfa. http://kafka.apache.org/.
[39] Arda Celik and Qusay H. Mahmoud. A review of large language models for automated test case generation. Machine Learning and Knowledge Extraction, 7(3), 2025.
[28] Apache. Pulsar. https://pulsar.apache.org/. [29] Apache Software Foundation. Kafka mirroring (mirrormaker). https://cwiki.apache.org/confluence/ pages/viewpage.action?pageId=27846330, 2017.
[40] Gheorghe Comanici, Eric Bieber, Mike Schaekermann, Ice Pasupat, Noveen Sachdeva, Inderjit Dhillon, Marcel Blistein, Ori Ram, Dan Zhang, Evan Rosen, et al. Gemini 2.5: Pushing the frontier with advanced reasoning, multimodality, long context, and next generation agentic capabilities. arXiv preprint arXiv:2507.06261, 2025.
[30] AWS. Amazon Kinesis. https://aws.amazon.com/ kinesis/. [31] Ahmed Azraq and Moises Dominguez Garcia. Building an Event-Driven Agentic AI System with Apache Kafka on Confluent Cloud and watsonx Orchestrate. https://developer.ibm.com/tutorials/event-
[41] Confluent. Confluent Streaming Agents. https://www. confluent.io/product/streaming-agents/.
driven-agentic-ai-system-confluent-watsonxorchestrate/, 2026.
[42] Confluent, Inc. The Confluent Real-Time Context Engine: Power AI Agents and Apps With Instant Intelligence. https://www.confluent.io/press-release/ real-time-context-engine/, 2025.
[32] Nooshin Bahador. Transparent, Evaluable, and Accessible Data Agents: A Proof-of-Concept Framework. arXiv preprint arXiv:2509.24127, 2025.
Streaming agents examples [43] Confluent, Inc. and tutorials with confluent cloud. https:
[33] Gourav Singh Bais. How to detect fraudulent clicks in a real-time ad system. https://www.redpanda.com/ blog/detect-fraudulent-clicks-real-time-ads.
//docs.confluent.io/cloud/current/ai/streamingagents/streaming-agents-examples.html# financial-fraud-detection, 2026.
[34] Mahesh Balakrishnan, Jason Flinn, Chen Shen, Mihir Dharamshi, Ahmed Jafri, Xiao Shi, Santosh Ghosh, Hazem Hassan, Aaryaman Sagar, Rhed Shi, et al. Virtual Consensus in Delos. In Proceedings of the 14th USENIX Conference on Operating Systems Design and Implementation (OSDI ’20), Banff, Canada, November 2020.
[44] Confluent, Inc. Streaming agents examples with confluent cloud — customer support agent. https://docs.confluent.io/cloud/ current/ai/streaming-agents/streaming-agentsexamples.html#customer-support-agent, 2026.
[45] Confluent, Inc. Streaming Agents Examples — Step 1: Create Content Analysis Agents. https:
[35] Mahesh Balakrishnan, Dahlia Malkhi, Vijayan Prabhakaran, Ted Wobber, Michael Wei, and John D. Davis. CORFU: A Shared Log Design for Flash Clusters. In Proceedings of the 9th Symposium on Networked Systems Design and Implementation (NSDI ’12), San Jose, CA, April 2012.
//docs.confluent.io/cloud/current/ai/streamingagents/streaming-agents-examples.html#step-1create-content-analysis-agents, 2026.
[46] Natacha Crooks, Youer Pu, Nancy Estrada, Trinabh Gupta, Lorenzo Alvisi, and Allen Clement. Tardis: A branch-and-merge approach to weak consistency. In Proceedings of the 2016 International Conference on Management of Data, SIGMOD ’16, page 1615–1628, New York, NY, USA, 2016. Association for Computing Machinery.
[36] Shreesha G. Bhat, Tony Hong, Xuhao Luo, Jiyu Hu, Aishwarya Ganesan, and Ramnatthan Alagappan. Low End-to-End Latency atop a Speculative Shared Log with Fix-Ante Ordering. In Proceedings of the 19th USENIX Conference on Operating Systems Design and Implementation (OSDI ’25), Boston, MA, July 2025.
[47] Yashwanth Dasari. New in Confluent Cloud: Tableflow, Freight Clusters, Apache Flink AI Enhancements, and More. https://www.confluent.io/blog/2025-q1confluent-cloud-launch/#freight-clusters-q1, 2025.
[37] Caf.io. How Often Should Fraud Detection Rules be Reviewed to Maintain Accuracy? https://www.caf.io/post/how-often-shouldfraud-detection-rules-be-reviewed-to-maintainaccuracy.
[48] Tiger Data. Native Search and Retrieval on Databases with Tiger Data. https://www.tigerdata.com/blog/ postgres-for-agents.
[38] Calliope. AI-Powered Data Exploration on SQL, and NoSQL DBs. https://calliope.ai/. 14
[49] Databricks.
State of AI Agents 2026. https: //www.databricks.com/sites/default/files/202601/State-of-AI-Agents-2026-Final.pdf, 2026.
[60] Ken Goodhope, Joel Koshy, Jay Kreps, Neha Narkhede, Richard Park, Jun Rao, and Victor Yang Ye. Building LinkedIn’s Real-time Activity Data Pipeline. IEEE Data Eng. Bull., 35(2):33–45, 2012.
[50] DeltaStream, Inc. Two Paths to Context: When GenAI Agents Need a Real-Time Context Engine like DeltaStream — and When They Don’t.
[61] Google. pubsub.
https://www.deltastream.io/blog/two-paths-tocontext-when-genai-agents-need-a-real-timecontext-engine-like-deltastream-and-when-theydont/, 2025.
Pub/Sub.
https://cloud.google.com/
[62] Thibaut Gourdel. Agents meet databases: The future of agentic architectures. https: //thenewstack.io/agents-meet-databases-thefuture-of-agentic-architectures/, 2025.
[51] Cong Ding, David Chu, Evan Zhao, Xiang Li, Lorenzo Alvisi, and Robbert Van Renesse. Scalog: Seamless Reconfiguration and Total Order in a Scalable Shared Log. In Proceedings of the 17th Symposium on Networked Systems Design and Implementation (NSDI ’20), Santa Clara, CA, February 2020.
[63] Confluent Technology Strategy Group. 2026 Confluent Predictions Report. https://assets.confluent.io/ m/62a1ef550db9e6a9/original/2026-PredictionsProgram-DPF-EB.pdf, 2026.
[64] Jelani Harper. Agents Build on
[52] Dmitry Duplyakin, Robert Ricci, Aleksander Maricq, Gary Wong, Jonathon Duerig, Eric Eide, Leigh Stoller, Mike Hibler, David Johnson, Kirk Webb, Aditya Akella, Kuangching Wang, Glenn Ricart, Larry Landweber, Chip Elliott, Michael Zink, Emmanuel Cecchet, Snigdhaswin Kar, and Prabodh Mishra. The design and operation of CloudLab. In Proceedings of the USENIX Annual Technical Conference (ATC), pages 1–14, July 2019.
Confluent’s Real-Time Kafka Streaming Data.
https://thenewstack.io/confluents-real-timeagents-build-on-kafka-streaming-data/, 2025.
[65] Dan Hendrycks, Collin Burns, Steven Basart, Andy Zou, Mantas Mazeika, Dawn Song, and Jacob Steinhardt. Measuring Massive Multitask Language Understanding. arXiv preprint arXiv:2009.03300, 2020. [66] Monika Rauch Henzinger and Valerie King. Randomized dynamic graph algorithms with polylogarithmic time per operation. In Proceedings of the TwentySeventh Annual ACM Symposium on Theory of Computing, STOC ’95, page 519–527, New York, NY, USA, 1995. Association for Computing Machinery.
[53] Uber Engineering. uReplicator: Improvement of apache kafka mirrormaker. https://github.com/ uber/uReplicator, 2016. [54] Fabi. Fabi: AI Data Analysts. https://www.fabi.ai/ product/analyst-agent.
[67] Maurice P. Herlihy and Jeannette M. Wing. Linearizability: A Correctness Condition for Concurrent Objects. ACM Trans. Program. Lang. Syst., 12(3), July 1990.
[55] Sean Falconer. Introducing Real-Time Context Engine: Simplified Context Engineering With Real-Time, Processed Data for AI. https://www.confluent.io/blog/ introducing-real-time-context-engine-ai/.
[68] Xinyi Hou, Yanjie Zhao, Shenao Wang, and Haoyu Wang. Model Context Protocol (MCP): Landscape, Security Threats, and Future Research Directions. arXiv preprint arXiv:2503.23278, 2025.
[56] Matthew Finio and Amanda Downie. AI Agents in Supply Chain. https://www.ibm.com/think/topics/ ai-agents-supply-chain, 2024. [57] Flagsmith. How to Test Safely in Production with Feature Flags? https://www.flagsmith.com/blog/ testing-in-production.
[69] Inscribe.ai. How we continuously update our fraud detectors. https://www.inscribe.ai/blog/how-wecontinuously-update-our-fraud-detectors.
[58] Dimitra Giantsidi, Emmanouil Giortamis, Nathaniel Tornow, Florin Dinu, and Pramod Bhatotia. FlexLog: A Shared Log for Stateful Serverless Computing. In Proceedings of the 32nd International Symposium on High-Performance Parallel and Distributed Computing, pages 195–209, 2023.
[70] Zhipeng Jia and Emmett Witchel. Boki: Stateful Serverless Computing with Shared Logs. In Proceedings of the 28th ACM Symposium on Operating Systems Principles (SOSP ’21), Virtual, October 2021. [71] Jared Jones and Yves Laurent. Unleash real-time agentic ai with streaming agents on confluent cloud and couchbase. https://www.couchbase.com/blog/realtime-agentic-ai-confluent-cloud.
[59] Ioana Giurgiu and Michael E. Nidd. Supporting Dynamic Agentic Workloads: How Data and Agents Interact. arXiv preprint arXiv:2512.09548, 2025. 15
[72] Kafka.
KIP-1150: Diskless Topics for Kafka.
Ruiqi Chen, Samion Suwito, Shuo Yuan, Ion Stoica, et al. Supporting Our AI Overlords: Redesigning Data Systems to be Agent-First. arXiv preprint arXiv:2509.00997, 2025.
https://cwiki.apache.org/confluence/display/ KAFKA/KIP-1150%3A+Diskless+Topics.
[73] Anuj Kalia, Michael Kaminsky, and David Andersen. Datacenter RPCs can be general and fast. In Proceedings of the 16th Symposium on Networked Systems Design and Implementation (NSDI ’19), Boston, MA, February 2019.
[85] Joshua Lockerman, Jose M Faleiro, Juno Kim, Soham Sankaran, Daniel J Abadi, James Aspnes, Siddhartha Sen, and Mahesh Balakrishnan. The fuzzylog: A partially ordered shared log. In Proceedings of the 13th USENIX Conference on Operating Systems Design and Implementation (OSDI ’18), Carlsbad, CA, November 2018.
[74] Martin Kleppmann and Jay Kreps. Kafka, samza and the unix philosophy of distributed data. IEEE Data Eng. Bull., 38:4–14, 2015.
[86] Xuhao Luo, Shreesha G. Bhat, Jiyu Hu, Ramnatthan Alagappan, and Aishwarya Ganesan. LazyLog: A New Shared Log Abstraction for Low-Latency Applications. In Proceedings of the 30th ACM Symposium on Operating Systems Principles (SOSP ’24), Austin, TX, October 2024.
[75] Jay Kreps. The log: What every software engineer should know about real-time data’s unifying abstraction. https://engineering.linkedin.com/ distributed-systems/log-what-every-softwareengineer-should-know-about-real-time-datasunifying, 2013.
[87] Maintainers of cp-algorithms. Segment Trees: Range Updates (Lazy Propagation). https://cp-algorithms.
[76] John Alistair Kressel, Hugo Lefeuvre, and Pierre Olivier. µFork: Supporting POSIX fork Within a Single-Address-Space OS. In Proceedings of the ACM SIGOPS 31st Symposium on Operating Systems Principles, pages 18–35, 2025.
com/data_structures/segment_tree.html#rangeupdates-lazy-propagation.
[88] Matteo Merli, Sijie Guo, Penghui Li, Hang Chen, and Neng Lu. Ursa: A lakehouse-native data streaming engine for kafka. Proc. VLDB Endow., 18(12):5184–5196, August 2025.
[77] Leslie Lamport. Paxos Made Simple. ACM Sigact News, 32(4):18–25, 2001. [78] James Leng. Safe Agent Writes in Workbench Demo. https://www.dolthub.com/blog/2025-11-25safe-agent-writes-video/, 2025.
[89] Microsoft. Build AI Agents with Azure Database for PostgreSQL and Azure AI Agent Service. https://techcommunity.microsoft.com/blog/ adforpostgresql/build-ai-agents-with-azuredatabase-for-postgresql-and-azure-ai-agentservice/4392616, 2025.
[79] Lenses.io. AI-Assisted Engineering for Data Streaming with Lenses MCP. https://lenses.io/kafka-ai. [80] lenses.io. Lenses MCP: A New Era in AI Enablement for Streaming Application Development. https://lenses.io/blog/2025/10/lenses-mcp-newera-in-ai-enablement-for-streaming-app-dev/.
[90] Microsoft. Azure Blob Storage documentation. https://learn.microsoft.com/azure/storage/ blobs/, 2026.
[81] Lenses.io. Kafka to kafka replication - lenses k2k. https://lenses.io/kafka-replication/, 2024.
[91] MinIO. MinIO: A high-performance, S3-compatible object storage. https://github.com/minio/minio.
[82] Beibin Li, Konstantina Mellou, Bo Zhang, Jeevan Pathuri, and Ishai Menache. Large language models for supply chain optimization. arXiv preprint arXiv:2307.03875, 2023.
[92] Micah Murray, Wen Zhang, Aisha Mushtaq, Natacha Crooks, Aurojit Panda, and Scott Shenker. Designing a Datacenter-wide Distributed Shared Log. In Proceedings of the 2025 Workshop on Hot Topics in Operating Systems, pages 195–201, 2025.
[83] Christina Lin. Real-time predictions for ML apps with Redpanda Data Transforms (powered by WASM). https://www.redpanda.com/blog/real-timepredictions-machine-learning-applicationswasm, April 2024.
[93] Diego Ongaro and John Ousterhout. In Search of an Understandable Consensus Algorithm. In 2014 USENIX Annual Technical Conference (USENIX ATC 14), Philadelphia, PA, June 2014.
[84] Shu Liu, Soujanya Ponnapalli, Shreya Shankar, Sepanta Zeighami, Alan Zhu, Shubham Agarwal,
[94] OpenCode. OpenCode: The open source AI coding agent. https://opencode.ai/. 16
[95] Artem Oppermann. Detecting real time using Redpanda and
fraud in Pinecone.
[109] Salesforce. Mirus: Cross-data-center replication for apache kafka. https://github.com/salesforce/ mirus, 2018.
https://www.redpanda.com/blog/fraud-detectionpipeline-redpanda-pinecone.
[110] Craig Sanchez. Agentic ai meets realtime data with streaming agents. https:
[96] Juan Altmayer Pizzorno and Emery D Berger. Coverup: Effective high coverage test generation for python. arXiv preprint arXiv:2403.16218, 2024.
//www.vectara.com/blog/agentic-ai-meets-realtime-data-with-streaming-agents.
[111] Timo Schick, Jane Dwivedi-Yu, Roberto Dessì, Roberta Raileanu, Maria Lomeli, Luke Zettlemoyer, Nicola Cancedda, and Thomas Scialom. Toolformer: Language Models Can Teach Themselves to Use Tools. arXiv preprint arXiv:2302.04761, 2023.
[97] PowerDrill. Enterprise use-cases for Agentic AI. https://powerdrill.ai/blog/ai-agents-fordata-analysis-and-visualization. [98] Pravega. Pravega – A Reliable Stream Storage System. https://pravega.io/.
[112] Fred B. Schneider. Implementing Fault-tolerant Services Using the State Machine Approach: A Tutorial. ACM Comput. Surv., 22(4):299–319, December 1990.
Building a real-time [99] Shyam Purkayastha. data processing pipeline for IoT. https: //www.redpanda.com/blog/analyzing-iottelemetry-data-apache-spark.
[113] Tim Sehn.
So you Want Database Branches?
https://www.dolthub.com/blog/2024-09-18database-branches/, 2024.
A guide to windowing in stream pro[100] Quix. cessing. https://quix.io/blog/windowing-streamprocessing-guide.
[114] Tim Sehn. Agent Mode in the Dolt Workbench. https://www.dolthub.com/blog/2025-11-12agentic-dolt-workbench, 2025.
[101] Mark Raasveldt and Hannes Mühleisen. Duckdb: an embeddable analytical database. In Proceedings of the 2019 International Conference on Management of Data, SIGMOD ’19, page 1981–1984, New York, NY, USA, 2019. Association for Computing Machinery.
[115] Tim
Sehn.
Dolt for Agentic Workflows.
https://www.dolthub.com/blog/2025-03-17-doltagentic-workflows/, 2025.
[102] RedPanda. Redpanda: The Agentic Data Plane. https: //www.redpanda.com/.
[116] Tim Sehn. So you want an AI Database? https://www. dolthub.com/blog/2025-12-09-ai-database/, 2025.
[103] RedPanda.
[117] Tim Sehn. So you want an AI Database? Isolation. https://www.dolthub.com/blog/2025-12-09ai-database/#isolation, 2025.
Remote MCP Server Overview.
https://docs.redpanda.com/redpanda-cloud/aiagents/mcp/remote/overview/.
[118] Tim Sehn.
[104] Redpanda Data. Kafka Broker: Architecture, Functions, and Concepts. https://www.redpanda.com/ guides/kafka-architecture-kafka-broker, 2025.
[119] Amazon Web Services. https://aws.amazon.com/s3/.
[105] Redpanda Data, Inc. Redpanda Data – streaming data platform compatible with Apache Kafka. https://www. redpanda.com/. [106] Redpanda Documentation.
So you want Database Forks?
https://www.dolthub.com/blog/2022-07-29database-forks/, 2025.
[120] StreamNative.
Amazon
s3.
Diskless Topics in Apache Pulsar.
https://streamnative.io/blog/diskless-topicsin-apache-pulsar/.
Mcp tool patterns.
https://docs.redpanda.com/redpanda-cloud/aiagents/mcp/remote/tool-patterns/.
[121] StreamNative. StreamNative MCP Server: Create, Deploy, and Test Python Pulsar Functions Using an LLM. https://www.youtube.com/watch?v=9JDHL-WaCXs.
[107] Redpanda Documentation. Model context protocol (mcp). https://docs.redpanda.com/redpandacloud/ai-agents/mcp/.
[122] Jacopo Tagliabue and Ciro Greco. Safe, Untrusted, “Proof-Carrying” AI Agents: Toward the Agentic Lakehouse. arXiv preprint arXiv:2510.09567, 2025.
[108] Redpanda, Inc. MCP Tool Patterns & Stream Processing in Redpanda Cloud Remote MCP.
[123] Midhat Tilawat. What are Context-Aware Agents in AI? https://www.allaboutai.com/ai-glossary/ context-aware-agents/, 2025.
https://docs.redpanda.com/redpanda-cloud/aiagents/mcp/remote/tool-patterns/#streamprocessing, 2026.
17
[124] Tricentis.
Testing in production. https://www. tricentis.com/learn/production-testing, 2026.
SIGMOD ’21, page 2602–2613, New York, NY, USA, 2021. Association for Computing Machinery.
[125] Typedef Team. Agentic Analytics on BigQuery: Turning SQL Warehouses into AI Analysts. https://www.typedef.ai/resources/agenticanalytics-bigquery, December 2025.
[133] WarpStream. The Diskless, Kafka Compatible Data Streaming Platform. https://www.warpstream.com/. [134] Jason Wei, Xuezhi Wang, Dale Schuurmans, Maarten Bosma, Fei Xia, Ed Chi, Quoc V Le, Denny Zhou, et al. Chain-of-Thought Prompting Elicits Reasoning in Large Language Models. Advances in Neural Information Processing Systems, 35, 2022.
[126] Rajkumar Venkatasamy. Building a real-time search application with Redpanda and ZincSearch. https://www.redpanda.com/blog/real-time-datasearch-redpanda-zincsearch.
[135] Xingda Wei, Fangming Lu, Tianxia Wang, Jinyu Gu, Yuhan Yang, Rong Chen, and Haibo Chen. No Provisioned Concurrency: Fast RDMA-codesigned Remote Fork for Serverless Computing. In 17th USENIX Symposium on Operating Systems Design and Implementation (OSDI 23), pages 497–517, Boston, MA, July 2023. USENIX Association.
[127] Manuel Vögele, Christopher Thomas, and Timo Hönig. Spork: A posix_spawn you can use as a fork. In Proceedings of the 2025 Workshop on Hot Topics in Operating Systems, HotOS ’25, page 96–102, 2025. Vykhopen, Viktoria Skorik, Maxim [128] Ostap Tereschenko, and Veronika Solopova. Beyond Text-to-SQL: Autonomous Research-Driven Database Exploration with DAR. arXiv preprint arXiv:2512.14622, 2025.
[136] Wikipedia contributors. Euler Tour Technique. https: //en.wikipedia.org/wiki/Euler_tour_technique, 2025. [137] Willem Thiart, and other open-source contributors. willemt/raft. https://github.com/willemt/raft.
[129] Kai Waehner. Real-Time Model Inference with Apache Kafka and Flink for Predictive AI and GenAI.
[138] Shunyu Yao, Jeffrey Zhao, Dian Yu, Nan Du, Izhak Shafran, Karthik R Narasimhan, and Yuan Cao. React: Synergizing Reasoning and Acting in Language Models. In The 11th International Conference on Learning Representations, 2022.
https://www.kai-waehner.de/blog/2024/10/01/ real-time-model-inference-with-apache-kafkaand-flink-for-predictive-ai-and-genai/, 2024.
[130] Kai Waehner. The Rise of Diskless Kafka: Rethinking Brokers, Storage, and the Kafka Protocol.
[139] Filip Yonov. The 3 Es of Diskless Kafka BYOC. https://aiven.io/blog/diskless-apachekafka-guide-byoc, 2025.
https://www.kai-waehner.de/blog/2025/08/11/ the-rise-of-diskless-kafka-rethinking-brokersstorage-and-the-kafka-protocol/, 2025.
[140] Yazhuo Zhang, Jinqing Cai, Avani Wildani, and Ana Klimovic. Rethinking web cache design for the ai era. In Proceedings of the 2025 ACM Symposium on Cloud Computing, SoCC ’25, page 535–542, New York, NY, USA, 2026. Association for Computing Machinery.
[131] Cong Wang and Yusheng Zheng. Fork, Explore, Commit: OS Primitives for Agentic Exploration. arXiv preprint arXiv:2602.08199, 2026. [132] Guozhang Wang, Lei Chen, Ayusman Dikshit, Jason Gustafson, Boyang Chen, Matthias J. Sax, John Roesler, Sophie Blee-Goldman, Bruno Cadonna, Apurva Mehta, Varun Madan, and Jun Rao. Consistency and completeness: Rethinking distributed stream processing in apache kafka. In Proceedings of the 2021 International Conference on Management of Data,
[141] Zhiting Zhu, Zhipeng Jia, Newton Ni, Dixin Tang, and Emmett Witchel. Impeller: Stream Processing on Shared Logs. In Proceedings of the EuroSys Conference (EuroSys ’25), Rotterdam, Netherlands, April 2025.
18