Apify Cost Tuning
Overview
Apify charges on three axes: compute units (CU), proxy traffic (GB), and storage.
One CU = 1 GB of memory running for 1 hour, so cost scales with both memory
allocation and run duration. This skill walks the investigate → tune → guard loop
that finds where spend is going, cuts it at the biggest lever (memory), and installs
guardrails so it stays down.
Full pricing tables (plan CU prices, proxy rates, storage rules) live in
pricing-model.md.
Prerequisites
- An Apify account with API access and
APIFY_TOKEN set in the environment.
- The
apify-client package installed (npm install apify-client).
- At least one Actor with run history to analyze.
Instructions
The workflow is six steps. Each is summarized here with its core lever; the full,
runnable code for every step is in
implementation.md.
Analyze current costs — roll up the last N days of runs into total CU, USD, and
duration, and surface the single most expensive run:
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const { items: runs } = await client.actor(actorId).runs().list({ limit: 1000, desc: true });
const totalUsd = runs.reduce((s, r) => s + (r.usageTotalUsd ?? 0), 0);
Reduce memory allocation (biggest lever) — sweep memory from 4096 MB down to
256 MB and stop at the first failure to find the sweet spot. Most CheerioCrawler
Actors are over-provisioned. Sweet spots: simple Cheerio 256-512 MB, complex
512-1024 MB, Playwright 2048-4096 MB.
Optimize crawl duration — higher maxConcurrency, tighter
requestHandlerTimeoutSecs, a maxRequestsPerCrawl cap, fewer retries, and
selective enqueueLinks. Faster crawls consume fewer CUs.
Minimize proxy costs — prefer datacenter (free with plan), only reach for
residential when a site blocks it, block images/fonts/CSS to save residential GB,
and reuse proxy sessions with useSessionPool.
Cost guard for runaway Actors — start the run, poll usageTotalUsd every 30s,
and .abort() once spend crosses a hard cap.
Monitor monthly usage — iterate every Actor's runs since the 1st of the month
and print a cost-descending report so the top spenders are obvious.
See full walkthrough for the complete code of each
step, including the memory sweep, proxy hooks, budget guard, and monthly report.
Output
Running this skill produces:
- A per-Actor cost analysis (runs, total CU, total USD, avg CU/run, avg cost/run,
most expensive run) for a chosen lookback window.
- A memory profile table mapping memory settings to status, duration, CU, and USD
so you can pick the cheapest allocation that still succeeds.
- A monthly cost report ranking every Actor by spend, with a grand total.
- Tuned Actor configuration (reduced memory, capped crawls, proxy resource blocking)
and an optional budget guard that aborts runs exceeding a USD ceiling.
Cost Optimization Checklist
Error Handling
| Issue |
Cause |
Solution |
| Unexpected cost spike |
No maxRequestsPerCrawl |
Always set an upper bound |
| High residential proxy cost |
Scraping images/fonts |
Block non-essential resources |
| Over-provisioned memory |
Default 1024MB |
Profile and reduce to minimum |
| Too many scheduled runs |
Aggressive cron |
Reduce frequency if data freshness allows |
Examples
Three worked scenarios chain the steps against concrete symptoms — a CheerioCrawler
bill that tripled, runaway residential-proxy GB, and guarding a brand-new Actor. Each
shows the full investigate → tune → verify loop. See
examples.md.
Quick guard example — abort any run that exceeds $0.50:
// runWithBudget polls usageTotalUsd every 30s and aborts past the cap
const run = await runWithBudget('user/scraper', input, 0.50);
Resources
Next Steps
For architecture patterns, see apify-reference-architecture.
1---2name: apify-cost-tuning3description: Optimize Apify platform costs through memory tuning, compute unit management, and proxy budgeting. Use when analyzing Apify billing, reducing Actor run costs, or implementing usage monitoring and budget alerts. Trigger with "apify cost", "apify billing", "reduce apify costs", "apify pricing", "apify expensive", "apify budget", "compute units".4license: MIT5---6# Apify Cost Tuning
7
8## Overview
9
10Apify charges on three axes: compute units (CU), proxy traffic (GB), and storage.
11One CU = 1 GB of memory running for 1 hour, so cost scales with both memory
12allocation and run duration. This skill walks the investigate → tune → guard loop
13that finds where spend is going, cuts it at the biggest lever (memory), and installs
14guardrails so it stays down.
15
16Full pricing tables (plan CU prices, proxy rates, storage rules) live in
17[pricing-model.md](references/pricing-model.md).
18
19## Prerequisites
20
21- An Apify account with API access and `APIFY_TOKEN` set in the environment.
22- The `apify-client` package installed (`npm install apify-client`).
23- At least one Actor with run history to analyze.
24
25## Instructions
26
27The workflow is six steps. Each is summarized here with its core lever; the full,
28runnable code for every step is in
29[implementation.md](references/implementation.md).
30
311. **Analyze current costs** — roll up the last N days of runs into total CU, USD, and
32 duration, and surface the single most expensive run:
33
34 ```typescript
35 import { ApifyClient } from 'apify-client';
36 const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
37
38 const { items: runs } = await client.actor(actorId).runs().list({ limit: 1000, desc: true });
39 const totalUsd = runs.reduce((s, r) => s + (r.usageTotalUsd ?? 0), 0);
40 ```
41
422. **Reduce memory allocation** (biggest lever) — sweep memory from 4096 MB down to
43 256 MB and stop at the first failure to find the sweet spot. Most CheerioCrawler
44 Actors are over-provisioned. Sweet spots: simple Cheerio 256-512 MB, complex
45 512-1024 MB, Playwright 2048-4096 MB.
46
473. **Optimize crawl duration** — higher `maxConcurrency`, tighter
48 `requestHandlerTimeoutSecs`, a `maxRequestsPerCrawl` cap, fewer retries, and
49 selective `enqueueLinks`. Faster crawls consume fewer CUs.
50
514. **Minimize proxy costs** — prefer datacenter (free with plan), only reach for
52 residential when a site blocks it, block images/fonts/CSS to save residential GB,
53 and reuse proxy sessions with `useSessionPool`.
54
555. **Cost guard for runaway Actors** — start the run, poll `usageTotalUsd` every 30s,
56 and `.abort()` once spend crosses a hard cap.
57
586. **Monitor monthly usage** — iterate every Actor's runs since the 1st of the month
59 and print a cost-descending report so the top spenders are obvious.
60
61See [full walkthrough](references/implementation.md) for the complete code of each
62step, including the memory sweep, proxy hooks, budget guard, and monthly report.
63
64## Output
65
66Running this skill produces:
67
68- A **per-Actor cost analysis** (runs, total CU, total USD, avg CU/run, avg cost/run,
69 most expensive run) for a chosen lookback window.
70- A **memory profile** table mapping memory settings to status, duration, CU, and USD
71 so you can pick the cheapest allocation that still succeeds.
72- A **monthly cost report** ranking every Actor by spend, with a grand total.
73- Tuned Actor configuration (reduced memory, capped crawls, proxy resource blocking)
74 and an optional budget guard that aborts runs exceeding a USD ceiling.
75
76## Cost Optimization Checklist
77
78- [ ] Memory profiled (start low: 256-512MB for Cheerio)
79- [ ] `maxRequestsPerCrawl` set to prevent runaway crawls
80- [ ] Datacenter proxy used when possible (free with plan)
81- [ ] Residential proxy: images/CSS/fonts blocked to save bandwidth
82- [ ] `maxConcurrency` tuned (higher = faster = fewer CUs)
83- [ ] Scheduled runs have appropriate frequency (don't over-scrape)
84- [ ] Cost guard implemented for expensive runs
85- [ ] Monthly usage reviewed
86
87## Error Handling
88
89| Issue | Cause | Solution |
90|-------|-------|----------|
91| Unexpected cost spike | No `maxRequestsPerCrawl` | Always set an upper bound |
92| High residential proxy cost | Scraping images/fonts | Block non-essential resources |
93| Over-provisioned memory | Default 1024MB | Profile and reduce to minimum |
94| Too many scheduled runs | Aggressive cron | Reduce frequency if data freshness allows |
95
96## Examples
97
98Three worked scenarios chain the steps against concrete symptoms — a CheerioCrawler
99bill that tripled, runaway residential-proxy GB, and guarding a brand-new Actor. Each
100shows the full investigate → tune → verify loop. See
101[examples.md](references/examples.md).
102
103Quick guard example — abort any run that exceeds $0.50:
104
105```typescript
106// runWithBudget polls usageTotalUsd every 30s and aborts past the cap
107const run = await runWithBudget('user/scraper', input, 0.50);
108```
109
110## Resources
111
112- [Apify Pricing](https://apify.com/pricing)
113- [Usage & Resources](https://docs.apify.com/platform/actors/running/usage-and-resources)
114- [Compute Unit Calculator](https://help.apify.com/en/articles/3490384-what-is-a-compute-unit)
115- [pricing-model.md](references/pricing-model.md) — full pricing tables (local)
116- [implementation.md](references/implementation.md) — complete step-by-step code (local)
117- [examples.md](references/examples.md) — worked cost-tuning scenarios (local)
118
119## Next Steps
120
121For architecture patterns, see `apify-reference-architecture`.