How Do I Set Up AI Agents to Run Autonomously Overnight?
Purpose
I saw a Reddit post where someone ran 7 AI agents overnight to build products. They said: “I basically just approved things and clicked buttons” in the morning. That caught my attention.
This post shows how I set up AI agents that run autonomously overnight. The key is building three components: a task queue with scheduling, an orchestration layer with LangGraph, and a monitoring dashboard for morning review.
Problem
I wanted my AI agents to work while I sleep. My first attempt failed:
# This doesn't work for overnight runsasync def run_agent(): result = await agent.process(task) return result
# Problem: No scheduling, no persistence, no monitoringI woke up to crashed processes, lost state, and no visibility into what happened. The agents ran for 2 hours then failed silently.
What You Need
To run agents overnight, you need three pillars:
- Task Queue with Scheduling - Store tasks, schedule them, handle failures
- Orchestration Layer - Coordinate agents, persist state, route work
- Monitoring Dashboard - See progress, approve decisions, catch errors
Here’s the architecture:
┌─────────────────────────────────────────────────────────────┐│ OVERNIGHT AGENT SYSTEM │├─────────────────────────────────────────────────────────────┤│ ││ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ││ │ Task Queue │───>│ Orchestrator │───>│ Agents │ ││ │ (PostgreSQL) │ │ (LangGraph) │ │ (Claude/GPT) │ ││ └──────────────┘ └──────────────┘ └──────────────┘ ││ │ │ │ ││ │ v │ ││ │ ┌──────────────┐ │ ││ └──────────>│ Memory │<───────────┘ ││ │ (Vector DB) │ ││ └──────────────┘ ││ │ ││ v ││ ┌──────────────┐ ││ │ Dashboard │ ││ │ (Monitor) │ ││ └──────────────┘ ││ │└─────────────────────────────────────────────────────────────┘Where Should Agents Live?
Before building anything, I needed to decide where to run agents overnight.
Option A: Cloud Server (Recommended)
I chose a cloud VM for production reliability. It runs 24/7 without my computer.
Pros:- 24/7 availability without your computer running- Consistent environment- Easy scaling
Cons:- Monthly cost ($20-100/month for basic instances)- Requires initial setup
Best for: Production workloads, consistent overnight runsOption B: Home Computer
I tested this first but switched to cloud after issues.
Pros:- No additional hosting cost- Full control over hardware- Local file access
Cons:- Must keep computer on overnight- Power consumption- Potential interruptions (updates, crashes)
Best for: Experimentation, local developmentOption C: Managed Platform
For quick starts, platforms like Modal or RunPod handle infrastructure.
Pros:- Zero infrastructure management- Built-in scheduling- Easy deployment
Cons:- Higher cost- Less customization
Examples: Modal, RunPod, ReplicateBest for: Quick start, minimal DevOpsPhase 1: Build Task Queue
I started with a PostgreSQL-based task queue. Here’s my implementation:
from datetime import datetime, timedeltafrom dataclasses import dataclassfrom enum import Enumimport asyncio
class TaskStatus(Enum): PENDING = "pending" RUNNING = "running" AWAITING_APPROVAL = "awaiting_approval" COMPLETED = "completed" FAILED = "failed"
@dataclassclass ScheduledTask: id: str task_type: str # research, write, review, publish payload: dict priority: int scheduled_at: datetime status: TaskStatus = TaskStatus.PENDING retry_count: int = 0 max_retries: int = 3
class OvernightTaskQueue: """Manages overnight task scheduling and execution."""
def __init__(self, db_connection): self.db = db_connection self.agents = {} # agent registry
async def schedule_overnight(self, tasks: list[ScheduledTask]): """Queue tasks for overnight execution.""" for task in tasks: # Schedule for 2 AM next day overnight_time = datetime.now().replace( hour=2, minute=0, second=0 ) + timedelta(days=1)
task.scheduled_at = overnight_time await self._persist_task(task)
async def run_overnight_loop(self): """Main loop that runs during overnight window.""" while True: # Check if within overnight window (11 PM - 6 AM) now = datetime.now() if not self._is_overnight_window(now): await asyncio.sleep(300) # Check every 5 min continue
# Fetch pending tasks tasks = await self._fetch_pending_tasks()
for task in tasks: try: await self._execute_task(task) except Exception as e: await self._handle_failure(task, e)
await asyncio.sleep(60) # Poll every minute
def _is_overnight_window(self, dt: datetime) -> bool: """Check if current time is within overnight window.""" hour = dt.hour return hour >= 23 or hour < 6
async def _execute_task(self, task: ScheduledTask): """Execute a single task with appropriate agent.""" agent = self.agents.get(task.task_type) if not agent: raise ValueError(f"No agent for task type: {task.task_type}")
task.status = TaskStatus.RUNNING await self._update_task(task)
result = await agent.execute(task.payload)
if result.needs_approval: task.status = TaskStatus.AWAITING_APPROVAL else: task.status = TaskStatus.COMPLETED
await self._update_task(task)The key insight: I track task status separately from execution. This lets me resume after failures.
Phase 2: Orchestration Layer
I used LangGraph for orchestrating agent workflows. It handles state persistence natively.
from langgraph.graph import StateGraph, ENDfrom typing import TypedDict, Annotatedimport operator
class OvernightState(TypedDict): tasks: list[dict] completed: Annotated[list[dict], operator.add] pending_approvals: list[dict] errors: Annotated[list[str], operator.add] session_id: str
def supervisor_node(state: OvernightState) -> dict: """Routes tasks to appropriate agents.""" if not state["tasks"]: return {"tasks": []}
next_task = state["tasks"][0] remaining = state["tasks"][1:]
return { "tasks": remaining, "current_task": next_task }
def research_agent_node(state: OvernightState) -> dict: """Agent that researches topics overnight.""" task = state.get("current_task") if not task: return {}
# Call Claude/GPT API for research result = { "task_id": task["id"], "research_output": "...", "sources": ["..."] }
return {"completed": [result]}
def writer_agent_node(state: OvernightState) -> dict: """Agent that creates content from research.""" completed = state["completed"] research = [c for c in completed if c.get("research_output")]
if not research: return {}
# Create content from research article = { "task_id": research[0]["task_id"], "content": "...", "needs_review": True # Flag for human approval }
if article["needs_review"]: return {"pending_approvals": [article]}
return {"completed": [article]}
def approval_check_node(state: OvernightState) -> str: """Check if task needs human approval.""" if state["pending_approvals"]: return "await_approval" if state["tasks"]: return "supervisor" return END
# Build the overnight workflowworkflow = StateGraph(OvernightState)workflow.add_node("supervisor", supervisor_node)workflow.add_node("research_agent", research_agent_node)workflow.add_node("writer_agent", writer_agent_node)
workflow.set_entry_point("supervisor")workflow.add_edge("supervisor", "research_agent")workflow.add_edge("research_agent", "writer_agent")workflow.add_conditional_edges( "writer_agent", approval_check_node, { "await_approval": END, # Pause for morning review "supervisor": "supervisor", END: END })
overnight_app = workflow.compile()The important part: needs_review flag. Agents don’t auto-publish or auto-deploy. They queue decisions for my morning review.
Phase 3: Monitoring Dashboard
I built a simple Flask dashboard to review overnight work:
from flask import Flask, render_template, jsonify
app = Flask(__name__)
@app.route("/dashboard")def dashboard(): """Main dashboard showing overnight agent status.""" summaries = get_overnight_summaries() pending_approvals = get_pending_approvals()
return render_template( "dashboard.html", summaries=summaries, pending_approvals=pending_approvals, overnight_window="11 PM - 6 AM" )
@app.route("/api/approve/<task_id>", methods=["POST"])def approve_task(task_id): """Approve a pending task from dashboard.""" task = get_task(task_id) task.status = TaskStatus.COMPLETED save_task(task)
return jsonify({"status": "approved", "task_id": task_id})
@app.route("/api/overnight-report")def overnight_report(): """API endpoint for overnight run summary.""" return jsonify({ "total_tasks": 47, "completed": 42, "failed": 2, "pending_approval": 3, "total_cost": 12.50, "run_duration_hours": 7.2, "agents_used": ["research", "writer", "publisher"] })
@app.route("/morning-review")def morning_review(): """Dashboard for overnight results requiring human review.""" return { "completed_overnight": [ {"task": "research_market_trends", "status": "done"}, {"task": "draft_blog_posts", "status": "done", "count": 5}, {"task": "generate_product_ideas", "status": "done", "count": 12} ], "pending_approval": [ {"task": "publish_article", "preview_url": "..."}, {"task": "deploy_feature", "diff_url": "..."}, {"task": "spend_budget", "amount": 50} ], "overnight_cost": 12.50, "time_saved_hours": 6.5 }My morning workflow: open the dashboard, review pending approvals, click approve or reject. That’s the “approve things and click buttons” experience.
Server Deployment
I deployed on a DigitalOcean droplet ($20/month). Here’s the setup:
# Using a cloud VM (DigitalOcean, AWS, GCP, etc.)
# 1. Create server (e.g., $20/month droplet)# 2. Install dependenciessudo apt updatesudo apt install python3.11 python3-pip postgresql redis-server
# 3. Clone your agent projectgit clone https://github.com/yourusername/your-agent-project.gitcd your-agent-project
# 4. Set up environmentpython3 -m venv venvsource venv/bin/activatepip install -r requirements.txt
# 5. Configure environment variablesexport ANTHROPIC_API_KEY="your-key"export OPENAI_API_KEY="your-key"export DATABASE_URL="postgresql://..."
# 6. Set up systemd service for overnight runssudo cat > /etc/systemd/system/overnight-agents.service << EOF[Unit]Description=Overnight AI AgentsAfter=network.target
[Service]Type=simpleUser=youruserWorkingDirectory=/home/youruser/your-agent-projectExecStart=/home/youruser/your-agent-project/venv/bin/python run_overnight.pyRestart=alwaysRestartSec=60
[Install]WantedBy=multi-user.targetEOF
sudo systemctl enable overnight-agentssudo systemctl start overnight-agentsThe main entry point:
import asynciofrom datetime import datetime, time
async def main(): queue = OvernightTaskQueue(db_connection) orchestrator = build_overnight_orchestrator()
# Run only during overnight window while True: now = datetime.now().time()
# Overnight window: 11 PM to 6 AM if time(23, 0) <= now or now < time(6, 0): print(f"[{datetime.now()}] Overnight window active") await queue.run_overnight_loop() else: print(f"[{datetime.now()}] Outside overnight window, waiting...") await asyncio.sleep(300) # Check every 5 minutes
if __name__ == "__main__": asyncio.run(main())Pitfalls I Hit
Pitfall 1: No State Persistence
My first version lost context between sessions. The agents would start fresh each night.
Fix: Add LangGraph checkpointing:
from langgraph.checkpoint.memory import MemorySaver
checkpointer = MemorySaver()app = workflow.compile(checkpointer=checkpointer)
# Resume from previous sessionconfig = {"configurable": {"thread_id": "overnight-session-2026-03-16"}}Pitfall 2: Infinite Loops
One agent got stuck in a loop, burning through API budget overnight.
Fix: Add timeouts and budget caps:
async def execute_with_timeout(agent, task, timeout_seconds=300): try: return await asyncio.wait_for( agent.execute(task), timeout=timeout_seconds ) except asyncio.TimeoutError: return {"error": "timeout", "task_id": task["id"]}Pitfall 3: No Retry Logic
API failures would kill the entire overnight run.
Fix: Exponential backoff retries:
async def execute_with_retry(agent, task, max_retries=3): for attempt in range(max_retries): try: return await agent.execute(task) except Exception as e: if attempt == max_retries - 1: raise wait_time = 2 ** attempt * 60 # 1, 2, 4 minutes await asyncio.sleep(wait_time)Pitfall 4: Missing Approval Gates
I accidentally let an agent publish content without review. Not good.
Fix: Explicit approval list:
APPROVAL_REQUIRED_FOR = [ "publish_content", "deploy_code", "spend_money", "delete_files"]
def should_require_approval(action: str, confidence: float) -> bool: if action in APPROVAL_REQUIRED_FOR: return True return confidence < 0.8Cost Breakdown
Here’s what I pay per month:
| Component | Service | Cost ||-----------------|----------------------|-------------|| Cloud Server | DigitalOcean Droplet | $20-40 || Database | Managed PostgreSQL | $15-50 || Vector Store | Pinecone Starter | Free-$70 || AI API Calls | Claude/GPT | $50-200 || Total | | $85-360/mo |Cost optimization tips I learned:
- Use cheaper models for simple tasks (Claude Haiku, GPT-4o-mini)
- Batch similar tasks to reduce API overhead
- Implement caching for repeated operations
- Set daily cost limits with alerts
Framework Comparison
I tested different orchestration frameworks:
| Framework | Overnight Suitability | Key Feature ||------------|----------------------|--------------------------------|| LangGraph | Excellent | State persistence, clear routing || CrewAI | Good | Role-based agents, built-in memory || AutoGen | Moderate | Conversation patterns, heavier setup || Custom | Variable | Full control, more maintenance |I recommend LangGraph for overnight orchestration. It handles state persistence natively and has clear patterns for pausing/resuming workflows.
Summary
In this post, I showed how to set up AI agents that run autonomously overnight. The key is building three components:
- Task Queue - PostgreSQL-based scheduling with overnight window detection
- Orchestration Layer - LangGraph for state management and agent coordination
- Monitoring Dashboard - Flask-based approval interface for morning review
The Reddit poster was right: once you have this infrastructure, you “basically just approve things and click buttons” in the morning. My agents now handle research, content creation, and product development while I sleep.
Deploy on a cloud server for reliability, add checkpointing for session persistence, and always add approval gates for critical actions.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Reddit: AI agents paying for themselves
- 👨💻 LangGraph Documentation
- 👨💻 Circuit Breaker Pattern
- 👨💻 Modal - Serverless GPU Platform
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments