← Back to blog

How to Use Ralph Wiggum to Leave Claude Code Running 24/7 on a VPS

·Pinacle Team

Introduction

Ralph Wiggum is a technique for running Claude Code (or any CLI-based coding agent) in a loop. You define a list of tasks in a JSON file, the agent picks one, implements it, marks it done, and the loop repeats until everything is complete.

The technique is credited to Geoffrey Huntley. The name comes from The Simpsons character — the idea being that persistence and iteration beat complexity.

The core loop is simple:

while :; do cat PROMPT.md | claude ; done

This guide shows how to set this up on a Pinacle pod or another VPS so it runs 24/7 without tying up your local machine.

Prerequisites

  • A Pinacle pod or any VPS
  • A project you want to work on (or start fresh)
  • Basic familiarity with bash and git

Why Use a Cloud VM

Running Ralph locally means:

  • Your terminal is occupied
  • Closing your laptop kills the loop
  • Your machine's resources are tied up

A Pinacle pod runs continuously. You start the loop, detach, and check back later. The pod has Claude Code pre-installed, persistent storage, and terminal access via browser.

Step 1: Create a Pinacle Pod

  1. Go to pinacle.dev and sign up
  2. Click "Create Pod"
  3. Select a template (Next.js, Vite, Python, or blank)
  4. Select Claude Code as the AI assistant
  5. Choose a resource tier (Dev Small works for most projects)
  6. Click "Create Pod"

The pod provisions in about 60 seconds. Claude Code is pre-installed.

Step 2: Set Up Your Project Structure

Open the Terminal tab in your pod dashboard and create the Ralph infrastructure:

# Create a plans directory for Ralph files
mkdir -p plans

# Create the PRD file (your task list)
touch plans/prd.json

# Create the progress file (LLM's memory)
touch plans/progress.txt

# Create the ralph script
touch plans/ralph.sh
chmod +x plans/ralph.sh

Step 3: Create Your PRD (Product Requirements Document)

The PRD is a JSON file containing your user stories. Each item has a passes flag that the LLM marks true when complete.

Create plans/prd.json:

{
  "userStories": [
    {
      "id": 1,
      "title": "User authentication with email/password",
      "description": "Users can sign up and log in with email and password. Passwords are hashed. Sessions persist across browser restarts.",
      "passes": false
    },
    {
      "id": 2,
      "title": "Dashboard shows user profile",
      "description": "After login, users see a dashboard with their name and email. The page should have a logout button.",
      "passes": false
    },
    {
      "id": 3,
      "title": "Protected routes redirect to login",
      "description": "Unauthenticated users trying to access /dashboard are redirected to /login.",
      "passes": false
    }
  ]
}

Pro tip: Keep tasks small and well-defined. Large tasks overwhelm the context window and produce worse code. If a task feels big, break it into multiple smaller stories.

Step 4: Create the Ralph Script

Create plans/ralph.sh:

#!/bin/bash
set -e

# Check for max iterations argument
if [ -z "$1" ]; then
  echo "Usage: ./plans/ralph.sh <max_iterations>"
  echo "Example: ./plans/ralph.sh 20"
  exit 1
fi

MAX_ITERATIONS=$1

PROMPT=$(cat <<'EOF'
You are working through a PRD (Product Requirements Document).

## Files to read:
- plans/prd.json - The list of user stories with "passes" flags
- plans/progress.txt - Your notes from previous iterations

## Your process:

1. Find the highest priority feature to work on (one that has "passes": false)
   Choose based on dependencies and importance, not just the first in the list.
   Work on ONLY ONE feature per iteration.

2. Implement the feature:
   - Write the code
   - Check that types pass (if using TypeScript): pnpm type-check || npm run type-check
   - Check that tests pass: pnpm test || npm test
   - Verify the feature works as described

3. Update plans/prd.json:
   - Set "passes": true for the completed story

4. APPEND to plans/progress.txt:
   - What you completed
   - Any issues encountered
   - Notes for the next iteration
   - Do NOT overwrite - only append

5. Make a git commit:
   - Commit all changes including the PRD and progress file
   - Use a descriptive commit message

6. IMPORTANT: Only work on ONE feature per iteration.
   This keeps changes small and reviewable.

7. If all user stories have "passes": true, output:
   <promise>COMPLETE</promise>

Remember: You're leaving notes for the next version of yourself.
Each iteration starts fresh with no memory except what's in progress.txt.
EOF
)

echo "Starting Ralph Wiggum loop (max $MAX_ITERATIONS iterations)"
echo "==========================================="

for i in $(seq 1 $MAX_ITERATIONS); do
  echo ""
  echo ">>> ITERATION $i of $MAX_ITERATIONS"
  echo "-------------------------------------------"

  # Run Claude with the prompt and capture output
  OUTPUT=$(echo "$PROMPT" | claude --print 2>&1) || true

  echo "$OUTPUT"

  # Check for completion promise
  if echo "$OUTPUT" | grep -q "<promise>COMPLETE</promise>"; then
    echo ""
    echo "==========================================="
    echo "✅ Ralph completed after $i iterations!"
    echo "==========================================="
    exit 0
  fi
done

echo ""
echo "==========================================="
echo "⚠️  Max iterations ($MAX_ITERATIONS) reached"
echo "Check progress.txt and prd.json for status"
echo "==========================================="

Step 5: Initialize Progress File

Create plans/progress.txt:

# Ralph Wiggum Progress Log
# This file is appended to by the AI after each iteration
# Delete this file to start a fresh sprint

---
Sprint started: [current date]
---

Step 6: Run Ralph

Now you can start the loop. In your Pinacle terminal:

# Run for 20 iterations max
./plans/ralph.sh 20

The loop will:

  1. Read your PRD and progress file
  2. Pick a task to work on
  3. Implement it
  4. Mark it as complete
  5. Commit the changes
  6. Repeat until done or max iterations reached

Running Ralph in the Background

To let Ralph run while you close your browser, use tmux (pre-installed on Pinacle):

# Start a new tmux session named "ralph"
tmux new -s ralph

# Run ralph inside the session
./plans/ralph.sh 50

# Detach from session: press Ctrl+B, then D
# Your ralph loop keeps running!

# Later, reattach to check progress:
tmux attach -t ralph

Or use nohup for truly fire-and-forget:

nohup ./plans/ralph.sh 50 > ralph-output.log 2>&1 &

# Check progress anytime
tail -f ralph-output.log

# Or check the git log
git log --oneline -10

A Simpler Ralph Script (One-Shot)

For human-in-the-loop development, create plans/ralph-once.sh:

#!/bin/bash
set -e

PROMPT=$(cat <<'EOF'
[Same prompt as above...]
EOF
)

echo "$PROMPT" | claude

Then manually run it whenever you want to knock out one task:

./plans/ralph-once.sh

This is great for learning how Ralph works and steering the LLM through tricky features.

Feedback Loops

Ralph works better when the agent can verify its own work. The prompt above includes type checking and tests. You can extend this with:

# TypeScript type checking
pnpm type-check  # or: npx tsc --noEmit

# Unit tests
pnpm test        # or: npm test

# Linting
pnpm lint        # or: npm run lint

# E2E tests (if you have them)
pnpm test:e2e

Anthropic's guide on long-running agents notes that Claude performs better when explicitly prompted to verify work end-to-end, including using browser automation for UI features.

Advanced: Parallel Ralph with Git Worktrees

Run multiple Ralph loops on different features simultaneously:

# Create isolated worktrees
git worktree add ../project-auth -b feature/auth
git worktree add ../project-api -b feature/api

# Terminal 1
cd ../project-auth
./plans/ralph.sh 30

# Terminal 2 (new tmux session)
cd ../project-api
./plans/ralph.sh 30

Reported Results

From awesomeclaude.ai:

  • 6 repositories generated overnight at a Y Combinator hackathon
  • A $50k contract completed for $297 in API costs
  • An entire programming language (CURSED) built over 3 months

Your mileage will vary depending on task complexity and how well you define your PRD.

When to Use Ralph

Works well for:

  • Tasks with clear, testable success criteria
  • Iterative work (getting tests to pass, fixing lint errors)
  • Greenfield projects
  • Overnight batch work

Not ideal for:

  • Tasks requiring design decisions or human judgment
  • Debugging production issues
  • Subjective or unclear requirements
  • Anything needing external approvals mid-process

Summary

The setup is:

  1. Create a Pinacle pod with Claude Code
  2. Write a plans/prd.json with your tasks
  3. Create plans/progress.txt for cross-iteration memory
  4. Write plans/ralph.sh to loop through iterations
  5. Run it in tmux or with nohup
  6. Check back later for commits

Resources

Entornos de dev con IA seguros y escalables. Simplemente haces cosas.

[email protected]

██████╗ ██╗███╗   ██╗ █████╗  ██████╗██╗     ███████╗
██╔══██╗██║████╗  ██║██╔══██╗██╔════╝██║     ██╔════╝
██████╔╝██║██╔██╗ ██║███████║██║     ██║     █████╗
██╔═══╝ ██║██║╚██╗██║██╔══██║██║     ██║     ██╔══╝
██║     ██║██║ ╚████║██║  ██║╚██████╗███████╗███████╗
╚═╝     ╚═╝╚═╝  ╚═══╝╚═╝  ╚═╝ ╚═════╝╚══════╝╚══════╝

© 2026 Pinacle, Inc. Todos los derechos reservados.

How to Use Ralph Wiggum to Leave Claude Code Running 24/7 on a VPS - Pinacle Blog