Web scraper hosting, with somewhere to put what it collects
A scraper is a loop plus storage. Deploy the repository, pick your interval, and it runs in its own sandbox writing to a file under /data or to a managed database on your private network. Nothing to keep awake and nothing to pay per run.
The light kind, which fits the free plan
requests with BeautifulSoup, httpx, Scrapy, or cheerio on Node.js: a scraper that fetches HTML and parses it runs in a few tens of megabytes and sits comfortably in the free 256 MB. Outbound HTTP and HTTPS are on the free plan's fixed list, so a scraper can reach the sites it is pointed at without a paid plan.
The headless browser kind, which does not
Playwright and Puppeteer drive a real browser, and a browser is not a 256 MB program: Chromium alone wants more than the free plan has, before your pages. Those scrapers belong on a paid app with 1 GB, and up to 3 GB more at $1 a gigabyte. A Dockerfile is also the reliable way to get a browser and its system libraries in place, and Dockerfile builds come with the paid plans.
Where the results go
Files under /data survive redeploys, so a SQLite file, a JSONL log or a CSV is the simplest answer and needs nothing else. When the data outgrows a file, or something else needs to read it, a managed MySQL, PostgreSQL, MongoDB or Redis is one click away and answers on your private network only. The first database on a verified account is free.
The limits worth knowing before you build it
- 1 GB of traffic a day on the free plan, in and out together. Pages of HTML do not come close; images, PDFs and video do. Paid apps have no traffic limit.
- Outbound follows a fixed list on the free plan: DNS, HTTP, HTTPS and the database ports. A scraper that needs some other port needs a paid plan.
- Proxies and tunnels are not allowed, on any plan. Scraping through your own upstream proxy service is a normal outbound call; turning the app into a proxy for other people is not. The rules are in the terms.
Being the kind of scraper that stays welcome
Identify the scraper in its user agent, keep an interval the site can live with, cache what you already have and read the site's own terms before you point anything at it. A scraper that gets blocked is usually one that asked too often. Breaking the rules of the site you are scraping is on the person running the scraper, and our terms cover apps that do it.
Frequently asked questions
Does Playwright or Puppeteer work on the free plan?
No. A headless browser needs more than 256 MB in practice, so those scrapers want a paid app at $2 a month with 1 GB, and a Dockerfile build if the browser needs system libraries.
How do I run it every hour?
Either sleep in your own loop, or use the panel's scheduled commands to run the scraper inside the app on an interval. There is no per-run charge either way.
Where should the data go?
A file under /data for anything small, because /data survives redeploys. A managed database when it grows or when another app needs to read it; the first one on the account is free.
Is there a traffic limit?
A free app may move 1 GB a day, counted in and out together, and the Plan and usage tab shows where the day stands. Past the limit the app stops and starts are blocked for 24 hours. Paid apps have no traffic limit.
Does a free app sleep?
The process does not. Only a web address sleeps on the free plan, when nobody has opened it for a while, and a worker or a script has no address to sleep. A free app is asked every few days whether it is still in use, and one click in that mail keeps it running. Paid apps are never asked.
What happens on a deploy?
The repository is cloned at your branch, dependencies install, the build runs when there is one, the app starts. With auto-deploy on, every push does the same. The live console shows each step; a failed one is explained in plain words.