# Scaling agent systems with Apache Kafka and A2A (Part 6): The Quartz Chronometer Agent &#8211; An Example using the default A2A protocols

[Blog](/blog/)&gt;[Technology](/blog/category/technical/)&gt;Scaling agent systems with Apache Kafka and A2A (Part 6): The Quartz Chronometer Agent – An Example using the default A2A protocols 

Scaling agent systems with Apache Kafka and A2A (Part 6): The Quartz Chronometer Agent – An Example using the default A2A protocols
===================================================================================================================================

October 08, 2026 | By [ Paul Brebner](https://www.instaclustr.com/blog/author/paul-brebner/)

 

 

 

 



   [ ](https://x.com/intent/tweet?text=Scaling%20agent%20systems%20with%20Apache%20Kafka%20and%20A2A%20(Part%206):%20The%20Quartz%20Chronometer%20Agent%20%E2%80%93%20An%20Example%20using%20the%20default%20A2A%20protocols&url=https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-a2a-part-6-the-quartz-chronometer-agent-an-example-using-the-default-a2a-protocols/) [ ](https://www.linkedin.com/shareArticle?mini=true&url=https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-a2a-part-6-the-quartz-chronometer-agent-an-example-using-the-default-a2a-protocols/&title=&summary=Scaling%20agent%20systems%20with%20Apache%20Kafka%20and%20A2A%20(Part%206):%20The%20Quartz%20Chronometer%20Agent%20%E2%80%93%20An%20Example%20using%20the%20default%20A2A%20protocols&source=) 

Our A2A “campaign” is so far progressing according to plan: we’ve marched from [the motivation for Agent systems](https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-agent2agent-part-1-the-evolution-of-agent-systems/), to [A2A objects](https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-agent2agent-part-2-understanding-the-a2a-object-model/), [runtime behaviour](https://www.instaclustr.com/blog/scaling-agent-systems-with-kafka-and-a2a-part-3-agent2agent-protocol-explained/) and [diagrams](https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-a2a-part-4-visualizing-the-agent2agent-protocol/), ending up with a working Clockwork Agent example in part 5. But Napoleon’s armies didn’t run on maps (diagrams) and dispatches (protocols) alone; they depended on keeping time. Part 6 is where we upgrade the clock to the Quartz Chronometer Agent!

In the [previous blog](https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-a2a-part-5-the-clockwork-agent-a-java-a2a-example/), we introduced the Clockwork Agent example – a runnable demo of the main A2A protocol paths: an immediate Message, a long-running Task, and an input-required flow with follow-up on the same task. You’d be wrong to conclude that’s the end of the story: the Clockwork Agent was a deliberate simplification – it demoed the example using plain Java. This part demonstrates the same example using the official A2A protocols – JSON-RPC on the reference SDK server and SSE for long-running tasks – as the Quartz Chronometer Agent!

You can find the new code here: <https://github.com/instaclustr/code-samples/tree/main/AI/A2A/quartz-chronometer>

Here’s an explanatory flow diagram:

![Quartz Chronometer Agent: the Clockwork Agent examples using the official A2A JSON-RPC + SSE protocols]()

Quartz Chronometer Agent: the Clockwork Agent examples using the official A2A JSON-RPC + SSE protocols

I’ve called it the **Quartz Chronometer**, as it’s a significant upgrade to the original Java version. Napoleon had several famous timekeepers that he used during his military campaigns, including a [Breguet No. 178 Travel clock](https://blog.nationalmuseum.ch/en/2017/06/napoleon-was-a-fan-of-breguet/) and a more practical [pocket watch](https://collection.nam.ac.uk/detail.php?acc=1963-10-212-1). But even the [first experimental quartz clock](https://en.wikipedia.org/wiki/Quartz_clock#History) was 50+ times more accurate than these.

And there’s also a real timing improvement in this version – by moving from polling to streaming.

What the A2A default protocol example includes
----------------------------------------------

The Quartz Chronometer example is a complete A2A default-protocol version of the Clockwork Agent. It’s the same deterministic, rule-based server (so no LLMs yet), but with a different stack:

- Quarkus 
    - We use **Quarkus** because the official [a2a-java](https://github.com/a2aproject/a2a-java) reference server ships on it — see the [Quarkus guides](https://quarkus.io/guides/) for the framework itself.
    - Our custom code is now limited to an Agent Card producer and an AgentExecutor; Quarkus handles HTTP, JSON-RPC, and SSE.
- A2A-java reference JSON-RPC server 
    - Official Quarkus reference server for A2A over JSON-RPC
    - <https://github.com/a2aproject/a2a-java/blob/main/reference/jsonrpc/README.md>
- Agent Card at `/.well-known/agent-card.json`
- Streaming with SSE for long-running tasks instead of the GetTask poll loop 
    - For long-running tasks, the client keeps a connection open and receives **`statusUpdate`** / **artifactUpdate** frames over **Server-Sent Events (SSE)**
    - <https://a2a-protocol.org/latest/topics/streaming-and-async/>

What changed in the A2A demo?
-----------------------------

The following table summarizes what changed from the Clockwork Agent to the Quartz Chronometer:

Clockwork (Part 5)Quartz Chronometer (Part 6)**Server**Hand-rolled HttpServerOfficial A2A reference server (Quarkus)**Binding**JSON-RPC (custom)JSON-RPC (SDK)**Port**80808085**Task updates**Client polls GetTaskClient receives streaming SSE statusUpdate / artifactUpdate**Examples**3 examplesSame 3 clockwork examplesThe transports and how the client observes long tasks are the main changes.

Designing the A2A default protocol example
------------------------------------------

The guiding design principle was to use the best default A2A mechanism that matches each example’s response shape, summarized in the following table:

ExamplePromptServerClient1 · Time What is the current time? sendMessage → immediate Message JSON-RPC, streaming off 2 · Countdown Count down 60 seconds Task + startWork / updateStatus / complete JSON-RPC + SSE 3 · Confirm Count down 20 seconds with confirm requiresInput → user confirm on same taskId → countdown SSE before and after confirm The implementation is still small (now 570 lines of Java). The `AgentExecutor` routes prompts, `QuartzCountdownRunner` drives the async loop via `AgentEmitter`, and `QuartzDemoClient` runs all three examples in one script. The full design notes are on GitHub.

A2A demo: Example output
------------------------

Here’s sample output from the new code:































=== Agent Card === name: Quartz Chronometer Agent streaming: true skills: 3 === Example 1: Synchronous Time (immediate Message) === Response: The current time is 2026-08-19 14:16:13 AEST. === Example 2: Async Countdown (SSE stream) === Example 2 statusUpdate | state=TASK\_STATE\_WORKING | Countdown started: 10s remaining. Example 2 artifactUpdate | Countdown completed at 2026-08-19 14:16:23 AEST. Example 2 statusUpdate | state=TASK\_STATE\_COMPLETED | Countdown completed at 2026-08-19 14:16:23 AEST. Final artifact: Countdown completed at 2026-08-19 14:16:23 AEST. === Example 3: Input-Required Countdown (SSE stream) === event=statusUpdate | state=TASK\_STATE\_INPUT\_REQUIRED | Please confirm countdown start for 10 seconds. Sending confirm on task e45f8042-f43a-4c52-9429-6b41a5d74193 event=statusUpdate | state=TASK\_STATE\_WORKING | Countdown started: 10s remaining. Example 3 statusUpdate | state=TASK\_STATE\_WORKING | Countdown started: 10s remaining. Example 3 artifactUpdate | Countdown completed at 2026-08-19 14:16:33 AEST. Example 3 statusUpdate | state=TASK\_STATE\_COMPLETED | Countdown completed at 2026-08-19 14:16:33 AEST. Final artifact: Countdown completed at 2026-08-19 14:16:33 AEST. === Quartz Chronometer demo complete ===

   1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20



  === Agent Card ===

name: Quartz Chronometer Agent

streaming: true

skills: 3

=== Example 1: Synchronous Time (immediate Message) ===

Response: The current time is 2026-08-19 14:16:13 AEST.

=== Example 2: Async Countdown (SSE stream) ===

Example 2 statusUpdate | state=TASK\_STATE\_WORKING | Countdown started: 10s remaining.

Example 2 artifactUpdate | Countdown completed at 2026-08-19 14:16:23 AEST.

Example 2 statusUpdate | state=TASK\_STATE\_COMPLETED | Countdown completed at 2026-08-19 14:16:23 AEST.

Final artifact: Countdown completed at 2026-08-19 14:16:23 AEST.

=== Example 3: Input-Required Countdown (SSE stream) ===

event=statusUpdate | state=TASK\_STATE\_INPUT\_REQUIRED | Please confirm countdown start for 10 seconds.

Sending confirm on task e45f8042-f43a-4c52-9429-6b41a5d74193

event=statusUpdate | state=TASK\_STATE\_WORKING | Countdown started: 10s remaining.

Example 3 statusUpdate | state=TASK\_STATE\_WORKING | Countdown started: 10s remaining.

Example 3 artifactUpdate | Countdown completed at 2026-08-19 14:16:33 AEST.

Example 3 statusUpdate | state=TASK\_STATE\_COMPLETED | Countdown completed at 2026-08-19 14:16:33 AEST.

Final artifact: Countdown completed at 2026-08-19 14:16:33 AEST.

=== Quartz Chronometer demo complete ===



   

 

 **What each example shows:**

1. **Ex 1** — instant Message back, no Task, no SSE.
2. **Ex 2** — Task created, SSE delivers `statusUpdate` → `artifactUpdate` → COMPLETED (~10s later).
3. **Ex 3** — first SSE event is `INPUT_REQUIRED`; client sends confirm on the same task ID; then the same SSE countdown pattern as Ex 2.

What’s missing?
---------------

So, what’s still missing?

An obvious omission is A2A webhooks. But webhooks are not needed for this example, as the Quartz Chronometer models a connected client that stays open while tasks run. Webhooks only matter if we want to support notifications from Agents to disconnected clients. I went down a rabbit hole with an earlier version of this example (called the “bridge”) and explored three different notification mechanisms for the same “countdown” task, including webhooks (polling, SSE, webhook), and the code is still [here](https://github.com/instaclustr/code-samples/tree/main/AI/A2A/part6)).

JSON-RPC for the request-response interaction and SSE streaming (for countdown and confirmation examples) are the correct protocols for this example.

As with the Clockwork Agent example, there are still some simplifications and features implemented, but not demonstrated (see the GitHub for more details on the limitations).

Fixing stale polling data with streaming
----------------------------------------

After writing the previous blog, I noticed a minor issue with the Clockwork Agent demo (and the polling version of the “bridge” – SSE and webhooks both fixed the problem in that code). Polling doesn’t know if anything changed since the last read – it simply pulls the current value on a fixed schedule. It can therefore receive the same value twice, or even skip over a value. Pull-based updates are not ideal as they are disconnected from real state transitions. Put another way, polling is sampling, not subscribing!

The symptom shows up in the console output as duplicate or missing status lines. Polling is also inefficient. We fixed this problem by using the A2A SSE to prevent guessing on a timer and polling, to let Agents push updates only when status data changes. Each streamed value now corresponds to a real state change, so the clients stay aligned with the Agent. This is our promised timing improvement – the Quartz Chronometer is more accurate than Clockwork!

Benefits of the A2A default protocol example
--------------------------------------------

The Quartz Chronometer (using default A2A protocols) marks significant progress towards a more realistic A2A protocol demo. It preserves the Clockwork Agent’s observable behaviour while replacing the hand-rolled server and polling loop with the official A2A Java reference server, JSON-RPC, and SSE. We still don’t have LLMs or Kafka, but we now have a stronger protocol foundation with significant benefits:

Benefitvs original Java-only Clockwork AgentSpec-faithfulOfficial a2a-java + JSON-RPC reference server — Agent Card, operations, and task lifecycle match what other A2A clients expectCorrect task updatesSSE for long tasks (normative connected-client path), not a poll loop (with overheads and stale data)Less custom wire codeYou implement business logic (AgentExecutor); the SDK handles JSON-RPC, streaming, and card servingInteroperabilityCompliant clients can call it — not tied to the bespoke HttpServer / /rpc shimProduction-shapedSame patterns you’d use for real agents (SDK, requiresInput(), AgentEmitter, streaming capabilities)Room to growThe project can adopt other official bindings (gRPC/REST) without rewriting the agent modelThe Quartz Chronometer shows how A2A agents can communicate and hand work to one another using the official protocol stack. As those interactions grow in volume, complexity, and operational scope, scaling agent systems will eventually require durable events, state, search and gateways — workloads [**Instaclustr**](https://www.instaclustr.com/platform/) already operates as managed Kafka, OpenSearch, PostgreSQL, Cassandra, ClickHouse, Cadence, and a new MCP gateway. A2A defines how agents communicate and hand work to one another; Apache Kafka and related infrastructure provide the foundation for operating it at scale.

Want to catch up on the other blogs in this series?
---------------------------------------------------

Explore the earlier posts to follow the series from the evolution of agent systems and the A2A object model through runtime behavior, protocol diagrams, and the first runnable Java example.

- [Part 1: The evolution of agent systems](https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-agent2agent-part-1-the-evolution-of-agent-systems/)
- [Part 2: Understanding the A2A object model](https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-agent2agent-part-2-understanding-the-a2a-object-model/)
- [Part 3: Agent2Agent Protocol explained](https://www.instaclustr.com/blog/scaling-agent-systems-with-kafka-and-a2a-part-3-agent2agent-protocol-explained/)
- [Part 4: Visualizing the Agent2Agent protocol](https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-a2a-part-4-visualizing-the-agent2agent-protocol/)
- [Part 5: The Clockwork Agent—a Java A2A example](https://www.instaclustr.com/blog/scaling-agent-systems-with-apache-kafka-and-a2a-part-5-the-clockwork-agent-a-java-a2a-example/)

 

### About the author

**[Paul Brebner](https://www.instaclustr.com/blog/author/paul-brebner/)** | Technology Evangelist at Instaclustr

Paul has extensive R&amp;D and consulting experience in distributed systems, technology innovation, software architecture, and engineering, software performance and scalability, grid and cloud computing, and data analytics and machine learning.

 

 [ Add Instaclustr as a preferred source on Google ](https://google.com/preferences/source?q=instaclustr.com)



 

 ![mail icon]()#### Get the latest articles for open sourceIn your inbox

 <a class="btn btn-primary btn-popup text-dark" href="">Sign up now</a> 

 

 

 

  ### Related content

 [ Zero Downtime Migration to Instaclustr 

 

 Yes, we can migrate existing Cassandra clusters to Instaclustr without any downtime. Here's what to expect from the process... 

 

 

 

 

 

 

 ](https://www.instaclustr.com/blog/zero-downtime-migration-to-instaclustr/) 

 [ Workflow Comparison: Uber Cadence vs Netflix Conductor 

 

 When choosing what’s right for your company’s opensource workflow needs it is important to know the difference and similarities ... 

 

 

 

 

 

 

 ](https://www.instaclustr.com/blog/workflow-comparison-uber-cadence-vs-netflix-conductor/) 

 [ Will Your Cassandra Database Project Succeed?: The New Stack 

 

 Open source Apache Cassandra® continues to stand out as an enterprise-proven solution for organizations seeking high availability... 

 

 

 

 

 

 

 ](https://www.instaclustr.com/blog/will-your-cassandra-database-project-succeed-the-new-stack/) 

 

  <a class="close-modal" href="">×</a>Sign upto ourNewsletter
-----------------------
