Choosing an Effort Level
Every extract and generate request accepts an optional effort parameter that controls the tradeoff between speed and capability.
Every /extract and /generate request accepts an optional effort parameter. It controls the tradeoff between speed and capability; specifically, how hard Tabstack works to render and process the target page before extracting data.
The three levels
Section titled “The three levels”| Level | Page fetch | What it does |
|---|---|---|
min | 1-5s | Fetches raw HTML. No JavaScript execution. Use for static, server-rendered pages. |
standard | 3-15s | Fetches with enhanced reliability and light JS handling. Default for all requests. |
max | 15-60s | Full headless browser rendering. Executes JavaScript, waits for dynamic content to load. |
Default is standard when the parameter is omitted.
Effort is not your whole response time
Section titled “Effort is not your whole response time”The times above cover fetching and rendering the page. They do not cover extracting your data out of it, and for /extract/json and /generate/json that second step usually dominates. Total response time is roughly page fetch plus extraction, and extraction scales with how much you ask for.
Measured on the same page at the same standard effort, varying only the schema:
| Schema | Observed total |
|---|---|
| 2 flat string/number fields | 2-6s |
| 4 fields across an array of ~30 items | 18-120s |
Same URL, same effort level, same day. The only variable was the number of values requested.
What that means for you: if you are extracting a handful of fields, effort is a good predictor of latency and the table above holds. If you are extracting an array (every product on a listing page, every story on a feed, every row of a table), expect to run well past 30 seconds regardless of effort, and expect a long tail. Do not size a timeout, a serverless function, or a retry budget off the fetch column alone.
To keep array extractions faster, narrow what you ask for: fewer properties per item, and a description on the array that bounds it (for example, “the first 10 stories” rather than “all stories”). See Schema Design.
/extract/markdown is not affected. It has no schema, so it stays inside the fetch times above.
For deployment implications, see Serverless and edge functions.
When to use each level
Section titled “When to use each level”min: Fastest, static pages only
Section titled “min: Fastest, static pages only”Use when:
- The page is server-rendered HTML (blogs, news sites, documentation)
- Speed matters and the content doesn’t require JavaScript to appear
- You’re running high-volume extractions and want lowest latency
Don’t use when:
- The page uses a JavaScript framework (React, Vue, Next.js, Angular)
- Content is loaded asynchronously after the initial HTML response
- You see empty fields or missing data with
standard
const result = await client.extract.json({ url: 'https://news.ycombinator.com', // Static HTML, min works fine effort: 'min', json_schema: { /* ... */ }})result = client.extract.json( url="https://news.ycombinator.com", # Static HTML, min works fine effort="min", json_schema={...},)tabstack extract json https://news.ycombinator.com \ --schema @schema.json \ --effort mincurl -X POST https://api.tabstack.ai/v1/extract/json \ -H "Authorization: Bearer $TABSTACK_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://news.ycombinator.com", "effort": "min", "json_schema": { "type": "object" } }'standard: The default, works for most pages
Section titled “standard: The default, works for most pages”Use when:
- You’re not sure what the page renders like
- You want reliable results without committing to full browser rendering time
- The page may have some JavaScript but its primary content is in the initial HTML
This is the right starting point. If results feel incomplete, move to max.
const result = await client.extract.json({ url: 'https://example.com/products', // effort: 'standard' is the default, can be omitted json_schema: { /* ... */ }})result = client.extract.json( url="https://example.com/products", # effort="standard" is the default, can be omitted json_schema={...},)# effort defaults to standard, can be omittedtabstack extract json https://example.com/products \ --schema @schema.jsoncurl -X POST https://api.tabstack.ai/v1/extract/json \ -H "Authorization: Bearer $TABSTACK_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/products", "json_schema": { "type": "object" } }'max: Full rendering, JS-heavy sites
Section titled “max: Full rendering, JS-heavy sites”Use when:
- The page is a Single Page Application (React, Vue, Angular, Next.js client-side)
- Content loads lazily or after user interaction
- Pricing tables, product listings, or data grids are rendered by JavaScript
- You’re getting empty fields with
standard - The page is behind a login with JS-rendered content after auth
const result = await client.extract.json({ url: 'https://app.example.com/dashboard', effort: 'max', // Wait for JS to fully render json_schema: { /* ... */ }})result = client.extract.json( url="https://app.example.com/dashboard", effort="max", # Wait for JS to fully render json_schema={...},)tabstack extract json https://app.example.com/dashboard \ --schema @schema.json \ --effort maxcurl -X POST https://api.tabstack.ai/v1/extract/json \ -H "Authorization: Bearer $TABSTACK_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://app.example.com/dashboard", "effort": "max", "json_schema": { "type": "object" } }'Decision flow
Section titled “Decision flow”Is the page server-rendered HTML with no JavaScript? └─ Yes → try 'min' └─ No or unsure → use 'standard' (default)
Are you getting empty fields or incomplete data? └─ Yes → upgrade to 'max'
Is the page a React/Vue/Angular SPA or loads content dynamically? └─ Yes → use 'max' from the startCost and timeout notes
Section titled “Cost and timeout notes”max uses full headless browser rendering. It consumes more compute than min or standard. If your target page consistently needs max, factor this into your per-request cost expectations.
Default request timeout is 60 seconds. max requests on complex SPAs can approach this limit on very slow pages. If you’re hitting timeouts, consider whether the page can be targeted more specifically with a starting URL or nocache.