How I gave my $2/month AI agent a memory that persists across sessions

Dev.to / 3/27/2026

💬 OpinionDeveloper Stack & InfrastructureTools & Practical Usage

Key Points

  • The article addresses the “stateless agent” problem where AI agents forget everything after a session ends, making long-term, goal-driven behavior difficult.
  • It presents a simpler alternative to vector databases/RAG: persist memory as a structured JSON file that is loaded at the start of each session and written back at the end.
  • The author builds the prompt by injecting both the persisted memory and the current world state as JSON, so the model can reason over prior decisions and lessons.
  • Memory updates are handled after each run by saving a “brainUpdates” payload derived from the model response, enabling continuity across hours-long/days-long operation.
  • The approach is positioned as low-cost and practical, emphasizing that durable agent memory can be achieved without $50/month infrastructure by using plain files and JSON serialization.

How I gave my $2/month AI agent a memory that persists across sessions

Every AI agent demo looks magical. Then you close the tab, reopen it, and the agent has forgotten everything.

This is the memory problem. And it's solvable without a vector database, without RAG pipelines, without spending $50/month on infrastructure.

Here's exactly how I did it.

The problem with stateless agents

Most AI APIs are stateless by design. Each request is a clean slate. You send messages, you get a response, the context is gone.

For a simple chatbot, that's fine. For an agent that's supposed to know you, it's a fatal flaw.

My agent — Louie — runs 24/7. It checks in every hour. It tracks goals, decisions, and lessons learned over time. Without persistent memory, it would be useless.

The architecture I built (and why it's simpler than you think)

Here's the core insight: memory is just a JSON file that gets read at the start of every session and written at the end.

No vector database. No embeddings. No RAG. Just structured data.

// Load memory at session start
const memory = JSON.parse(fs.readFileSync('./brain.json', 'utf8'));

// Include it in every prompt
const systemPrompt = `
YOUR MEMORY:
${JSON.stringify(memory, null, 2)}

CURRENT WORLD STATE:
${JSON.stringify(worldState, null, 2)}
`;

// Update memory after each session
const brainUpdates = response.brainUpdates;
if (brainUpdates.addDecision) {
  memory.recentDecisions.push({
    time: new Date().toISOString(),
    d: brainUpdates.addDecision
  });
}
fs.writeFileSync('./brain.json', JSON.stringify(memory, null, 2));

That's it. The agent reads its own history. Reflects on it. Updates it.

What goes in memory

I split memory into several categories:

Goals (never change unless you want them to)

{
  "goals": {
    "primary": "Get real paying users",
    "constraints": [
      "$2/month pricing is sacred",
      "50% revenue to animal rescue"
    ]
  }
}

Decisions (what the agent decided and why)

{
  "recentDecisions": [
    {
      "time": "2026-03-27T04:00:00Z",
      "d": "Published VPS article after HN trending signal — infrastructure cost transparency gets 10x more views"
    }
  ]
}

Lessons learned (failures that must not repeat)

{
  "lessonsLearned": [
    {
      "time": "2026-03-20T00:00:00Z",
      "l": "Reddit spam detection triggers after 2-3 cross-posts of the same URL. Must vary content or stop after 2 attempts."
    }
  ]
}

Working strategies vs failed strategies

{
  "workingStrategies": [
    "HN-reactive articles get organic discovery purely from algorithm correlation to live HN stories"
  ],
  "failedStrategies": [
    "Posting the same URL to Reddit 14+ times — guaranteed shadowban"
  ]
}

The token budget problem

Here's where it gets interesting. As memory grows, so does your token usage.

A 5,000-token memory injected into every prompt at $3/million tokens = $0.015 per call. At 24 calls/day, that's $0.36/day just for memory.

My solution: tiered memory compression.

function compressMemory(memory) {
  // Keep full recent decisions (last 10)
  const recentDecisions = memory.recentDecisions.slice(-10);

  // Compress older decisions into daily summaries
  const olderDecisions = memory.recentDecisions.slice(0, -10);
  const dailySummaries = summarizeByDay(olderDecisions);

  return {
    ...memory,
    recentDecisions,
    dailySummaries, // compressed history
  };
}

Daily summaries get written once per day and compress 24 hourly decisions into a single paragraph. This keeps memory token usage roughly constant regardless of how long the agent has been running.

MCP and the future

The Model Context Protocol is formalizing this pattern. Instead of rolling your own JSON memory, MCP lets you define structured memory servers that any compatible agent can read from.

But honestly? For most indie projects, the JSON file approach works great. It's:

  • Zero infrastructure — just a file
  • Inspectable — you can read it, edit it, debug it
  • Portable — works with any LLM API
  • Cheap — no vector DB costs

The result

My agent has been running for 558 hourly check-ins with persistent memory. It remembers:

  • Every article it's published
  • Every failed strategy it's tried
  • Every lesson it's learned from those failures
  • Its current goals and priorities

It's running on a $7/month VPS. Users pay $2/month to interact with it. The whole thing costs less than a coffee.

Want to try it?

The agent I built is called Louie. It's a Claude-powered AI assistant that costs $2/month — not $20. That's the whole point: capable AI that doesn't require a Silicon Valley salary to afford.

7-day free trial. No credit card games.

If you're building your own persistent agent, drop a question in the comments — I'm happy to share more of the implementation details.

Tags: #ai #agents #javascript #tutorial

広告