Last month I counted what it takes to keep my AI agents running around the clock. It is not a server rack. It is two Mac Minis on a desk, connected by one cable, running 24/7. This is exactly how I set it up, what broke, and what I would do differently.
I am not an engineer. I run revenue for a YouTube education company and a local water treatment business, and the agents handle the repetitive work: lead pulls, content drafts, reports, monitoring. If you can follow a recipe, you can follow this.
Why a Mac Mini and not the cloud
I started on rented servers. Two problems showed up fast. First, the bill grows every time you add an agent, and it grows quietly. Second, the agents need access to my files, my scripts and my local tools, and wiring all of that into a cloud box is its own project.
A Mac Mini with an M4 chip and 16GB of memory is a computer you buy once. It sits quiet, uses little power, and runs macOS, so the scheduling tools are built in. If you want the full cost picture of an AI setup, I broke that down in The Real Cost of AI Implementation.
My setup: two machines, two jobs
I run two Minis and give each one a single job.
- Machine 1 is the executor. It runs Claude Code, the scheduled jobs, the dashboards and the scripts. When an agent needs to write a report or pull leads, it happens here.
- Machine 2 is the local model server. It runs Ollama with Gemma models and does the cheap, simple work: heartbeats, status checks, classification, data extraction. This work costs zero tokens because the model lives on my own hardware.
The two machines connect over a Thunderbolt cable, which gives about 0.6 milliseconds of latency between them. For comparison, a call to a cloud API takes far longer. Machine 1 treats Machine 2 like a free assistant in the next room.
Step 1: Make the machine stay awake and come back by itself
This is the boring step that decides whether your agents are real or a demo.
- Turn on automatic login for the user account that runs your agents.
- In System Settings, set the Mac to start up automatically after a power failure and to never sleep on power adapter.
- Run every long-lived process as a launchd service with KeepAlive turned on. If the process dies, macOS restarts it. If the whole machine reboots, everything relaunches on its own.
I tested this by shutting the machine down and walking away. When it came back, the dashboards, the tunnel and the schedulers were all running without me touching anything. If you skip this test, you will find out about the gap at 2 AM.
Step 2: Use launchd for scheduling, not a pile of loops
Every recurring job I have is a launchd LaunchAgent: a small file that says “run this script at this time.” Daily lead pulls, report builds, content jobs, health checks. Each one is its own file, so I can see exactly what is scheduled and turn one off without touching the rest.
Retired jobs get moved into an archive folder instead of deleted. That way I can always see what used to run and why I stopped it.
Step 3: Install Claude Code and run it headless
Claude Code is the brain for anything that needs real judgment: writing, analysis, multi-step builds. The scheduled jobs call it from the command line in non-interactive mode, and I always pass the model explicitly: Opus for planning, Sonnet for building, Haiku for checking.
I learned to always name the model after finding that the bare default on my machine resolved to a different model than I expected. Naming it every time removes the guesswork. I wrote about how that routing saves money in AI Model Routing: How I Cut Token Costs.
One more safety net: a watchdog job runs every hour and kills any headless Claude run that has been stuck for more than two hours. Without it, one hung job can sit there all weekend holding resources.
Step 4: Put the free work on Ollama
Install Ollama on the second machine, pull a Gemma model, and point your scripts at its address. Anything that does not need top-tier reasoning goes there: “is this service up,” “which category is this email,” “pull the phone number out of this text.”
Here is the lesson that cost me the most. A 16GB machine holds one model in memory at a time. I had two Gemma sizes loaded by different scripts, and every time one script asked for the other model, Ollama swapped them. The swap costs several seconds and kicks out whoever was working. Scripts started timing out, and the system thrashed for most of a day before I traced it.
The fix was a simple set of rules:
- One fast model for anything a person or a live call is waiting on.
- The larger model only for unattended batch jobs, scheduled overnight.
- No script is allowed to fall back from one model to the other. If the model it needs is busy, it fails loudly so I find out.
- Every call sets a timeout and a cap on output length.
I go deeper on when local models win in Local AI Models vs Cloud AI: When Free Beats Paid.
Step 5: Reach it from anywhere
I live part of the time in Mexico and fly to Idaho for custody days, so the machines have to be reachable from wherever I am. Tailscale gives every device a private address, and I can SSH into either Mini from my laptop or phone. For dashboards that other people need to open, a Cloudflare tunnel exposes just those pages. I keep exactly one tunnel connector, because a second one causes confusing routing problems.
What goes wrong (so you can skip it)
- Disk fills up. A 228GB drive got tight because of video files. Heavy media goes on the machine with free space, and I check disk monthly.
- Keys end up in scripts. Every API key lives in one .env file and nowhere else. Scripts read from it and never contain the key.
- Silent failures. A job that fails quietly is worse than one that crashes. Anything critical posts to a dashboard I check, and only true emergencies reach my phone.
- Too many cooks. Early on I had agents with overlapping jobs. One agent per job, with one clear output, fixed it.
What this does not do
A Mac Mini does not give you intelligence. The Claude calls still run on Anthropic’s servers and still count against a plan. The Minis give you a reliable place to run the schedule, hold the files and handle the free work. If your agents only need to run once a week, a laptop is fine. This setup earns its keep when agents run every day and you want them to keep working while you are on a plane.
What to do next
- Pick one job. Choose a single recurring task, such as a daily report, and make it run on a schedule through launchd.
- Do the reboot test. Restart the machine and confirm the job still runs without you logging in.
- Add one free local task. Install Ollama and move a simple check, like a status ping, onto it.
- Name your model every time. In every Claude command, state the model so the cost and quality are predictable.
- Add a watchdog. One small hourly job that kills stuck processes and writes to a log you can read.
Start with step one this weekend. A single scheduled job that survives a reboot is worth more than ten agents that only run when you are watching.