Blog · 2026-05-21

Give your agent memory with denkops.store

Persist agent state with denkops.store, a key-value API with TTL on the durable /persist disk. Survives redeploys, works locally, in Bun and Python.

Your agent's backend can remember things in one line: denkops.store.set("key", "value"). The store is a key-value API built into the DenkOps SDK, saved on the durable /persist disk, so whatever your app writes is still there after a restart or a redeploy. No database to provision, no connection string, no extra service to keep alive.

What is denkops.store?

denkops.store is the default surface of @denkopsai/sdk (Bun) and the denkops package (Python). It has four methods, get, set, delete, and list, plus an optional TTL per key. Values are strings, so JSON-encode anything structured. The data lives in a single file on the /persist disk attached to your always-on slot, which means state written by version 12 of your app is readable by version 13.

How do I use it from Bun?

import denkops from "@denkopsai/sdk";

// remember something indefinitely
denkops.store.set("memory:preferred-name", "Sam");

// remember something for an hour
denkops.store.set(
  "session:sam",
  JSON.stringify({ step: 2, cart: ["sku-1"] }),
  { ttlSeconds: 3600 },
);

denkops.store.get("memory:preferred-name"); // "Sam"
denkops.store.list("memory:");              // ["memory:preferred-name"]
denkops.store.delete("session:sam");

get returns null for a missing or expired key, and expired keys drop out of list as well. list takes a key prefix, which is how you get namespaces for free: memory:, session:, cache:, whatever fits your app.

What about Python?

Same store, same file, same semantics:

import denkops

denkops.store.set("memory:preferred-name", "Sam")
denkops.store.set("session:sam", '{"step": 2}', ttl_seconds=3600)

denkops.store.get("memory:preferred-name")  # "Sam"
denkops.store.list("memory:")               # ["memory:preferred-name"]
denkops.store.delete("session:sam")

The only differences are idiomatic: the TTL argument is ttl_seconds, and get returns None instead of null.

Does the same code work on my laptop?

Yes, the store is env-aware. In the cloud it writes to the /persist volume. On your machine the exact same code writes to a .denkops_local directory inside your project, so local development runs against the real API instead of a mock. Add .denkops_local to .gitignore and you are done. When you deploy, nothing changes except where the file lives.

What should an agent actually store?

The patterns that keep coming up on hosted agent backends:

  • Memory: facts and preferences an assistant should keep across conversations, under a memory: prefix with no TTL.
  • Session state: multi-step workflows in flight, with a TTL so abandoned sessions clean themselves up.
  • Caches: responses from slow or rate-limited external APIs, with a short TTL.
  • Event feeds: webhook payloads a tool can query later, a pattern worth its own post.

This works because a DenkOps app is a process that stays up, not a function that forgets everything between invocations. The store is for state, the always-on process is for everything you can keep in memory anyway.

FAQ

Does denkops.store survive a redeploy?

Yes. The store writes to the durable /persist disk attached to your slot, and that disk carries over across restarts and redeploys. Keys you wrote before shipping a new version are still readable after it.

Can I store objects or only strings?

Values are strings. Serialize structured data yourself: JSON.stringify and JSON.parse in Bun, json.dumps and json.loads in Python. Keys are plain strings too, and prefix conventions like session:123 give you cheap namespacing via list(prefix).

How do TTLs work in denkops.store?

Pass ttlSeconds (Bun) or ttl_seconds (Python) to set. After the TTL passes, get returns null (None in Python) and the key no longer appears in list results. Omit the TTL and the key lives until you delete it.

Ship it yourself: bunx denkops deploy or say "deploy on DenkOps" from your coding agent.

Start on DenkOps →

← MCP needs a process, not a lambda · A webhook your agent can query →