Skip to content

docs(webhooks): pricing and per-plan webhook limits - #5051

Open
jackbridger wants to merge 1 commit into
mainfrom
docs/webhooks-pricing
Open

jackbridger wants to merge 1 commit into
mainfrom
docs/webhooks-pricing

Conversation

@jackbridger

Copy link
Copy Markdown
Collaborator

Adds webhooks pricing and per-plan limits to the docs ahead of the webhooks launch on Mon Oct 26 (TRI-14179).

Pricing

Webhooks have no separate charge. The runs a delivery starts or resumes are billed as normal compute (Eric in #project-webhooks, Oct 20). Filtered deliveries start no run, and waiting runs are suspended, so neither uses compute.

Changes

  • docs/limits.mdx: new sections for webhook waiters, processing concurrency, delivery retention and subscribers per endpoint (values from enterprise/apps/billing/app/plans/v3.server.ts and MAX_WEBHOOK_SUBSCRIBERS_PER_ENDPOINT). The existing ingest-rate tables and the #webhook-ingest-rate-limits anchor are unchanged.
  • docs/webhooks/overview.mdx: new "Pricing and limits" section.
  • docs/webhooks/deliveries.mdx: new "Retention" section.
  • docs/webhooks/waiters.mdx: links the plan-dependent limits to the new table.
  • docs/how-to-reduce-your-spend.mdx: new tip, "Filter webhooks before they start runs".
  • trigger-cost-savings skill: one bullet on webhook filters, plus a patch changeset for @trigger.dev/sdk.

mint broken-links passes.

To confirm before merging

  • "No separate charge" holds after the beta too, not only during it.
  • The per-plan webhook limits are live on prod (the webhook-limits-backfill has run).

Webhooks have no separate charge: the runs a delivery starts are billed
as normal compute, and filtered deliveries start no run. Adds the plan
limits for webhook waiters, processing concurrency, delivery retention
and subscribers per endpoint to the limits page, links them from the
webhooks pages, and adds a webhook filter tip to the spend guide and the
bundled cost-savings skill.
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The changes add webhook pricing and filtering guidance, including that unmatched deliveries start no run and incur no separate webhook charge. They also document plan-based limits for waiters, processing concurrency, delivery retention, and subscribers. Related documentation now links to the webhook limits and delivery-retention information.

Priority: ⬇️ Low

Merge Risk: 🔵 Low · up to 451d7

The pages could understate the cost of runs started by webhooks, overstate how long deliveries can be recovered after a plan upgrade, and leave Enterprise users and self-hosters with incomplete limit information. None of this affects runtime behavior. Tighten the wording and confirm the live plan limits before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Description check Warning The description clearly explains the pricing model, documents the changed files, and reports the broken-link test. It does not include the required issue reference, checklist, Testing heading, Changel… Add the required template sections and information: issue reference, completed checklist, Testing section with test steps, Changelog section, and Screenshots section or an explicit statement that screenshots are not applicable. Resolve or e…
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly summarizes the main documentation changes for webhook pricing and per-plan limits.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (7 skipped: 7 unsupported.)

Full details: Description check

Explanation

The description clearly explains the pricing model, documents the changed files, and reports the broken-link test. It does not include the required issue reference, checklist, Testing heading, Changelog section, or Screenshots section. It also identifies two unresolved items before merge.

Resolution

Add the required template sections and information: issue reference, completed checklist, Testing section with test steps, Changelog section, and Screenshots section or an explicit statement that screenshots are not applicable. Resolve or explicitly document the beta pricing and production-limit confirmations before merging.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Devin Review


## Filter webhooks before they start runs

Give each [webhook](/webhooks/overview) subscriber a [filter](/webhooks/filters) so it only runs for the events it handles. A delivery that no filter matches is recorded as `FILTERED` and starts no run, so you aren't charged compute for it. Receiving webhooks has no separate charge.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Filtered subscribers do not prevent waiter compute

When subscriber filters reject an event but a waiter matches, FILTERED is not its status and the waiting run resumes. That run consumes compute despite the cost-saving promise.

Learn more

Webhook waiters subscribe to an endpoint independently of task, agent, and channel subscribers. A matching waiter resumes its existing run even when all subscriber filters reject the event. The delivery then succeeds rather than settling as FILTERED in #finishDelivery. Resuming the run incurs compute, so the same unconditional claim in the pricing overview and bundled cost skill also needs qualification.

Example: A Stripe endpoint has a task filtered to charge.refunded and a waiter matching payment_intent.succeeded. A payment event rejects the task filter but resumes the waiter, so the delivery is not FILTERED and the resumed task can incur compute.

Recommended fix: Qualify the zero-compute claim on there being no matching waiter as well as no matching subscriber; update the cost guide, pricing overview, and bundled skill together.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread docs/limits.mdx
| Pro | 30 days |
| Enterprise | 90, 180 or 365 days |

Deliveries are stored for at least 30 days, so upgrading your plan shows older deliveries right away.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Strict retention removes upgrade history

With deliveryRetentionStrict enabled, Free deliveries use a three-day storage class rather than the promised 30 days. Upgrading after those deliveries expire cannot restore them.

Learn more

The visible retention limit and physical storage duration are separate settings. resolveWebhookLimits selects the visible retention class for storage when deliveryRetentionStrict is true, instead of enforcing the default 30-day minimum. The back-office retention option allows this override, and the partition maintenance deletes expired classes. Thus an upgrade can only reveal history still physically stored.

Example: An organization with three-day visible retention and strict retention receives a delivery on Monday. Its delivery enters the three-day class; an upgrade several weeks later cannot reveal it.

Recommended fix: Qualify the 30-day storage and upgrade promise with the condition that strict retention is not enabled, or describe the strict-retention exception explicitly.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7


ℹ️ Review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 735eb1fe-95d4-45b6-9a5e-bc1f29b5101a
📥 Commits

Reviewing files that changed from the base of the PR and between d9bf563 and 451d78c.

📒 Files selected for processing: 7
  • .changeset/cost-skill-webhook-filters.md
  • docs/how-to-reduce-your-spend.mdx
  • docs/limits.mdx
  • docs/webhooks/deliveries.mdx
  • docs/webhooks/overview.mdx
  • docs/webhooks/waiters.mdx
  • packages/trigger-sdk/skills/trigger-cost-savings/SKILL.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📜 Review details
⏰ Context from checks skipped due to timeout: 12
  • GitHub Check: sdk-compat / Node.js 20.20 (warp-ubuntu-latest-x64-4x)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (2, 6)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (6, 6)
  • GitHub Check: sdk-compat / Node.js 26.12.1 (warp-ubuntu-latest-x64-4x)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (3, 6)
  • GitHub Check: webapp / 🧪 Unit Tests: Webapp (1, 6)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (1)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (2, 3)
  • GitHub Check: internal / 🧪 Unit Tests: Internal (2)
  • GitHub Check: e2e-webapp / 🧪 E2E Tests: Webapp (1, 1)
  • GitHub Check: packages / 🧪 Unit Tests: Packages (3, 3)
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📚 Code guidelines: 4
packages/trigger-sdk/AGENTS.md — auto-discovered
.claude/rules/sdk-packages.md — auto-discovered
.claude/rules/docs-writing.md — auto-discovered
docs/AGENTS.md — auto-discovered
📓 Path-based instructions: 4
Source excerpt: Always import from `@trigger.dev/sdk`.

📄 CodeRabbit inference engine (packages/trigger-sdk/AGENTS.md)

Files:

  • packages/trigger-sdk/skills/trigger-cost-savings/SKILL.md
Source excerpt: Changes to `packages/` are **customer-facing**.

📄 CodeRabbit inference engine (.claude/rules/sdk-packages.md)

Files:

  • packages/trigger-sdk/skills/trigger-cost-savings/SKILL.md
Source excerpt: Use Mintlify MDX format.

📄 CodeRabbit inference engine (.claude/rules/docs-writing.md)

Files:

  • docs/webhooks/deliveries.mdx
  • docs/webhooks/waiters.mdx
  • docs/how-to-reduce-your-spend.mdx
  • docs/limits.mdx
  • docs/webhooks/overview.mdx
Applicability reference: AGENTS.md: # AGENTS.md Docs live in `docs/` as a Mintlify site (MDX format).

📄 CodeRabbit inference engine (docs/AGENTS.md)

Files:

  • docs/webhooks/deliveries.mdx
  • docs/webhooks/waiters.mdx
  • docs/how-to-reduce-your-spend.mdx
  • docs/limits.mdx
  • docs/webhooks/overview.mdx
🪛 SkillSpector (2.12.0)
packages/trigger-sdk/skills/trigger-cost-savings/SKILL.md

[warning] 43: [RP1] MCP server referenced without pinned version: 'npx trigger.dev'.: npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Remediation: Pin the version: npx @scope/server@1.2.3

(MCP Rug Pull (RP1))

🔇 Additional comments: 2
docs/webhooks/overview.mdx: 1

92-92: 🗄️ Data Integrity & Integration

Confirm the webhook-limit rollout before publishing these values.

The page presents the plan limits as active behavior. The implementation resolves limits from organization configuration over environment defaults, but the available source does not show which production organizations have these values or whether webhook-limits-backfill has run. Confirm the deployed configuration and backfill state. Otherwise, label the limits as planned or beta.

docs/limits.mdx: 1

185-190: 🗄️ Data Integrity & Integration

The active Cloud values and webhook-limits-backfill status cannot be determined from the repository. The resolver reads environment defaults and organization overrides, but no deployed Cloud configuration or backfill record is present. The publication concern therefore remains undecidable from the available evidence.

"@trigger.dev/sdk": patch
---

The bundled `trigger-cost-savings` skill now notes that a webhook delivery no subscriber's filter matches starts no run and costs no compute.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the changeset sentence.

The phrase a webhook delivery no subscriber's filter matches starts no run is not grammatical. Use a webhook delivery starts no run when no subscriber's filter matches.

Comment thread docs/limits.mdx

## Webhook processing concurrency

This limit controls how many webhook deliveries and waiter resumes are processed at once per environment. More wait their turn. It is not a limit on the runs those deliveries start, which use your normal [concurrency limits](#concurrency-limits).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Clarify the processing-concurrency sentence.

Replace “More wait their turn.” with “Additional deliveries wait their turn.” The current sentence is not grammatical and does not identify what waits.

Comment thread docs/limits.mdx
Comment on lines +198 to +202
| Pricing tier | Limit |
| :----------- | :----------------------- |
| Free | 5 concurrent deliveries |
| Hobby | 10 concurrent deliveries |
| Pro | 50 concurrent deliveries |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Document the Enterprise processing limit.

Add an Enterprise row or state that Enterprise uses a separate organization-level setting. The other webhook limit tables document Enterprise explicitly, and the webhook limits configuration supports an optional concurrency override.

Comment thread docs/limits.mdx
| Pro | 30 days |
| Enterprise | 90, 180 or 365 days |

Deliveries are stored for at least 30 days, so upgrading your plan shows older deliveries right away.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

set -o pipefail
printf '%s\n' '--- changed docs hunk ---'
git diff --no-ext-diff --unified=25 d9bf563ae3badd0620a88b85c6784c5a8a5c1b6d 451d78c9b54eda489cf9ba278f05ec68544bfcbf -- docs/limits.mdx

printf '%s\n' '--- retention identifier references ---'
rg -n -F --glob '!node_modules' --glob '!dist' --glob '!build' -e 'deliveryRetentionDays' -e 'deliveryStorageDays' -e 'deliveryRetentionStrict' -e 'Deliveries are stored for at least 30 days' .

printf '%s\n' '--- relevant file candidates ---'
rg --files | rg '(^|/)(limits|retention|delivery|webhook|cloud|plan|configuration|config)([^/]*)\.(ts|tsx|js|jsx|json|md|mdx|yaml|yml)$' | head -200

Repository: triggerdotdev/trigger.dev

Length of output: 13606


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- changed docs hunk ---'
git diff --no-ext-diff --unified=25 d9bf563ae3badd0620a88b85c6784c5a8a5c1b6d 451d78c9b54eda489cf9ba278f05ec68544bfcbf -- docs/limits.mdx
printf '%s\n' '--- retention identifier references ---'
rg -n -F --glob '!node_modules' --glob '!dist' --glob '!build' -e 'deliveryRetentionDays' -e 'deliveryStorageDays' -e 'deliveryRetentionStrict' -e 'Deliveries are stored for at least 30 days' .

Repository: triggerdotdev/trigger.dev

Length of output: 9882


🏁 Script executed:

set -o pipefail
git diff --no-ext-diff --unified=25 d9bf563ae3badd0620a88b85c6784c5a8a5c1b6d 451d78c9b54eda489cf9ba278f05ec68544bfcbf -- docs/limits.mdx
rg -n -F --glob '!node_modules' --glob '!dist' --glob '!build' -e 'deliveryRetentionDays' -e 'deliveryStorageDays' -e 'deliveryRetentionStrict' -e 'Deliveries are stored for at least 30 days' .

Repository: triggerdotdev/trigger.dev

Length of output: 9816


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- resolver ---'
nl -ba apps/webapp/app/v3/webhookLimits.ts | sed -n '1,90p'
printf '%s\n' '--- default loading ---'
nl -ba apps/webapp/app/v3/webhookLimits.server.ts | sed -n '1,95p'
printf '%s\n' '--- webhook engine README contract ---'
nl -ba internal-packages/webhook-engine/README.md | sed -n '35,70p'
printf '%s\n' '--- retention environment/config declarations ---'
rg -n -F --glob '!node_modules' --glob '!dist' --glob '!build' -e 'WEBHOOK_DELIVERY_RETENTION_DAYS' -e 'WEBHOOK_DELIVERY_STORAGE_DAYS' -e 'WEBHOOK_DELIVERY_RETENTION_STRICT' -e 'deliveryRetentionStrict' -e 'deliveryStorageDays' -e 'deliveryRetentionDays' -- .env* apps internal-packages packages deploy infra docs 2>/dev/null || test "$?" -eq 1

Repository: triggerdotdev/trigger.dev

Length of output: 16811


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- environment defaults ---'
nl -ba apps/webapp/app/env.server.ts | sed -n '2112,2135p'
printf '%s\n' '--- admin retention controls ---'
nl -ba apps/webapp/app/components/admin/backOffice/WebhookLimitsSection.tsx | sed -n '135,195p'
nl -ba apps/webapp/app/components/admin/backOffice/WebhookLimitsForm.ts | sed -n '1,70p'
printf '%s\n' '--- webhook limits config persistence/references ---'
rg -n -F --glob '!node_modules' --glob '!dist' --glob '!build' -e 'webhookLimitsConfig' -e 'deliveryRetentionStrict' apps/webapp | head -160

Repository: triggerdotdev/trigger.dev

Length of output: 9546


Qualify the delivery storage claim.

Strict retention changes the storage window. When it is disabled, deliveries remain stored for at least 30 days and an upgrade can reveal older deliveries that remain within their storage class. When it is enabled, new deliveries are stored only for the visible retention period rounded to a retention class, so an upgrade cannot recover deliveries already deleted.

Suggested wording
--- "a/docs/limits.mdx"
+++ "b/docs/limits.mdx"
@@ -212,7 +212,7 @@
 | Pro          | 30 days                      |
 | Enterprise   | 90, 180 or 365 days          |
 
-Deliveries are stored for at least 30 days, so upgrading your plan shows older deliveries right away.
+When strict retention is disabled, deliveries are stored for at least 30 days and hidden after the visible retention, so upgrading can show older deliveries that remain within their storage class. When strict retention is enabled, new deliveries are stored only for the visible retention rounded to a retention class, so upgrading cannot recover deliveries deleted before the upgrade.
 
 ## Webhook subscribers
 
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Deliveries are stored for at least 30 days, so upgrading your plan shows older deliveries right away.
When strict retention is disabled, deliveries are stored for at least 30 days and hidden after the visible retention, so upgrading can show older deliveries that remain within their storage class. When strict retention is enabled, new deliveries are stored only for the visible retention rounded to a retention class, so upgrading cannot recover deliveries deleted before the upgrade.


## Retention

Deliveries stay visible for 3 days on Free, 7 days on Hobby and 30 days on Pro. See [Limits](/limits#webhook-delivery-retention).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Include Enterprise retention.

Add the Enterprise retention values, or explicitly scope this sentence to Free, Hobby, and Pro. The limits page documents 90, 180, or 365 days for Enterprise, so this page currently gives Enterprise users an incomplete answer.

Comment on lines +88 to +90
Webhooks have no separate charge on Trigger.dev Cloud. Receiving, verifying, filtering and recording deliveries is included in every plan. The runs a delivery starts or resumes are billed like any other run, by compute time. See [pricing](https://trigger.dev/pricing).

A delivery that no subscriber's filter matches starts no run, so it uses no compute. A run [waiting](/webhooks/waiters) for a webhook is suspended, so it uses no compute until the webhook arrives.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

set -eu
printf '%s\n' '--- diff ---'
git diff --stat d9bf563ae3badd0620a88b85c6784c5a8a5c1b6d 451d78c9b54eda489cf9ba278f05ec68544bfcbf -- docs/webhooks/overview.mdx docs/webhooks/deliveries.mdx docs/limits.mdx docs/guides/spend.mdx skills/trigger-cost-savings || true
git diff --unified=25 d9bf563ae3badd0620a88b85c6784c5a8a5c1b6d 451d78c9b54eda489cf9ba278f05ec68544bfcbf -- docs/webhooks/overview.mdx docs/webhooks/deliveries.mdx docs/limits.mdx docs/guides/spend.mdx skills/trigger-cost-savings || true
printf '%s\n' '--- relevant repository text ---'
rg -n -i --glob '!node_modules' --glob '!dist' --glob '!build' -e 'webhook.*(bill|charg|compute|filter)' -e '(bill|charg|compute).*webhook' -e 'FILTERED' -e 'webhook-limits-backfill' -e 'webhook.*limit' . || test "$?" -eq 1
printf '%s\n' '--- changed overview context ---'
nl -ba docs/webhooks/overview.mdx | sed -n '70,110p'
printf '%s\n' '--- changed spend/skill references ---'
rg -n -C 5 -i --glob '*.md' --glob '*.mdx' --glob '*.ts' --glob '*.json' --glob '*.yaml' --glob '*.yml' -e 'webhooks have no separate charge' -e 'no separate charge' -e 'filtered deliveries' -e 'webhook.*compute' -e 'webhook.*pricing' . || test "$?" -eq 1

Repository: triggerdotdev/trigger.dev

Length of output: 45664


🏁 Script executed:

set -eu
printf '%s\n' '--- webhook billing and ingress references ---'
rg -n -i --glob 'apps/**' --glob 'internal-packages/**' --glob 'packages/**' --glob 'docs/**' --glob '!**/node_modules/**' -e 'chargeWebhook' -e 'webhook.*billing' -e 'billing.*webhook' -e 'webhook.*price' -e 'price.*webhook' -e 'compute.*charge' -e 'charge.*compute' -e 'Webhook.*Billing' .
printf '%s\n' '--- ingress limiter implementation ---'
nl -ba apps/webapp/app/services/webhookIngressRateLimit.server.ts | sed -n '1,240p'
printf '%s\n' '--- webhook engine billing-adjacent declarations ---'
nl -ba internal-packages/webhook-engine/src/engine/index.ts | sed -n '230,330p'
nl -ba internal-packages/webhook-engine/src/engine/index.ts | sed -n '520,620p'
printf '%s\n' '--- local pricing references ---'
rg -n -i --glob 'docs/**' --glob 'apps/**' --glob 'internal-packages/**' --glob 'packages/**' -e 'pricing' -e 'included in every plan' -e 'no separate' -e 'billed like any other run' .
printf '%s\n' '--- exact changed files ---'
git diff --name-status d9bf563ae3badd0620a88b85c6784c5a8a5c1b6d 451d78c9b54eda489cf9ba278f05ec68544bfcbf

Repository: triggerdotdev/trigger.dev

Length of output: 41893


🌐 Web query:

site:trigger.dev pricing webhooks no separate charge compute

💡 Result:

<source_evidence>
<source kind="search">
<title>Cloud Pricing | Trigger.dev</title>
<location>https://trigger.dev/pricing</location>
<excerpt>citeturn0search0 [wordlim: 200] Crawled: 2 weeks ago; ## Compute pricing ... Multiply per second machine price by the seconds your run will take. ... Trigger.dev is framework agnostic so it works with most JavaScript frameworks. ... You can use any API either by using their SDK or through web requests using fetch or your preferred alternative.

# Simple pricing, built for growth

Begin for free, invite your team, and scale without limits.

## Free

### $0/month

* * *

[Input]

Get started

  * $5 / month free credits

  * 20 concurrent runs

  * Unlimited tasks

  * 5 team members

  * Dev and Prod environments

  * Preview branches

  * Custom dashboards

  * 10 schedules

  * 1 day log retention

  * 1 day query period

  * Community support

  * 1 alert destination

  * 10 concurrent Realtime connections

## Hobby

### $10/month

* * *

Get started

  * $10 / month credits included

  * 50 concurrent runs

  * Unlimited tasks

  * 5 team members

  * Dev, Preview and Prod environments

  * 5 preview branches

  * 1 custom dashboard

  * 100 schedules

  * 7 day log retention

  * 7 days query period

  * Community support

  * 3 alert destinations

  * 150 concurrent Realtime connections

  * HIPAA BAA add-on

Request a BAA

## Pro

### $50/month

* * *

Get started

  * $50 / month credits included

  * 200+ concurrent runs

Then $10/month per 50

  * Unlimited tasks

  * 25+ team members

Then $20/month per seat

  * Dev, Preview and Prod environments

  * 20+ preview branches

Then $10/month per branch

  * 5+ custom dashboards

Then $10/month per dashboard

  * 1000+ schedules

Then $10/month per 1,000

  * 30 day log retention

  * 30 days query period

  * Dedicated Slack support

  * 100+ alert destinations

  * 1000+ concurrent Realtime connections

Then $10/month per 1,000

  * AWS PrivateLink

  * HIPAA BAA add-on

Request a BAA

## Enterprise

## Custom

* * *

Contact us

  * Custom discounts

  * All Pro plan features +

  * Custom log retention

  * Priority support

  * Role-based access control (RBAC)

  * SOC 2 report

  * Penetration test report

  * Single sign-on (SSO)

  * HIPAA BAA add-on

Request a BAA

## Compute pricing

[Input]

Per sec

Per hour

Machine  | vCPU  | GB RAM  | Cost/sec
--- | --- | --- | ---
Micro  | 0.25  | 0.25  | $0.0000169
Small 1x Default  | 0.5  | 0.5  | $0.0000338
Small 2x  | 1  | 1  | $0.0000675
Medium 1x  | 1  | 2  | $0.0000850
Medium 2x  | 2  | 4  | $0.0001700
Large 1x  | 4  | 8  | $0.0003400
Large 2x  | 8  | 16  | $0.0006800

Tasks are executed on our managed workers. You are only charged when your tasks are executing.

## Run pricing

#### Cost/run invocation

$0.000025

($0.25 per 10,000 runs)

Every run that starts executing on our managed workers is charged an invocation cost in addition to compute costs. Runs in the DEV environment are not charged for.

## Frequently asked questions

### What is a task?

Tasks are functions that can run for a long time and provide strong resilience to failure. They run on our servers so there are no timeouts and no infrastructure to manage. You can read more about how they work in our docs .

### Can I self-host Trigger.dev?

Absolutely. We have a self hosting guide right here .

### How long can a task run for?

Tasks can run for as long as you need, with no timeouts.

### Where are my tasks run?

On our managed infrastructure. Your task code lives in `trigger` folders (commonly `src/trigger`), and the code inside is bundled and deployed together. You can also self-host if you prefer.

### How do I estimate my usage?

Multiply per second machine price by the seconds your run will take. Add the per run invocation cost and multiply by your run count.

A 10s task that does 100 runs per day on the small-1x machine:

1 run = (10s × $0.0000338) + $0.000025 = $0.000363
1 day = 100 × $0.000363 = $0.0363
1 month = $0.0363 × 30 = $1.09

### How does usage work?

We charge for usage in 2 ways: the number of seconds of compute yo…[truncated]</excerpt>
</source>
<source kind="search">
<title>Wait for HTTP callback | Changelog</title>
<location>https://trigger.dev/changelog/wait-for-http-callback</location>
<excerpt>citeturn0search1 [wordlim: 200] Published: 1.2 years ago; Crawled: today; ## Save on compute costs by pausing runs until third-party services complete their work with webhook callbacks. ... You can save money with Trigger.dev cloud when you are doing long requests to 3rd parties that support webhook callbacks.

# Wait for HTTP callback

## Save on compute costs by pausing runs until third-party services complete their work with webhook callbacks.

Matt Aitken

CEO, Trigger.dev

When you create a Waitpoint token we give you a URL back that can be passed to a 3rd party. When they&#39;re done with the work they can make a POST request to that URL and we&#39;ll continue the run with the result.

It&#39;s easier to understand with an example. Here we&#39;re going to get Replicate to generate an image for us in the background.

`

import { task, wait } from &quot;@trigger.dev/sdk&quot;;

const replicate = new Replicate({

auth: process.env.REPLICATE_API_KEY,

});

export const generateImage = task({

id: &quot;generate-image&quot;,

run: async () =&gt; {

// You can create this token from your backend or inside a task

const token = await wait.createToken({

timeout: &quot;10m&quot;,

});

await replicate.predictions.create({

version:

&quot;27b93a2413e7f36cd83da926f3656280b2931564ff050bf9575f1fdf9bcd7478&quot;,

input: {

prompt: &quot;A painting of a cat by Andy Warhol&quot;,

},

// pass the token url to Replicate&#39;s webhook, so they can &quot;callback&quot;

// 👇

webhook: token.url,

webhook_events_filter: [&quot;completed&quot;],

});

const result = await wait.forToken&lt;Prediction&gt;(token).unwrap();

// unwrap() throws a timeout error or returns the result 👆

return result;

},

});

`

When Replicate has finished processing the image it will make an HTTP POST request to the URL we gave it. That will complete the Waitpoint and the JSON body is set as the output of the Waitpoint. The run is continued with the output of the Waitpoint.

On the Cloud product we pause the run when you call `wait.forToken()` (so you stop being charged) and then continue the run when the HTTP callback comes in.
</excerpt>
</source>
<source kind="search">
<title>Trigger.dev vs Inngest | Trigger.dev</title>
<location>https://trigger.dev/vs/inngest</location>
<excerpt>citeturn0search2 [wordlim: 200] Crawled: today; Trigger.dev provides its own compute, so background tasks are decoupled from your web app entirely. ... ### How does pricing compare between Inngest and Trigger.dev?
The models favor different workload shapes.

Feature  | Trigger.dev  | Inngest
--- | --- | ---
Pricing model  | Compute-seconds + per-run fee  | Per-step execution + concurrency tiers
Free tier  | Free plan with monthly usage included  | 50,000 executions/mo, 5 concurrent steps
Pro tier  | See pricing  | Pro tier with more executions and concurrency (see pricing )
What counts as a billable unit  | Compute time (per second, by machine size) plus a flat fee per task run, however many steps it has  | Executions: 1 when the run starts, plus 1 for each step
Self-hosted cost  | Free (Apache 2.0) + your infra  | Free (SSPL) + your infra

Inngest&#39;s per-execution pricing scales with function complexity. Each run counts as the run itself plus every step, so a 5-step run is 6 executions and 100,000 runs of that function is 600,000 executions against your plan. This model works well for simple functions with few steps. Trigger.dev charges for compute time: a task that runs for 10 seconds costs the same whether it has 1 logical step or 50 internal operations. Which is cheaper depends on the workload. On Inngest, add your own hosting bill to the execution count. On Trigger.dev, cost depends on machine size and run time (including retries), plus a per-run fee for every task and subtask, so a workflow that splits work into subtasks, like the order example below, pays several run fees. Many-step work often favors Trigger.dev, while short functions with few steps can cost less on Inngest.
</excerpt>
</source>
<source kind="search">
<title>Trigger.dev vs n8n: open source n8n alternative | Trigger.dev</title>
<location>https://trigger.dev/vs/n8n</location>
<excerpt>citeturn0search3 [wordlim: 200] Crawled: today; The MCP server works across development and production environments, letting AI editors search docs, write tasks, trigger runs, and deploy. ... n8n&#39;s default architecture runs everything in a single Node.js process: the UI, webhooks, polling triggers, and workflow execution share the same resources. ... See n8n pricing and Trigger.dev pricing for current details. ... Trigger.dev charges per compute-second plus a per-run fee. n8n&#39;s model is simpler to predict for high-volume simple automations.
Environments  | Production, Staging, Preview (per-branch), Development  | Business + Enterprise: environments with source control sync

n8n&#39;s default architecture runs everything in a single Node.js process: the UI, webhooks, polling triggers, and workflow execution share the same resources. For production scale, queue mode distributes execution to separate worker processes via Redis. Both modes are available on self-hosted (including the free community edition). n8n Cloud handles hosting; Code nodes on Cloud run vanilla JS and Python without external package imports. Trigger.dev takes a managed compute approach: each task run gets its own container with configurable machine presets, so a memory spike in one task can&#39;t affect others. Build extensions add system-level dependencies (Prisma, FFmpeg, Playwright, Python) with a config line. Deploy with the CLI, GitHub auto-deploy, or the Vercel integration.

## How does pricing compare?

n8n charges per workflow execution. Trigger.dev charges per compute-second plus a per-run fee. </excerpt>
</source>
<source kind="search">
<title>Billing alerts | Changelog</title>
<location>https://trigger.dev/changelog/billing-alerts</location>
<excerpt>citeturn0search4 [wordlim: 200] Published: 1.2 years ago; Crawled: last month; Co-founder, Trigger.dev ... You can now get notified when your compute usage exceeds a certain threshold.

July 31, 2025 View all changelogs

# Billing alerts

## Get notified when your usage exceeds certain thresholds.

James Ritchie

Co-founder, Trigger.dev

Matt Aitken

CEO, Trigger.dev

Image: Image for Billing alerts

You can now get notified when your compute usage exceeds a certain threshold. Head to the new &quot;Billing alerts&quot; page in &quot;Settings&quot; from the top left main menu.

Image: Billing alerts menu

Set a threshold in dollars for when you want to be notified. You can also get notified when you hit different percentages of usage so you have plenty of warning. You can also add as many team members as you want to be notified.

Image: Billing alerts UI</excerpt>
</source>
<omitted_sources count="7">Additional source records were omitted from this bounded result.</omitted_sources>
</source_evidence>

Citations:

- 1: https://trigger.dev/pricing?utm_source=openai

Describe the standard run fee as well as compute charges.

docs/webhooks/overview.mdx:88 says delivery-started or resumed runs are billed “by compute time.” Normal pricing also charges an invocation fee when a run starts executing. State both charges so this documentation does not understate webhook-triggered run costs.

Suggested fix
--- "a/docs/webhooks/overview.mdx"
+++ "b/docs/webhooks/overview.mdx"
@@ -85,7 +85,7 @@
 
 ## Pricing and limits
 
-Webhooks have no separate charge on Trigger.dev Cloud. Receiving, verifying, filtering and recording deliveries is included in every plan. The runs a delivery starts or resumes are billed like any other run, by compute time. See [pricing](https://trigger.dev/pricing).
+Webhooks have no separate charge on Trigger.dev Cloud. Receiving, verifying, filtering and recording deliveries is included in every plan. The runs a delivery starts or resumes use normal run pricing: a run that starts executing incurs the standard invocation fee, and execution time incurs compute charges. See [pricing](https://trigger.dev/pricing).
 
 A delivery that no subscriber's filter matches starts no run, so it uses no compute. A run [waiting](/webhooks/waiters) for a webhook is suspended, so it uses no compute until the webhook arrives.
 
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Webhooks have no separate charge on Trigger.dev Cloud. Receiving, verifying, filtering and recording deliveries is included in every plan. The runs a delivery starts or resumes are billed like any other run, by compute time. See [pricing](https://trigger.dev/pricing).
A delivery that no subscriber's filter matches starts no run, so it uses no compute. A run [waiting](/webhooks/waiters) for a webhook is suspended, so it uses no compute until the webhook arrives.
Webhooks have no separate charge on Trigger.dev Cloud. Receiving, verifying, filtering and recording deliveries is included in every plan. The runs a delivery starts or resumes use normal run pricing: a run that starts executing incurs the standard invocation fee, and execution time incurs compute charges. See [pricing](https://trigger.dev/pricing).
A delivery that no subscriber's filter matches starts no run, so it uses no compute. A run [waiting](/webhooks/waiters) for a webhook is suspended, so it uses no compute until the webhook arrives.

Comment thread docs/webhooks/waiters.mdx
| Timeout | 24 hours by default, 90 days at most |

On Trigger.dev Cloud the per-endpoint and per-environment limits depend on your plan. Self-hosted installs can change them with `WEBHOOK_WAITER_MAX_PER_ENDPOINT`, `WEBHOOK_WAITER_MAX_PER_ENVIRONMENT` and `WEBHOOK_WAITER_MAX_SHAPES`.
On Trigger.dev Cloud the per-endpoint and per-environment limits depend on your plan: see [Limits](/limits#webhook-waiters). Self-hosted installs can change them with `WEBHOOK_WAITER_MAX_PER_ENDPOINT`, `WEBHOOK_WAITER_MAX_PER_ENVIRONMENT` and `WEBHOOK_WAITER_MAX_SHAPES`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clarify the scope of the preceding limits table.

The table lists 10,000 live waiters per endpoint as the default, while the linked Cloud table lists 100 for Free and 1,000 for Hobby. Label the table as self-hosted defaults or separate Cloud and self-hosted values.

This branch has not been deployed

No deployments
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.

1 participant