Skip to content

feat: pay-per-event pricing - #148

Draft
nikitachapovskii-dev wants to merge 3 commits into
masterfrom
feat/pay-per-event-pricing
Draft

feat: pay-per-event pricing#148
nikitachapovskii-dev wants to merge 3 commits into
masterfrom
feat/pay-per-event-pricing

Conversation

@nikitachapovskii-dev

@nikitachapovskii-dev nikitachapovskii-dev commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Moves RAG Web Browser to pay-per-event pricing with three events: actor-start (Normal mode only, once per run), search (once per query, both modes) and fetch (once per extracted page, both modes).

Charging moves into src/charging.ts, driven by per-mini-actor chargeEvents. In Standby the charge is attributed to the caller through x-actor-request-id and is always awaited before the response is sent, since the request ID is only valid while its request is in flight.

URL to Markdown's charging is deliberately left as it behaves today: same events, same moment of charging, same skip when a Standby request carries no request ID. The one place the two Actors differ is that no-request-ID branch: for single-tenant Standby the run belongs to the caller, so charging its owner is still correct, while for multi-tenant it would bill us. standbyTenancy in src/mini-actors.ts keeps them apart.

Also hides the serpProxyGroup input from the UI. its enum had to go, because a string field carrying an enum may only use editor: "select" and rewrites the README pricing section, which still claimed the Actor was free of charge.

Verified with local runs under ACTOR_TEST_PAY_PER_EVENT: a normal run charges actor-start + fetch, a search run adds search, and a run on the current compute-unit pricing charges nothing at all.

Needs Console setup. The platform's automatic apify-actor-start event must be set to $0, otherwise it duplicates Actor Start.

Closes #146

@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Comment @coderabbitai help to get the list of available commands.

@nikitachapovskii-dev

nikitachapovskii-dev commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

Worth discussion:

  1. Fetch is charged even when we return nothing useful. A media file (which we never download) and a page with an unparseable content type are both billed as a full fetch, while the customer gets status FAILED and empty text. Only hard load failures are free. I kept this because the charging code is shared with URL2M and I didn't want to change its live revenue. But for RAG's agent traffic, PDFs and image URLs are common, so it may be worth changing for both.

  2. Search is charged even when the search fails. It's billed when the query is submitted, not when Google answers, so one user query is paid for exactly once regardless of retries and result pages (a single query can span up to 11 Google pages). The downside: during a SERP proxy outage every query is billed and returns an error. Charging only on a successful SERP is possible but risks double-charging.

  3. Added custom event actor-start to replace apify-actor-start
    No decision needed, just so it's on the record. The built-in one isn't charged on Standby runs at all (confirmed with the platform team) So Console needs our actor-start, with apify-actor-start removed: the docs say not to have both.

@nikitachapovskii-dev nikitachapovskii-dev self-assigned this Sep 3, 2026
@nicklamonov

Copy link
Copy Markdown
Collaborator
  1. Let's charge them as is for now. PDF URLs are 0.69% of fetches, image urls are 0.1% at the moment. So at some later time we can skip billing for them, but now let's keep charging for them even if requests fail.
  2. Why can't we charge on successful SERP and why is there a risk of double-charging?
  3. No, we don't need a custom event for actor start. We need to use native platform one. In pricing we already took into account that it won't be charged in Standby calls.

@nikitachapovskii-dev

Copy link
Copy Markdown
Collaborator Author

Why can't we charge on successful SERP and why is there a risk of double-charging?

Charging too early inside the handler may go to retries. Charging at the end means it races the response in Standby so we can loose event.
But now that I think of it I can use the flag to avoid triggering on retries, if charging after successful attempts is preferred I can implement this, no problem👍

@nicklamonov

Copy link
Copy Markdown
Collaborator

Yeah, I would prefer charging for search only when we actually got successful SERP response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate pricing model from PPU to Pay-Per-Event (PPE)

3 participants