How I Monitor 20 Texas Counties from a Mac Mini
My entire data pipeline — 20 Texas counties, 800,000+ distressed-property records, five signal types, health monitoring, social posting, email campaigns, and billing reconciliation — runs on a Mac Mini that cost $699 and sits under a desk.
No AWS. No Kubernetes. No DevOps team. One computer, a handful of cron jobs, and the discipline to automate the right things.
The architecture
The core idea is simple: macOS has a built-in job scheduler called launchd, and it's better than most people realize. Every recurring task in my system is a .plist file — a small XML document that tells the Mac "run this script at this interval." The Mac handles the scheduling, the retry logic, and the logging. I handle the scripts.
Here's what's running:
- Data scrapers — Python scripts that pull pre-foreclosures, tax delinquencies, code violations, permits, and cash-buyer records from county websites and public databases. Each county has its own scraper (or shares one with a configurable county parameter). They run on staggered schedules — some hourly, some daily, some weekly — depending on how frequently the source updates.
- Health monitoring — a script that checks every table in every county, counts records, measures address coverage, geocoding coverage, and value coverage, and writes a letter grade (A through F) to a dashboard. Runs every hour.
- Social posting — an engine that posts to Twitter, Facebook, and Instagram three times a day for the main brand. Picks from a library of pre-written posts, adds the right image, handles API auth, and logs what it posted.
- Billing sync — pulls Stripe charges and checkout sessions every six hours, reconciles them against the client database, and flags mismatches to a Telegram channel.
- Bounce guard — monitors email campaign bounce rates via the Instantly API and auto-pauses any campaign that crosses 3%. This one has already saved us once — it caught a bad list segment before it could damage sender reputation.
- Site uptime — checks that every production URL returns 200. If something's down, Telegram notification within a minute.
Total: about 140 LaunchAgents. Most of them are lightweight — a Python script that runs for ten seconds, writes a result, and exits. A few (the scrapers for large counties) run for minutes. None of them need more than 2GB of RAM.
What it watches
Five data types, twenty counties:
Pre-foreclosures — notices of default and foreclosure sales filed with county clerks. The most valuable signal for investors. Updated daily in most counties. Coverage: 35,000+ active records.
Tax delinquencies — properties with unpaid property taxes. Often a precursor to a tax lien sale. Updated monthly in most counties. Coverage: 150,000+ records.
Code violations — open violations from city code enforcement. Indicates distress or neglect. Updated daily to weekly. Coverage: 1,000,000+ records (Dallas alone has 700K+ historical violations).
Permits — building permits indicating renovation, construction, or demolition activity. Updated daily. Coverage: 330,000+ records.
Cash buyers — recent cash purchases extracted from deed records. Indicates active investors in the area. Updated weekly. Coverage: 3,500+ records.
Each table in each county gets graded on three dimensions: address completeness (can we locate the property?), geocoding completeness (can we put it on a map?), and value completeness (do we know what it's worth?). The grades feed a health dashboard that I check every morning.
The cost breakdown
This is the part people don't believe until I show the numbers.
| Component | Monthly Cost |
|---|---|
| Mac Mini (M2, amortized over 3 years) | ~$19 |
| Electricity | ~$5 |
| Internet (shared household) | ~$0 incremental |
| Supabase (production database) | $25 |
| Render (web hosting for 5 sites) | $29–$60 |
| Domain names (amortized) | ~$5 |
| Instantly (email sending) | $30 |
| Total | ~$115–$145/mo |
The compute is free. macOS runs launchd for free. Python is free. The scrapers are free. The monitoring is free. The social posting engine is free. The billing reconciliation is free. The bounce guard is free.
The things that cost money are the things that should cost money: a real database, real hosting, real email infrastructure. Everything else is code running on a machine I already own.
For comparison: the cloud equivalent of this system — 140 scheduled functions, a managed database, five web services, monitoring, and email infrastructure — would run $300–$800/month on AWS or GCP, depending on configuration. More if you use managed cron services, more if you want the monitoring dashboards, more if someone else is managing the infrastructure.
I'm not anti-cloud. For a team of five, or for a system that needs to scale horizontally, cloud makes sense. But for a one-operator data business doing a known, bounded workload? A Mac Mini is cheaper, simpler, and easier to debug.
What breaks and how it self-heals
Things break. Here's what's gone wrong and what catches it:
Scrapers hit rate limits. County websites have varying tolerance for automated requests. Some serve happily at 10 requests per second; others start returning 429s after three. Every scraper has built-in backoff — exponential delay on 429s, session rotation on 403s, and a maximum-retry ceiling. If a scraper fails after retries, it logs the failure and moves on. The health monitor catches the gap in the next hourly sweep.
Render deploys hang. The web hosting platform (Render) occasionally gets a deploy stuck in a "building" state for hours. The autonomy system checks deploy status every cycle and cancels any build that's been running longer than fifteen minutes, then triggers a fresh deploy from HEAD. This has happened three times in two months. All three times, the system caught it and recovered without human intervention.
Database connections drop. Supabase (the PostgreSQL provider) occasionally drops long-running connections. Every database call in the pipeline uses retry logic with connection pooling — if the first attempt fails, it waits, reconnects, and tries again. The scripts are idempotent, so a retry never produces duplicates.
Email bounce rates spike. The bounce guard watches Instantly campaign metrics via API. If any campaign crosses 3% bounce rate, it auto-pauses the campaign and sends a Telegram alert. This caught a bad segment in the TXS outreach campaign at 2.5% — the auto-pause kicked in before it could damage the domain's sender reputation. Without the guard, that would have been a manual discovery, hours or days later.
Memory pressure. The Mac Mini has 16GB of RAM. Running 140 agents plus a local development environment occasionally pushes it. The solution is boring: the agents are designed to be short-lived. A scraper starts, does its work, writes the result, and exits. It doesn't sit in memory waiting for the next run — launchd handles the scheduling. Peak memory usage is typically under 8GB.
Why not cloud
I get this question a lot, so let me answer it directly.
Predictable workload. I know exactly how many scrapers run, how often, and how much data they produce. There's no spiky traffic pattern that needs auto-scaling. The workload is a flat line with small bumps, every day, forever.
Debugging is local. When a scraper breaks, I can open the script in my editor, read the log on my filesystem, and test the fix immediately. No SSH, no container rebuilds, no deploy pipelines. The feedback loop is measured in seconds, not minutes.
Cost ceiling is visible. My hosting bill is the same every month. There's no surprise Lambda invocation charge, no unexpected data-transfer fee, no "you left a NAT gateway running" moment. The Mac was a one-time purchase. The rest is subscription software with published prices.
Single point of failure is acceptable. Yes, if the Mac dies, everything stops. For a one-operator business doing $900/month in revenue, that's an acceptable risk. I have backups. I can restore to a new machine in a day. The data is in Supabase (cloud-hosted, replicated). The code is in Git. The only thing the Mac holds that isn't backed up elsewhere is the running cron state — and that recovers automatically on reboot.
If this were a $50K/month SaaS with uptime SLAs, I'd run it differently. It's not. It's a bootstrapped data business where the right amount of infrastructure is the minimum that works.
The real lesson
You don't need AWS. You don't need Kubernetes. You don't need a DevOps hire. You need a computer that turns on, a job scheduler, and the discipline to make every script idempotent, every failure recoverable, and every cost visible.
The Mac Mini under the desk is not a temporary hack while I "wait to scale." It's the architecture. It's the right tool for a one-person operation that runs a known workload at a known cost, and it'll stay the right tool until the workload outgrows it — which, based on the current trajectory, won't happen for a long time.
The system runs. The data refreshes. The scrapers scrape. The monitors monitor. And the total cost is less than what most people pay for a single SaaS tool they only half-use.
If running a data business from a Mac Mini sounds like your kind of infrastructure, the newsletter is where I share the systems, the costs, and the things that break at 3 AM.
Everything in this blog is built on the same data that powers Texas Signals: 8M+ property records, pre-foreclosures, tax delinquencies, and distress signals across 12+ Texas counties. Free 7-day trial.
Try Texas Signals FreeCheck out my books on Amazon and Gumroad — same operator voice, deeper frameworks.