# Add KV Caching to a Cloudflare Worker from a Linear Issue

Yes. An agent picks up the Linear issue, caches the D1 list query in KV for 60 seconds, invalidates on write and opens a pull request.

[Run this on Rush](https://cloud.getrush.ai/run/add-kv-caching/cloudflare-workers/), in a Project that has your repository.

## What the agent does

The run starts from the repository URL in `resources`: the agent clones it into its own cloud sandbox and opens the template the issue names. In `cloudflare/templates`, that Worker is `d1-template/`. Its `package.json` pins `wrangler` 4.136.1 and TypeScript 5.9.3, and defines `check` as `tsc && wrangler deploy --dry-run`, plus `seedLocalD1` for local migrations. `wrangler.json` binds a D1 database as `DB` with compatibility_date `2025-10-08` and does not declare a KV namespace yet.

The Worker today only reads. `src/index.ts` prepares `SELECT * FROM comments LIMIT 3`, calls `stmt.all()`, and returns HTML from `renderHtml` with the JSON rows embedded. The migration `migrations/0001_create_comments_table.sql` creates `comments (id, author, content)` and inserts three sample rows. There is no POST handler and no cache layer, so every request hits D1.

The agent adds a KV namespace binding in `wrangler.json`, reads the list query through a cache key with a 60 second TTL via `expirationTtl`, and returns the cached payload when present. It also adds a write path (POST that inserts a comment) that deletes the cache key after a successful D1 write so the next list is fresh. Types are regenerated with `wrangler types` so `Env` includes both `DB` and the KV binding.

Proving it means tests and the template's own check script. The agent adds a unit test that stubs D1 and KV, asserts a second list does not call D1 when the KV value is warm, and asserts a write deletes the key. Then it runs that test, `pnpm check` (tsc and `wrangler deploy --dry-run`) from the template directory.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "A Linear issue labeled agent says: \"Add KV Caching to a Cloudflare Worker. In d1-template, cache the list query's result in a KV namespace for 60 seconds and invalidate it on every write.\" Do the work in this repository, add tests for it, run the template's test, type check and wrangler deploy --dry-run, and open a pull request that links back to the issue.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request. Its diff updates `d1-template/src/index.ts`, `wrangler.json` with a KV binding, tests for cache hit and invalidation, and any `package.json` scripts needed to run them. The description quotes the issue and links back to it.

The checks on the pull request run the new test plus `tsc` and `wrangler deploy --dry-run`. A reviewer reads the 60 second TTL, confirms writes clear the list key, and confirms the HTML list path still renders comments from either cache or D1. Other templates in the monorepo stay untouched.

The session read keeps the record behind the pull request: typegen, the test run and the dry-run deploy. Anyone who questions a stale list can see the invalidation assertion in the trajectory.

## Run it on every Linear issue labelled agent

The Project's automation turns the label into the run. In the console, add an automation with a Linear trigger on `linear.issue.labeled` filtered to the `agent` label and this prompt; each labelled Workers performance issue starts its own run in its own sandbox and opens its own pull request on the templates repository.

If the automation is not wanted, a small server can do the same: receive Linear's issue webhook, put the issue text into `input`, and POST to `/o/{org}/sessions` with the cloudflare/templates repository in `resources`. A `run.completed` webhook on the API key posts the pull request when the dry-run deploy finishes.

## Why run it on Rush?

On a laptop this job needs wrangler, a Cloudflare login for some commands, and local D1 migrations before the Worker will serve comments. Each run on Rush boots its own sandbox with the toolchain already in reach, runs the template's check and tests itself, and keeps every command and its output, including the dry-run deploy that proves the KV binding binds.

Caching tickets compete with feature work on the same Worker. Labelling the issue gives it a dedicated sandbox so KV TTL and invalidation do not wait behind an unrelated Durable Object change in another template.

## Frequently asked questions

### The template has no write endpoint today. What does invalidate on write mean?

The agent adds a minimal POST that inserts into `comments` and deletes the list cache key afterward. Without a write path there is nothing to invalidate; the issue's second half requires that path.

### Is the cache in Cache API or KV?

KV, as the issue says. The agent binds a namespace in `wrangler.json` and uses `put` with `expirationTtl: 60` for the list payload.

### Does dry-run need account credentials?

`wrangler deploy --dry-run` validates the Worker bundle and bindings locally. The agent uses that path from the template's `check` script so the pull request does not depend on a production deploy.

### Will the HTML renderer change?

Only if the cached payload format needs a small adjustment. `renderHtml` still receives a JSON string of comment rows; the caching layer sits in front of the D1 `SELECT`.
