ATLAS

How it runs, what it costs, where every piece lives

Three tiers, never mixed. The customer-facing front-end is static and free. One shared control plane is the brain. The worker boxes are pure back-end muscle that scale with customers. Built to run as cheap as physically possible: about a dollar a month in fixed cost.

Hosting

Where the front-end lives, and the box question

The front-end is not on a scanner box at all. Both the marketing site and the customer dashboard are static on Cloudflare Pages, free, on a global CDN. The boxes never serve a line of HTML.

Tier 1 · Front-end (everything the customer sees) $0

Cloudflare Pages, static

The marketing site (getatlas.com) and the dashboard app (app.getatlas.com) are both static front-ends on Cloudflare Pages. Global CDN, free, fast, nothing sensitive. The dashboard is a single-page app that talks to the control-plane API over HTTPS. Reuses your existing ~/projects/atlas-site.

dashboard calls the API
Tier 2 · Control plane (the brain, shared by everyone) $0

Cloudflare Workers + D1

One shared API + database + provisioner for all customers. Stores customer config, watchlists, recent finds, and auth. Provisions worker boxes through the Hetzner, Oxylabs, and Cloudflare DNS APIs. Serverless, so it costs nothing at our scale and there is no box to babysit. (Simpler-to-debug alternative: the same logic as a plain Node app on one ~$5/mo VPS.)

provisions boxes, receives finds
Tier 3 · Worker boxes (the muscle) per customer

Hetzner CX21, 2 to 4 customers each

Pure back-end, exactly as you wanted: just a script. No UI, no marketing, no login. Headless scanners for the customers packed on the box, hitting marketplaces through their proxies, pulling config from and pushing finds to the control plane. The only tier that grows with customer count.

No, nobody has two boxes. There is one control plane for the whole product (serverless, so not even a box), and every customer shares a worker box with one to three others. A customer uses a slice of one worker box plus the shared control plane. That is it.
The Stack

Every service you need, as cheap as it goes

This is your whole bill. Everything on the control side is on Cloudflare's free tier (you already use Cloudflare), so the only money that moves is per-customer, and the price covers it. Fixed overhead is about a dollar a month.

What it doesCheapest serviceCostScales with
Marketing site + dashboard (front-end)Cloudflare Pages$0nothing
API (auth, watchlist, finds)Cloudflare Workers$0100k req/day free, we are far under
Database (customers, searches, finds)Cloudflare D1$05 GB free
Provisioner (purchase to live box)Cloudflare Worker + Cron$0nothing
Credential emailResend free tier$03k emails/mo free
NotificationsTelegram Bot API$0free forever
AI deal scoring (optional)Customer's own Gemini key (Google free tier)$0customer brings it
Image storagenone (we link the marketplace image URL)$0not stored
DomainCloudflare Registrar~$1/monothing
BillingWhop4% of revenuerevenue
Scanning computeHetzner CX21 (2 to 4 customers/box)~$5/mo per boxcustomers
ProxiesOxylabs Dedicated ISP AS7922~$16 per customercustomers
Why scanning cannot be serverless (the one real cost): a scanner runs a continuous loop, holds a session on a specific dedicated proxy IP, and sweeps every few minutes for hours. Serverless functions (Cloudflare Workers, AWS Lambda) time out in seconds to minutes and cannot hold that, so doing it serverless would be slower and more expensive, not cheaper. Real boxes are both correct and cheap here, and the box cost is covered many times over by the $60 price. AWS would work but is more complex and not cheaper than Cloudflare for this; since you already run Cloudflare, stay there.
Fixed overhead, whether 5 customers or 50~$1/mo (just the domain)
Per customer (covered by price)~$16 proxies + ~$5 box share
Throughput

Run as many as you want. Live count sets the speed.

There is no limit on how many searches you keep. What sets your speed is how many run live at once. Each live search is re-checked on a cycle, and the only reason more-live means slower is the per-proxy pacing that keeps every IP unbanned. Run fewer live and they refresh faster. Add proxies to run more live at full speed. Park the rest in your Archive, which is unlimited. The live count and its refresh time show in the dashboard, so the upgrade sells itself.

full refresh = ceil( live searches ÷ proxies ) × 45s 45s per step holds every IP at about 80 requests per hour, comfortably under Facebook's ~120/hr limit, no matter how many run live.

More live, same 5 proxies

Live searchesFull refreshPer IP
545 sec80/hr
152.25 min80/hr
304.5 min80/hr
507.5 min80/hr
10015 min80/hr

Per-IP rate never moves. More live only lengthens the cycle, it never makes any IP hotter, so there is no ban risk and no reason to cap.

Same 30 live, more proxies

ProxiesFull refreshPrice
5 (Standard)~4.5 minincluded
10 (+ Turbo)~2.25 min+$20/mo
15 (+ Max)~1.5 min+$35/mo

Proxies buy concurrency and speed. Each pack of 5 lets you run more live at full speed, or refresh the same set faster. They are a provision against bans, not an artificial limit.

Archive is unlimited. Keep a billion searches if you want. They cost nothing to store (each is a tiny config row). Swap any of them into your live set when you want them running, swap them back out when you do not. The live set is what the proxies are pacing; the archive just sits there for free.
Needs Phase 2. All of this depends on the proxy-pool rotation that today only the cars scanner has. The per-marketplace snipers currently use a single proxy, so without Phase 2 they would rate-limit at a handful of live searches. See Build.
Lifecycle

Billing keeps the proxies fresh

Each billing cycle does double duty: it confirms the customer paid, and it rotates their proxies so accounts stay ahead of detection.

Payment succeeds

The renewal webhook fires a proxy rotation: swap the customer's 5 IPs for fresh ones (Oxylabs Replace IPs), auto-vet them, re-replace any that come back flagged, push the new creds to the worker, restart the sniper. Fresh IPs every month, never a bad one.

Payment fails or cancels

Deprovision cleanly: stop the worker, release the proxies back to the pool, remove the DNS record. No orphaned boxes, no wasted proxies.

Scanners sleep at night

Active window defaults to 12 hours, customer-editable, supports split blocks (for example 7 to 9am and 5 to 11pm), stored in their local timezone. Sleep gaps look human and lower ban exposure. The dashboard stays up regardless.

Why rotate on renewal: a residential IP that scrapes the same site for months slowly builds a footprint. Swapping monthly keeps each customer ahead of that, and tying it to a successful payment means you only ever spend proxy rotations on paying customers. Auto-vetting after the swap means they never land on a flagged IP.