Repository navigation
docs(webhooks): pricing and per-plan webhook limits - #5051
jackbridger wants to merge 1 commit into
Conversation
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.
WalkthroughThe 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
|
|
|
||
| ## 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. |
There was a problem hiding this comment.
🟡 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
| | 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. |
There was a problem hiding this comment.
🟡 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
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
📒 Files selected for processing: 7
.changeset/cost-skill-webhook-filters.mddocs/how-to-reduce-your-spend.mdxdocs/limits.mdxdocs/webhooks/deliveries.mdxdocs/webhooks/overview.mdxdocs/webhooks/waiters.mdxpackages/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.mdxdocs/webhooks/waiters.mdxdocs/how-to-reduce-your-spend.mdxdocs/limits.mdxdocs/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.mdxdocs/webhooks/waiters.mdxdocs/how-to-reduce-your-spend.mdxdocs/limits.mdxdocs/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 & IntegrationConfirm 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-backfillhas run. Confirm the deployed configuration and backfill state. Otherwise, label the limits as planned or beta.docs/limits.mdx: 1
185-190: 🗄️ Data Integrity & IntegrationThe active Cloud values and
webhook-limits-backfillstatus 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. |
There was a problem hiding this comment.
📐 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.
|
|
||
| ## 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). |
There was a problem hiding this comment.
📐 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.
| | Pricing tier | Limit | | ||
| | :----------- | :----------------------- | | ||
| | Free | 5 concurrent deliveries | | ||
| | Hobby | 10 concurrent deliveries | | ||
| | Pro | 50 concurrent deliveries | |
There was a problem hiding this comment.
🗄️ 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.
| | 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. |
There was a problem hiding this comment.
🗄️ 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 -200Repository: 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 1Repository: 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 -160Repository: 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.
| 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). |
There was a problem hiding this comment.
🎯 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.
| 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. |
There was a problem hiding this comment.
🗄️ 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 1Repository: 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 451d78c9b54eda489cf9ba278f05ec68544bfcbfRepository: 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>citeturn0search0 [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>citeturn0search1 [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're done with the work they can make a POST request to that URL and we'll continue the run with the result.
It's easier to understand with an example. Here we're going to get Replicate to generate an image for us in the background.
`
import { task, wait } from "@trigger.dev/sdk";
const replicate = new Replicate({
auth: process.env.REPLICATE_API_KEY,
});
export const generateImage = task({
id: "generate-image",
run: async () => {
// You can create this token from your backend or inside a task
const token = await wait.createToken({
timeout: "10m",
});
await replicate.predictions.create({
version:
"27b93a2413e7f36cd83da926f3656280b2931564ff050bf9575f1fdf9bcd7478",
input: {
prompt: "A painting of a cat by Andy Warhol",
},
// pass the token url to Replicate's webhook, so they can "callback"
// 👇
webhook: token.url,
webhook_events_filter: ["completed"],
});
const result = await wait.forToken<Prediction>(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>citeturn0search2 [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'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>citeturn0search3 [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'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'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'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'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>citeturn0search4 [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 "Billing alerts" page in "Settings" 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.
| 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. |
| | 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`. |
There was a problem hiding this comment.
🎯 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.
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 fromenterprise/apps/billing/app/plans/v3.server.tsandMAX_WEBHOOK_SUBSCRIBERS_PER_ENDPOINT). The existing ingest-rate tables and the#webhook-ingest-rate-limitsanchor 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-savingsskill: one bullet on webhook filters, plus a patch changeset for@trigger.dev/sdk.mint broken-linkspasses.To confirm before merging
webhook-limits-backfillhas run).