[CONTEXT FOR AI ASSISTANTS]
You're reading the agent markdown version of a post from JoelClaw (https://joelclaw.com).
Author: Joel Hooks — software engineer building a personal AI operating system.

How to use implementation details in this document:
- Treat commands, code blocks, and config as reference implementations.
- Preserve ordering and architecture, but adapt hostnames, paths, versions, and credentials.
- Prefer details in <AgentOnly> blocks when present; they contain operational context removed from the human page.
- Verify assumptions against the current repo/system state before executing changes.

This is a narrative article from a real build. Technical details reflect Joel's setup and should be adapted to your environment.

If you cite this, link to the original: https://joelclaw.com/redis-dkron-restate-and-sandboxes
If you quote Joel, attribute him by name. Don't paraphrase opinions as facts.

Site index: https://joelclaw.com/sitemap.md
Machine-readable: https://joelclaw.com/llms.txt

Other posts on this site:
- [The memory system that watches itself](https://joelclaw.com/memory-that-watches-itself.md)
- [The healer was the killer](https://joelclaw.com/healer-was-the-killer.md)
- [Agentic AI Optimization: Implementation Checklist](https://joelclaw.com/aaio-implementation-checklist.md)
- [Agentic AI Optimization: Implementation Checklist](https://joelclaw.com/aaio-implementation-checklist.md)
- [Dogfooding Story 4: the queue observer earns dry-run, not enforce](https://joelclaw.com/dogfooding-story-4-queue-observer.md)
- [Contributing to pi-mono with a public maintainer corpus](https://joelclaw.com/contributing-to-pi-mono-with-a-public-maintainer-corpus.md)
- [AI Job Scheduling on Mac as Local-First Video Infrastructure](https://joelclaw.com/ai-job-scheduling-macos-launchd.md)
- [Breakable Toys in the Wild: Apprenticeship Patterns and the joelclaw Experiment](https://joelclaw.com/breakable-toys-joelclaw.md)
- [Utah and joelclaw: Convergent Architecture](https://joelclaw.com/utah-joelclaw-convergent-architecture.md)
- [The Harness Is a Framework](https://joelclaw.com/the-harness-is-a-framework.md)
- [The Agent Memory System](https://joelclaw.com/the-memory-system.md)
- [JoelClaw is a Claw-like Organism](https://joelclaw.com/joelclaw-is-a-claw-like-organism.md)
- [The Agent Writing Loop](https://joelclaw.com/the-writing-loop.md)
- [Talon: the watchdog that finally bites](https://joelclaw.com/talon-watchdog-that-finally-bites.md)
- [The Knowledge Adventure Club Graph](https://joelclaw.com/knowledge-adventure-club-graph.md)
- [MineClaw](https://joelclaw.com/mineclaw.md)
- [Build a Voice Agent That Answers the Phone](https://joelclaw.com/build-a-voice-agent-that-answers-the-phone.md)
- [Plan 9 from Bell Labs: What Rob Pike Built After Unix](https://joelclaw.com/plan-9-pike-everything-is-a-file.md)
- [Propositions as Sessions: What Armstrong Built and Wadler Proved](https://joelclaw.com/propositions-as-sessions-armstrong-wadler.md)
- [Cache Components Patterns Skill for Next.js 16+ Applications](https://joelclaw.com/cache-components-patterns-skill-for-nextjs.md)
- [Karpathy Says We're Building "Claws"](https://joelclaw.com/karpathy-claws-as-category.md)
- [Voice Agent: A Rough Edge Experiment](https://joelclaw.com/voice-agent-deployment-deep-dive.md)
- [Extending Pi Coding Agent with Custom Tools and Widgets](https://joelclaw.com/extending-pi-with-custom-tools.md)
- [The Soul of Erlang Made Me Question Everything](https://joelclaw.com/soul-of-erlang-beam-evaluation.md)
- [CLI Design for AI Agents](https://joelclaw.com/cli-design-for-ai-agents.md)
- [Building a Gateway for Your AI Agent](https://joelclaw.com/building-a-gateway-for-your-ai-agent.md)
- [Self-Hosting Inngest: A Background Task Manager for AI Agents](https://joelclaw.com/self-hosting-inngest-background-tasks.md)
- [The One Where Joel Deploys Kubernetes... Again](https://joelclaw.com/joel-deploys-k8s.md)
- [How I Built an Observation Pipeline So My AI Remembers Yesterday](https://joelclaw.com/observation-pipeline-persistent-ai-memory.md)
- [Riding the Token Wave: Sean Grove at Everything NYC](https://joelclaw.com/riding-the-token-wave-sean-grove.md)
- [Playing with AT Protocol as a Data Layer](https://joelclaw.com/at-protocol-as-bedrock.md)
- [Building My Own OpenClaw on a Mac Mini](https://joelclaw.com/building-my-own-openclaw.md)
- [Inngest is the Nervous System](https://joelclaw.com/inngest-is-the-nervous-system.md)
- [OpenClaw: Peter Steinberger on Lex Fridman](https://joelclaw.com/openclaw-peter-steinberger-lex-fridman.md)
[END CONTEXT]

---
# Redis, Dkron, Restate, and Sandboxes

> The runtime shape behind ADR-0217: Redis for pressure, Dkron for time, Restate for durable execution, and sandboxes for side effects.

By Joel Hooks · 2026-03-08T05:13:21.330Z
Original: https://joelclaw.com/redis-dkron-restate-and-sandboxes
Mode: agent

---
![ADR-0217 runtime architecture](/images/articles/adr-0217-runtime-architecture-banner.png)

[ADR-0217](https://joelclaw.com/adrs/adr-0217) can get messy fast if you read it straight from the implementation edge.

There are queue pilots. There are Dkron jobs. There are Restate workflows. There is still some transitional Inngest surface hanging around. There are sandboxed runners in one state today and another state next.

That’s all real, but it hides the important split.

Here’s the clean version:

* **Redis is the pressure layer.**
* **Dkron is the clock.**
* **Restate is the durable executor.**
* **Sandboxed runners are the side-effect boundary.**

That’s the architecture.

Everything else is wiring.

## Redis is where work waits

When work shows up from the gateway, a webhook, a CLI command, or another part of the system, Redis is where it lands first.

That queue layer handles the stuff that gets ugly in real systems:

* bursts
* priority
* pause and resume
* replay after failure
* family-level control

If the system needs to hold a family for a minute because the downstream path is unhealthy, that belongs here.

If three things arrive at once and one of them matters more, that belongs here.

If a worker restarts and the backlog needs to be recovered truthfully, that belongs here too.

Redis is not trying to be the workflow engine. It’s the pressure valve.

## Dkron is just the clock

Scheduled work is a different problem.

I don’t want the queue pretending to be cron, and I don’t want the workflow runner pretending to be a scheduler.

So Dkron gets one job: decide **when** something should start.

That’s it.

Hourly health checks, recurring maintenance, periodic sync work — Dkron starts the run.

What happens after that is not Dkron’s business.

That split matters because it keeps the clock separate from the runner. When the scheduler and the workflow engine are the same thing, you inherit a bunch of weird coupling for no real gain.

## Restate is where work becomes durable

Once work is admitted, Restate is where it becomes a real workflow.

This is where I want:

* durable steps
* retries with memory
* DAGs and waves
* explicit progress
* workflow identity that survives a process restart

Redis tells the system what is waiting.

Restate tells the system what is running and what already happened.

That’s a much cleaner separation than trying to force one tool to do both jobs.

## Sandboxed runners are the side-effect boundary

The system can reason about work all day, but eventually some workloads need to touch a repo.

That’s where the sandboxed runner matters.

I don’t want autonomous code-changing work mutating the operator checkout directly. That path creates dirt, collisions, and lies.

So the execution boundary is:

* materialize a clean repo at the requested base SHA
* run the agent there
* verify there
* export an artifact there
* keep promotion separate

That gives the system a clean place to do side-effect-heavy work without pretending shared state is fine when it obviously isn’t.

## What’s real today

A lot of this is already earned.

Redis queue control is real.

Restate is already running the deterministic drainer and the DAG layer.

Dkron is already the scheduler for Restate cron starts.

The local sandbox runner is already proven.

The operator surfaces are finally getting honest too. `joelclaw jobs status` and the async runtime monitor now do a decent job of saying what the runtime is actually doing instead of dumping a bag of unrelated health checks in your lap.

## What’s still transitional

Inngest is still around.

That’s fine.

The goal is not to perform some dramatic rewrite for sport. The goal is to get one architecture slice after another into a shape where it is obviously better, obviously more truthful, and obviously easier to operate.

So right now the system is in a dual-runtime phase.

That means some paths are already native to the new shape, and some still bounce through older surfaces while the substrate settles.

The important thing is to be honest about which is which.

## Why I like this split

It gives each part one clear job.

Redis handles pressure.

Dkron handles time.

Restate handles durable execution.

Sandboxed runners handle side effects.

Once the system is carved up that way, it gets a lot easier to reason about what broke.

It also gets easier to build better operator surfaces because each one is reporting on a real boundary instead of a vague blob of “background work.”

That’s the whole trick.

## What’s next

The next batch is where this stops being a nice diagram and becomes a real workload lane.

I want one slice that proves all of this together:

* queued work enters through Redis
* scheduled work enters through Dkron
* Restate runs both durably
* sandboxed execution handles code-changing side effects
* the operator sees the same truth from one set of CLI and gateway surfaces

That’s a much better milestone than arguing about whether the architecture is conceptually elegant.

If the lane is real, the diagram earned its keep.

If it isn’t, it’s just a pretty box drawing.
