Skip to content
All writing
Event messages connecting serverless functions with a live interface

Karere: Event-Driven Workflows at Kete Kai

At Kete Kai, I worked on Karere, a message-driven framework for serverless backend services. I was a Junior Full-stack Developer from November 2019 to October 2020, working across the AWS architecture, internal React tools, and the team's delivery workflow.

Karere's design used AWS SNS as the message broker, connecting functions through publish/subscribe messages and letting clients receive updates over WebSockets throughout an operation. That combination is the interesting part. A user-facing action could involve several pieces of backend work, and the interface did not have to wait for one final response to hear from the system.

Looking at Cloudflare Workflows today, I recognise some of the same concerns: how to coordinate multiple steps, handle failure, and expose progress. The programming models are different, but the questions are familiar.

Choreographing the work

Karere described its coordination model as a choreography saga. A saga divides an operation into separate local transactions. In choreography, participants react to published events, and their results can trigger other participants. The flow emerges from those subscriptions rather than a central function directing every action. AWS's description of saga choreography explains that distinction.

The broker was Amazon Simple Notification Service, or SNS. Publishers sent messages to topics, and subscribers reacted to those messages. Functions could participate in a larger operation without needing to know its entire structure. That gives each participant a smaller responsibility, although the overall flow still needs to be understandable to the people maintaining it.

I think that is the tradeoff worth explaining. The dependencies have moved into messages and subscriptions. They are still dependencies. Reviewing an individual function tells you what it does; understanding the operation also requires following what it publishes and what reacts next.

Compensation belongs beside the side effect

Karere's documentation recommended an alternative error function alongside each function. Each participant would handle its own side effects without needing to understand the greater saga. The framework left the reconciliation structure up to the application.

The principle is useful: the code responsible for changing something is also the best place to define what compensation means for that change. A distributed operation does not acquire a database-style rollback just because its functions are called a saga. Compensation is application logic, and it must be designed explicitly.

That becomes more important when paths can run in parallel. An error in one path does not erase the work another path has already completed. The application needs a policy for the resulting state, rather than treating a thrown exception as if it could reverse everything that preceded it.

The client could hear from the saga more than once

Clients connected through WebSockets, maintained through API Gateway. Karere allowed an operation to send data back multiple times during its execution. Its design also used DynamoDB to buffer messages that could not be delivered and referenced an existing library for publish/subscribe over API Gateway's WebSocket API.

Multiple updates give an interface more to work with than a single completion response. They can make progress visible while backend work continues. They also require a clear distinction between an intermediate update and the final result: hearing from the backend is not necessarily evidence that the whole operation has finished.

That connected directly to the internal tools I built in React and TypeScript, which communicated with our backend primarily over WebSockets. The communication contract was part of the frontend experience, not just a backend transport choice.

What Cloudflare's steps make familiar

Looking back in October 2026, Cloudflare Workflows makes some of these ideas familiar. It provides durable execution through named steps. A successful step.do persists its result, allowing an interrupted workflow to resume using completed step results. Retry behaviour can be configured at the step boundary.

Karere approached coordination through message-driven choreography. Cloudflare Workflows puts the flow into a workflow definition and supplies durable step execution. The similarity is the need to make multi-stage work manageable. The distinction is where the coordination and persisted execution state live.

I would not equate Karere's message buffering with Cloudflare's step checkpoints. Buffering an undelivered client message answers a delivery question. Remembering a completed step's result answers an execution question. Both involve storing state, but they preserve different facts for different purposes.

Part of a broader full-stack role

The wider Kete Kai stack included SQS, Lambda, API Gateway, DynamoDB, and QLDB, deployed through the Serverless Framework. QLDB supported our event-sourcing work; it is historical infrastructure now, with AWS retiring the service in July 2025. Epsagon provided observability. I also acted as sprint master in our adapted Scrum workflow, with Azure DevOps for repositories and pipelines.

I returned for a short contract from March to May 2021, helping with the technology we had built previously and delivering an internal tool using React, TypeScript, MongoDB, and serverless services.

Karere gives that role a more concrete story than a list of services. It brought together the movement of work, responsibility for side effects, and communication with the person waiting on the result. Those remain useful questions even as the platforms and execution models change.

See this role and my full work history.