- Coverage by target cloud
- How the backends compare
- On Google Cloud
- On Google Cloud, Azure, OCI, and Private Kubernetes
- On Azure
- Costs
- Service level agreements
- Debug this service
Coverage by target cloud
How the backends compare
Each row compares a capability of EventBridge with its adaptation on each backend. A dash means this row is not stated for that backend.Max adaptation
Infrastructure-only adaptation
On Google Cloud
Via Cloud SQL for PostgreSQL
PostgreSQL hosting
Google operates Cloud SQL for PostgreSQL. The appliance provisions one instance with no public IP address, reached only through a Private Service Connect endpoint inside the appliance’s network, and every connection uses TLS. The PostgreSQL major version is fixed when the appliance is set up; Google applies maintenance in its own window, which restarts the instance. Daily automated backups run with point-in-time recovery, keeping seven days of transaction logs and seven backups. The instance runs in a single zone without a regional standby, so a restart for maintenance or failure makes PutEvents return errors and stops delivery until the instance returns. Committed events and pending deliveries are still there afterwards. A restore is run by your administrator from the appliance’s Terraform runbook: it creates a new instance from the backups at the chosen point and moves the appliance to it by an apply, keeping the old instance until the writes made after that point are reconciled. A restore returns the store to a chosen point within the last seven days: events accepted after that point are lost although PutEvents returned success, deliveries pending at that point may be sent again, and buses, rules and targets created after it return when their stacks are applied again. EventBridge state lives in one database on that instance. The SQS and SNS adapters on the same appliance use the same database when they run on PostgreSQL, and the appliance’s own state store is a separate database on the same instance. Because an event bus declares no database size, the instance has a fixed, dedicated 1-vCPU, 6-GiB default machine size. The adapter runs as one pod, replaced rather than overlapped on each update; connections, storage and throughput are shared limits, so watch them alongside pending delivery work. New GCP setups use Cloud SQL IAM service-account logins, IAM tokens and password-free connection strings. The appliance runtime reads its connection strings from Kubernetes Secrets. A legacy appliance’s off-cluster adapters read their own IAM connection strings from Secret Manager; the standalone installer instead delivers each service’s own login and database connection string through a Kubernetes Secret. A privileged appliance administrator or initialization job applies the database grants. Existing installations may retain older credentials; this setup does not migrate them. The application never handles these connection strings. Removing the appliance removes the instance and the EventBridge state on it, so drain pending work first. Buses start empty, and existing AWS history is not migrated.Accepting and matching events
The Tensor9 adapter provides the EventBridge API, and PostgreSQL stores your buses, rules, targets, accepted events and the deliveries still to be made. Terraform declarations and authenticated API calls work on the same records within an account. Point the application’s EventBridge client at the adapter’s endpoint, with the target environment’s credentials. For each event sent to an existing bus, the adapter evaluates the bus’s enabled rules and saves the event together with one pending delivery per matched rule and target, so two rules with the same destination produce two deliveries. Each entry in a batch is saved on its own: a batch request can fail after earlier entries were saved, so retrying the whole batch can duplicate events. Delivery to destinations happens afterward. An event sent to a bus that does not exist can still receive an event ID, but it is neither stored nor delivered. Confirm the bus exists before switching producers; an event ID alone does not mean the event was saved. Event patterns support nested objects, scalar and array values, the alternatives operator, prefix and suffix with their case-insensitive forms, equals-ignore-case, wildcard with escaped asterisks, numeric ranges, exists, IPv4 and IPv6 cidr, and anything-but with values, prefix, suffix, wildcard and case-insensitive forms. Matching runs in the adapter, so rules can inspect nested detail fields directly. Case-insensitive matching folds Unicode letters as EventBridge does. A malformed pattern is rejected with EventBridge’s reason; a pattern that is not valid JSON gets a different message.Destination calls and payloads
Delivery workers pick up pending deliveries and call each target. SQS, SNS and Lambda calls are signed AWS requests, so each destination needs a reachable endpoint and permission for its operation:SendMessage, Publish or InvokeFunction. Permission to deliver to SQS does not imply SNS or Lambda access. HTTP targets receive an unsigned POST; EventBridge Connections and API destinations are not part of this mapping.
By default a target receives the EventBridge envelope: id, source, detail-type, time, region, account, resources and detail. A target can instead use a constant Input, an InputPath selection or an InputTransformer template, but only one of them. JSON paths support the root, dotted members and non-negative array indexes; other path syntax is rejected when you configure the target. Template variables must be declared, and not every AWS reserved variable is available. As in EventBridge, an InputPath that selects nothing delivers an empty JSON object, and a template variable that selects nothing renders as an empty value.
Lambda targets are invoked asynchronously first. If the function rejects asynchronous invocation, the worker falls back to a synchronous call; function errors then follow the target’s EventBridge retry policy, and Lambda’s asynchronous failure destinations do not apply. Deliveries in one batch are sent concurrently, so a slow function does not hold up the others in its batch, but the slowest send, up to a per-send time limit, delays the next batch.
Retries, duplicates and dead letters
Pending deliveries survive a restart. Deliveries a stopped worker had picked up resume when its lease expires, which can take up to about five minutes. A worker can retry after a lease expires even if the destination accepted the earlier call but the worker stopped before recording success. Delivery is therefore at least once, with no ordering guarantee; use an event key in your application to make repeated deliveries harmless. Each target can set its retry count and maximum event age. Age is measured from when the adapter accepted the event, not from the event’s own time field. The default number of attempts differs from AWS. One target’s retries do not depend on another target’s success. When a delivery fails for good and the target has an SQS dead-letter queue, the failure and the pending dead-letter send are saved together in one database transaction. A separate worker then sends the target’s rendered payload to that queue with EventBridge’sERROR_CODE, ERROR_MESSAGE, RULE_ARN and TARGET_ARN message attributes, plus RETRY_ATTEMPTS and EXHAUSTED_RETRY_CONDITION when a retry or age limit ran out. ERROR_CODE holds EventBridge’s value for a destination 5xx error, a permission error and a missing queue; other failures, including timeouts and throttling, are reported as UNKNOWN. Dead-letter messages arrive asynchronously and can be duplicated after a crash. Sends to the dead-letter queue are retried separately, and a send that exhausts those retries needs operator attention, so a dead-letter queue does not guarantee that every failed event arrives there.
Scheduled rules
Scheduled rules create the same saved deliveries as matched events. Rate expressions and six-field UTC cron are supported, including values, ranges that wrap, lists, steps, names, the? day selector, explicit years, and the L, L-n, LW, nW, nL and n#k calendar forms. L-n selects no day in a month too short for it. Changing a rule’s expression schedules it afresh.
PutRule validates expressions as EventBridge does and allows schedules only on the default bus. It also rejects a few forms EventBridge accepts but whose firing times are undocumented: a step of zero, # on a range or on a day outside 1-7, W on a range, and L-n or a ranged L in the day-of-week field. A rate too long for the database’s calendar is accepted but never fires. Occurrences missed during downtime are not run later, and re-enabling a rule does not replay the time it was disabled. The separate EventBridge Scheduler service is not part of this mapping.
Limitations
- Per-target
RoleArnand service-specific parameters are not supported.PutTargetsrejects them, including FIFOSqsParameters, ECS and HTTP parameters, and a request with any unsupported target field fails as a whole. Check the operation table before migrating those declarations. - Target updates behave differently: pending deliveries follow the new configuration. Workers read a target’s configuration when they pick up a delivery, so updating a target can redirect pending work; a delivery already picked up may still use the old configuration. - Disabling a rule behaves differently: saved deliveries still go out. It stops new matching but does not cancel accepted work. Drain pending deliveries before deleting and re-creating a target with the same name. - Archives, replay, cross-account and cross-region routing, per-bus customer KMS keys, Pipes and the schema registry are not supported. The saved delivery records are not an event archive your application can read. - Unrecognized credentials behave differently: they get HTTP 403. EventBridge answers 400.
Other considerations
Who runs what. Tensor9 operates the adapter, matcher, delivery workers and scheduler. Database availability, backups and capacity depend on the PostgreSQL deployment you choose. Set up database access and destination permissions with the deployment. Before switching producers. Create buses, rules and targets first. AWS event history and pending deliveries are not copied, so keep the old destinations available until their pending work finishes. Check the payloads your targets receive, not only successfulPutEvents responses.
What to monitor. Track pending deliveries, retries, permanent failures and failed dead-letter sends separately; a successful publish does not mean the event was delivered.
Example monthly charges
This Tensor9 BYOC scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. How Tensor9 estimates costs explains the method and what the estimates include.EventBridge · Custom event units
Feature: EventBridge. Estimated monthly service charges by Custom event units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.
Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 96 vCPU, 384 GiB memory and 100 GiB SSD at 10,000 per second.
Curve assumptions
- Rules evaluated, matched targets and retries remain explicit. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
- Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
- Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
- Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
- Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve’s workload note.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Cloud SQL Enterprise edition (PostgreSQL) publishes separate vCPU, memory and SSD prices for zonal instances; a high-availability (regional) instance bills exactly twice each, which the standby copy reproduces. Enterprise Plus, committed-use discounts, backups (USD 0.08 per GiB-month) and idle IPv4 addresses (0.01 per hour) are not selected.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU (https://docs.cloud.google.com/sql/docs/postgres/instance-settings).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
- AWS Price List API, AWSEvents offer: https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSEvents/current/us-east-1/index.json
- Cloud SQL pricing: https://cloud.google.com/sql/pricing
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
plan-c010cda26af1a7ba1dd7b53dd4a4725b1efe0c50 / 2026-10-22.planning.2. Curve: workload-1.
Sources: AWS Price List API, AWSEvents offer, Cloud SQL pricing.
EventBridge → Cloud SQL for PostgreSQL: Authored native-usage planning example. Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.
Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.
Estimated allocation, not benchmark calibrated: sized at 2 vCPU, 8 GiB memory and 100 GiB SSD for this scenario.
Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.
Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.
Excluded costs and workload features:
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
- Translated reads: 0 operations.
- Translated writes: 0 operations.
- Translated resident physical data: 0 GiB-month.
- Native provider operations: 0 operations.
- Published payload: 0 GiB.
- Delivered payload: 0 GiB.
- Allocated execution CPU: 0 vCPU-hour.
- Allocated execution RAM: 0 GiB-hour.
- Independent resource allocation: 0 resource-hour.
- Independent inventory: 0 resource-month.
- Input tokens: 0 tokens.
- Output tokens: 0 tokens.
- Billable network: 0 GiB.
- Dependent object sink retained data: 0 GiB-month.
- Dependent object sink writes: 0 writes.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Cloud SQL Enterprise edition (PostgreSQL) publishes separate vCPU, memory and SSD prices for zonal instances; a high-availability (regional) instance bills exactly twice each, which the standby copy reproduces. Enterprise Plus, committed-use discounts, backups (USD 0.08 per GiB-month) and idle IPv4 addresses (0.01 per hour) are not selected.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU (https://docs.cloud.google.com/sql/docs/postgres/instance-settings).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
plan-c010cda26af1a7ba1dd7b53dd4a4725b1efe0c50 / 2026-10-22.planning.2. Scenario: planning-example.
Sources: AWS Price List API, AWSEvents offer, Cloud SQL pricing.
Via Pub/Sub
Scope
EventBridge delivery through Google Cloud Pub/Sub is outside this profile’s offered contract. Use the PostgreSQL service adapter for EventBridge buses, rules and durable target delivery. This comparison explains the native Pub/Sub features and the differences that matter when you evaluate an EventBridge mapping.Topics, filters and destination delivery
A Pub/Sub topic is the natural counterpart of an event bus, with subscriptions selecting messages for consumers. Pub/Sub filters inspect message attributes, not the message body. Copying source and detail-type into attributes can express simple conditions; matching on nested EventBridge detail needs extra processing. See Pub/Sub message filtering. An EventBridge mapping would also need an adapter to acceptPutEvents and manage rules, plus workers that apply each target’s input selection and call authorized destinations. Pub/Sub acknowledging a message is not the same as that destination call completing.
Limitations
- EventBridge per-target retries, event-age limits and SQS dead-letter queues are not supported. Pub/Sub’s subscription redelivery and dead-letter topics are different mechanisms. - Scheduled rules are not supported. A separate scheduler, such as Cloud Scheduler, would have to reproduce rule timing and destination behavior. - Archives, replay, Pipes and the schema registry are not supported.
Other considerations
Google operates Pub/Sub storage and subscription redelivery. Your consumers still need authentication, network access and processing that tolerates duplicates. Pub/Sub’s broker features alone do not provide EventBridge API compatibility or target delivery.Example monthly charges
This Tensor9 BYOC scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. How Tensor9 estimates costs explains the method and what the estimates include. Native or deployment mapping. This mapping uses native Pub/Sub delivery rather than an EventBridge API endpoint. Event delivery follows the target service’s behavior; there is no EventBridge adapter request to measure. Cost estimates describe the selected service resources; operation coverage remains separate.EventBridge · Custom event units
Feature: EventBridge. Estimated monthly service charges by Custom event units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.
Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 96 vCPU, 384 GiB memory and 100 GiB SSD at 10,000 per second.
Curve assumptions
- Rules evaluated, matched targets and retries remain explicit. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
- Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
- Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
- Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
- Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve’s workload note.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Native/deployment comparison scope: This mapping uses native Pub/Sub delivery rather than an EventBridge API endpoint. Event delivery follows the target service’s behavior; there is no EventBridge adapter request to measure.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Google Pub/Sub bills published and delivered bytes at the Message Delivery Basic rate and retained messages per GiB-month. Each request is billed at no less than 1,000 bytes; the family’s batching and delivery assumptions must represent that. The first 10 GiB of combined throughput a month is free per billing account and is not applied. BigQuery and Cloud Storage subscriptions bill USD 50 per TiB instead. Unacknowledged messages younger than one day bill no storage.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU (https://docs.cloud.google.com/sql/docs/postgres/instance-settings).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
- AWS Price List API, AWSEvents offer: https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSEvents/current/us-east-1/index.json
- Pub/Sub pricing: https://cloud.google.com/pubsub/pricing
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
plan-c03446d19e35e982d41ca3014545e9ec0d6edd9c / 2026-10-22.planning.2. Curve: workload-1.
Sources: AWS Price List API, AWSEvents offer, Pub/Sub pricing.
EventBridge → Pub/Sub: Authored native-usage planning example. Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.
Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.
Estimated allocation, not benchmark calibrated: sized at 2 vCPU, 8 GiB memory and 100 GiB SSD for this scenario.
Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.
Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.
Excluded costs and workload features:
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
- Translated reads: 0 operations.
- Translated writes: 0 operations.
- Translated resident physical data: 0 GiB-month.
- Native provider operations: 0 operations.
- Published payload: 0 GiB.
- Delivered payload: 0 GiB.
- Allocated execution CPU: 0 vCPU-hour.
- Allocated execution RAM: 0 GiB-hour.
- Independent resource allocation: 0 resource-hour.
- Independent inventory: 0 resource-month.
- Input tokens: 0 tokens.
- Output tokens: 0 tokens.
- Billable network: 0 GiB.
- Dependent object sink retained data: 0 GiB-month.
- Dependent object sink writes: 0 writes.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Native/deployment comparison scope: This mapping uses native Pub/Sub delivery rather than an EventBridge API endpoint. Event delivery follows the target service’s behavior; there is no EventBridge adapter request to measure.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Google Pub/Sub bills published and delivered bytes at the Message Delivery Basic rate and retained messages per GiB-month. Each request is billed at no less than 1,000 bytes; the family’s batching and delivery assumptions must represent that. The first 10 GiB of combined throughput a month is free per billing account and is not applied. BigQuery and Cloud Storage subscriptions bill USD 50 per TiB instead. Unacknowledged messages younger than one day bill no storage.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU (https://docs.cloud.google.com/sql/docs/postgres/instance-settings).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
plan-c03446d19e35e982d41ca3014545e9ec0d6edd9c / 2026-10-22.planning.2. Scenario: planning-example.
Sources: AWS Price List API, AWSEvents offer, Pub/Sub pricing.
On Google Cloud, Azure, OCI, and Private Kubernetes
Via PostgreSQL
Accepting and matching events
The Tensor9 adapter provides the EventBridge API, and PostgreSQL stores your buses, rules, targets, accepted events and the deliveries still to be made. Terraform declarations and authenticated API calls work on the same records within an account. Point the application’s EventBridge client at the adapter’s endpoint, with the target environment’s credentials. For each event sent to an existing bus, the adapter evaluates the bus’s enabled rules and saves the event together with one pending delivery per matched rule and target, so two rules with the same destination produce two deliveries. Each entry in a batch is saved on its own: a batch request can fail after earlier entries were saved, so retrying the whole batch can duplicate events. Delivery to destinations happens afterward. An event sent to a bus that does not exist can still receive an event ID, but it is neither stored nor delivered. Confirm the bus exists before switching producers; an event ID alone does not mean the event was saved. Event patterns support nested objects, scalar and array values, the alternatives operator, prefix and suffix with their case-insensitive forms, equals-ignore-case, wildcard with escaped asterisks, numeric ranges, exists, IPv4 and IPv6 cidr, and anything-but with values, prefix, suffix, wildcard and case-insensitive forms. Matching runs in the adapter, so rules can inspect nested detail fields directly. Case-insensitive matching folds Unicode letters as EventBridge does. A malformed pattern is rejected with EventBridge’s reason; a pattern that is not valid JSON gets a different message.Destination calls and payloads
Delivery workers pick up pending deliveries and call each target. SQS, SNS and Lambda calls are signed AWS requests, so each destination needs a reachable endpoint and permission for its operation:SendMessage, Publish or InvokeFunction. Permission to deliver to SQS does not imply SNS or Lambda access. HTTP targets receive an unsigned POST; EventBridge Connections and API destinations are not part of this mapping.
By default a target receives the EventBridge envelope: id, source, detail-type, time, region, account, resources and detail. A target can instead use a constant Input, an InputPath selection or an InputTransformer template, but only one of them. JSON paths support the root, dotted members and non-negative array indexes; other path syntax is rejected when you configure the target. Template variables must be declared, and not every AWS reserved variable is available. As in EventBridge, an InputPath that selects nothing delivers an empty JSON object, and a template variable that selects nothing renders as an empty value.
Lambda targets are invoked asynchronously first. If the function rejects asynchronous invocation, the worker falls back to a synchronous call; function errors then follow the target’s EventBridge retry policy, and Lambda’s asynchronous failure destinations do not apply. Deliveries in one batch are sent concurrently, so a slow function does not hold up the others in its batch, but the slowest send, up to a per-send time limit, delays the next batch.
Retries, duplicates and dead letters
Pending deliveries survive a restart. Deliveries a stopped worker had picked up resume when its lease expires, which can take up to about five minutes. A worker can retry after a lease expires even if the destination accepted the earlier call but the worker stopped before recording success. Delivery is therefore at least once, with no ordering guarantee; use an event key in your application to make repeated deliveries harmless. Each target can set its retry count and maximum event age. Age is measured from when the adapter accepted the event, not from the event’s own time field. The default number of attempts differs from AWS. One target’s retries do not depend on another target’s success. When a delivery fails for good and the target has an SQS dead-letter queue, the failure and the pending dead-letter send are saved together in one database transaction. A separate worker then sends the target’s rendered payload to that queue with EventBridge’sERROR_CODE, ERROR_MESSAGE, RULE_ARN and TARGET_ARN message attributes, plus RETRY_ATTEMPTS and EXHAUSTED_RETRY_CONDITION when a retry or age limit ran out. ERROR_CODE holds EventBridge’s value for a destination 5xx error, a permission error and a missing queue; other failures, including timeouts and throttling, are reported as UNKNOWN. Dead-letter messages arrive asynchronously and can be duplicated after a crash. Sends to the dead-letter queue are retried separately, and a send that exhausts those retries needs operator attention, so a dead-letter queue does not guarantee that every failed event arrives there.
Scheduled rules
Scheduled rules create the same saved deliveries as matched events. Rate expressions and six-field UTC cron are supported, including values, ranges that wrap, lists, steps, names, the? day selector, explicit years, and the L, L-n, LW, nW, nL and n#k calendar forms. L-n selects no day in a month too short for it. Changing a rule’s expression schedules it afresh.
PutRule validates expressions as EventBridge does and allows schedules only on the default bus. It also rejects a few forms EventBridge accepts but whose firing times are undocumented: a step of zero, # on a range or on a day outside 1-7, W on a range, and L-n or a ranged L in the day-of-week field. A rate too long for the database’s calendar is accepted but never fires. Occurrences missed during downtime are not run later, and re-enabling a rule does not replay the time it was disabled. The separate EventBridge Scheduler service is not part of this mapping.
Limitations
- Per-target
RoleArnand service-specific parameters are not supported.PutTargetsrejects them, including FIFOSqsParameters, ECS and HTTP parameters, and a request with any unsupported target field fails as a whole. Check the operation table before migrating those declarations. - Target updates behave differently: pending deliveries follow the new configuration. Workers read a target’s configuration when they pick up a delivery, so updating a target can redirect pending work; a delivery already picked up may still use the old configuration. - Disabling a rule behaves differently: saved deliveries still go out. It stops new matching but does not cancel accepted work. Drain pending deliveries before deleting and re-creating a target with the same name. - Archives, replay, cross-account and cross-region routing, per-bus customer KMS keys, Pipes and the schema registry are not supported. The saved delivery records are not an event archive your application can read. - Unrecognized credentials behave differently: they get HTTP 403. EventBridge answers 400.
Other considerations
Who runs what. Tensor9 operates the adapter, matcher, delivery workers and scheduler. Database availability, backups and capacity depend on the PostgreSQL deployment you choose. Set up database access and destination permissions with the deployment. Before switching producers. Create buses, rules and targets first. AWS event history and pending deliveries are not copied, so keep the old destinations available until their pending work finishes. Check the payloads your targets receive, not only successfulPutEvents responses.
What to monitor. Track pending deliveries, retries, permanent failures and failed dead-letter sends separately; a successful publish does not mean the event was delivered.
Example monthly charges
This Tensor9 BYOC scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. How Tensor9 estimates costs explains the method and what the estimates include.EventBridge · Custom event units
Feature: EventBridge. Estimated monthly service charges by Custom event units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.
Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 128 vCPU, 512 GiB memory and 100 GiB SSD at 10,000 per second.
Curve assumptions
- Rules evaluated, matched targets and retries remain explicit. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
- Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
- Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
- Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
- Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve’s workload note.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Self-hosted target: PostgreSQL (PostgreSQL License, https://www.postgresql.org/about/licence/). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer’s Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB (https://docs.cloud.google.com/compute/docs/general-purpose-machines); a Persistent Disk volume holds up to 64 TiB (https://docs.cloud.google.com/compute/docs/disks/persistent-disks).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
- AWS Price List API, AWSEvents offer: https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSEvents/current/us-east-1/index.json
- Compute Engine general-purpose machine pricing: https://cloud.google.com/products/compute/pricing/general-purpose
- Disk and image pricing: https://cloud.google.com/compute/disks-image-pricing
- Network pricing: https://cloud.google.com/vpc/network-pricing
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
plan-1b3d195812060b0f8a3f49a7665e8f1d793b512b / 2026-10-22.planning.2. Curve: workload-1.
Sources: AWS Price List API, AWSEvents offer, Compute Engine general-purpose machine pricing, Disk and image pricing, Network pricing.
EventBridge → PostgreSQL: Authored native-usage planning example. Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.
Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.
Estimated allocation, not benchmark calibrated: sized at 2 vCPU, 8 GiB memory and 100 GiB SSD for this scenario.
Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.
Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.
Excluded costs and workload features:
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
- Translated reads: 0 operations.
- Translated writes: 0 operations.
- Translated resident physical data: 0 GiB-month.
- Native provider operations: 0 operations.
- Published payload: 0 GiB.
- Delivered payload: 0 GiB.
- Allocated execution CPU: 0 vCPU-hour.
- Allocated execution RAM: 0 GiB-hour.
- Independent resource allocation: 0 resource-hour.
- Independent inventory: 0 resource-month.
- Input tokens: 0 tokens.
- Output tokens: 0 tokens.
- Billable network: 0 GiB.
- Dependent object sink retained data: 0 GiB-month.
- Dependent object sink writes: 0 writes.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Self-hosted target: PostgreSQL (PostgreSQL License, https://www.postgresql.org/about/licence/). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer’s Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB (https://docs.cloud.google.com/compute/docs/general-purpose-machines); a Persistent Disk volume holds up to 64 TiB (https://docs.cloud.google.com/compute/docs/disks/persistent-disks).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
plan-1b3d195812060b0f8a3f49a7665e8f1d793b512b / 2026-10-22.planning.2. Scenario: planning-example.
Sources: AWS Price List API, AWSEvents offer, Compute Engine general-purpose machine pricing, Disk and image pricing, Network pricing.
On Azure
Via PostgreSQL Flexible Server
PostgreSQL hosting
Microsoft operates Azure Database for PostgreSQL Flexible Server. The appliance provisions one server, injected into the appliance’s virtual network with no public endpoint, and every connection uses TLS. The PostgreSQL major version is fixed when the appliance is set up; Microsoft applies maintenance in its own window, which restarts the server. Automated backups keep seven days of history with point-in-time restore inside that window; geo-redundant backup is off. The server runs in a single availability zone without a zone-redundant standby, so a restart for maintenance or failure makes PutEvents return errors and stops delivery until the server returns. Committed events and pending deliveries are still there afterwards. A restore is run by your administrator from the appliance’s Terraform runbook: it creates a new server from the backups at the chosen point and moves the appliance to it by an apply, keeping the old server until the writes made after that point are reconciled. A restore returns the store to a chosen point within the last seven days: events accepted after that point are lost although PutEvents returned success, deliveries pending at that point may be sent again, and buses, rules and targets created after it return when their stacks are applied again. EventBridge state lives in one database on that server. The SQS and SNS adapters on the same appliance use the same database when they run on PostgreSQL, and the appliance’s own state store is a separate database on the same server. Because an event bus declares no database size, the server has a fixed default size; connections, storage and throughput are shared limits, so watch them alongside pending delivery work. New installations use Microsoft Entra authentication with managed identities and disable password authentication. The runtime uses short-lived Entra access tokens over TLS; its connection string names the database and identity without including a password. The connection string is written to a Kubernetes Secret in the appliance cluster, where the adapter reads it, for the cluster-hosted runtime. Appliance setup also publishes a password-free connection string for the adapters’ separate identity in Azure Key Vault. The standalone Kubernetes installer delivers its runtime connection string through its Kubernetes Secret; it does not require that appliance-vault copy. In standalone installations the messaging runtime currently has the family server’s Entra administrator role. Older appliances created before the Entra-only setup can retain their original password credentials. Removing the appliance removes the server and the EventBridge state on it, so drain pending work first. Buses start empty, and existing AWS history is not migrated.Accepting and matching events
The Tensor9 adapter provides the EventBridge API, and PostgreSQL stores your buses, rules, targets, accepted events and the deliveries still to be made. Terraform declarations and authenticated API calls work on the same records within an account. Point the application’s EventBridge client at the adapter’s endpoint, with the target environment’s credentials. For each event sent to an existing bus, the adapter evaluates the bus’s enabled rules and saves the event together with one pending delivery per matched rule and target, so two rules with the same destination produce two deliveries. Each entry in a batch is saved on its own: a batch request can fail after earlier entries were saved, so retrying the whole batch can duplicate events. Delivery to destinations happens afterward. An event sent to a bus that does not exist can still receive an event ID, but it is neither stored nor delivered. Confirm the bus exists before switching producers; an event ID alone does not mean the event was saved. Event patterns support nested objects, scalar and array values, the alternatives operator, prefix and suffix with their case-insensitive forms, equals-ignore-case, wildcard with escaped asterisks, numeric ranges, exists, IPv4 and IPv6 cidr, and anything-but with values, prefix, suffix, wildcard and case-insensitive forms. Matching runs in the adapter, so rules can inspect nested detail fields directly. Case-insensitive matching folds Unicode letters as EventBridge does. A malformed pattern is rejected with EventBridge’s reason; a pattern that is not valid JSON gets a different message.Destination calls and payloads
Delivery workers pick up pending deliveries and call each target. SQS, SNS and Lambda calls are signed AWS requests, so each destination needs a reachable endpoint and permission for its operation:SendMessage, Publish or InvokeFunction. Permission to deliver to SQS does not imply SNS or Lambda access. HTTP targets receive an unsigned POST; EventBridge Connections and API destinations are not part of this mapping.
By default a target receives the EventBridge envelope: id, source, detail-type, time, region, account, resources and detail. A target can instead use a constant Input, an InputPath selection or an InputTransformer template, but only one of them. JSON paths support the root, dotted members and non-negative array indexes; other path syntax is rejected when you configure the target. Template variables must be declared, and not every AWS reserved variable is available. As in EventBridge, an InputPath that selects nothing delivers an empty JSON object, and a template variable that selects nothing renders as an empty value.
Lambda targets are invoked asynchronously first. If the function rejects asynchronous invocation, the worker falls back to a synchronous call; function errors then follow the target’s EventBridge retry policy, and Lambda’s asynchronous failure destinations do not apply. Deliveries in one batch are sent concurrently, so a slow function does not hold up the others in its batch, but the slowest send, up to a per-send time limit, delays the next batch.
Retries, duplicates and dead letters
Pending deliveries survive a restart. Deliveries a stopped worker had picked up resume when its lease expires, which can take up to about five minutes. A worker can retry after a lease expires even if the destination accepted the earlier call but the worker stopped before recording success. Delivery is therefore at least once, with no ordering guarantee; use an event key in your application to make repeated deliveries harmless. Each target can set its retry count and maximum event age. Age is measured from when the adapter accepted the event, not from the event’s own time field. The default number of attempts differs from AWS. One target’s retries do not depend on another target’s success. When a delivery fails for good and the target has an SQS dead-letter queue, the failure and the pending dead-letter send are saved together in one database transaction. A separate worker then sends the target’s rendered payload to that queue with EventBridge’sERROR_CODE, ERROR_MESSAGE, RULE_ARN and TARGET_ARN message attributes, plus RETRY_ATTEMPTS and EXHAUSTED_RETRY_CONDITION when a retry or age limit ran out. ERROR_CODE holds EventBridge’s value for a destination 5xx error, a permission error and a missing queue; other failures, including timeouts and throttling, are reported as UNKNOWN. Dead-letter messages arrive asynchronously and can be duplicated after a crash. Sends to the dead-letter queue are retried separately, and a send that exhausts those retries needs operator attention, so a dead-letter queue does not guarantee that every failed event arrives there.
Scheduled rules
Scheduled rules create the same saved deliveries as matched events. Rate expressions and six-field UTC cron are supported, including values, ranges that wrap, lists, steps, names, the? day selector, explicit years, and the L, L-n, LW, nW, nL and n#k calendar forms. L-n selects no day in a month too short for it. Changing a rule’s expression schedules it afresh.
PutRule validates expressions as EventBridge does and allows schedules only on the default bus. It also rejects a few forms EventBridge accepts but whose firing times are undocumented: a step of zero, # on a range or on a day outside 1-7, W on a range, and L-n or a ranged L in the day-of-week field. A rate too long for the database’s calendar is accepted but never fires. Occurrences missed during downtime are not run later, and re-enabling a rule does not replay the time it was disabled. The separate EventBridge Scheduler service is not part of this mapping.
Limitations
- Per-target
RoleArnand service-specific parameters are not supported.PutTargetsrejects them, including FIFOSqsParameters, ECS and HTTP parameters, and a request with any unsupported target field fails as a whole. Check the operation table before migrating those declarations. - Target updates behave differently: pending deliveries follow the new configuration. Workers read a target’s configuration when they pick up a delivery, so updating a target can redirect pending work; a delivery already picked up may still use the old configuration. - Disabling a rule behaves differently: saved deliveries still go out. It stops new matching but does not cancel accepted work. Drain pending deliveries before deleting and re-creating a target with the same name. - Archives, replay, cross-account and cross-region routing, per-bus customer KMS keys, Pipes and the schema registry are not supported. The saved delivery records are not an event archive your application can read. - Unrecognized credentials behave differently: they get HTTP 403. EventBridge answers 400.
Other considerations
Who runs what. Tensor9 operates the adapter, matcher, delivery workers and scheduler. Database availability, backups and capacity depend on the PostgreSQL deployment you choose. Set up database access and destination permissions with the deployment. Before switching producers. Create buses, rules and targets first. AWS event history and pending deliveries are not copied, so keep the old destinations available until their pending work finishes. Check the payloads your targets receive, not only successfulPutEvents responses.
What to monitor. Track pending deliveries, retries, permanent failures and failed dead-letter sends separately; a successful publish does not mean the event was delivered.
Example monthly charges
This Tensor9 BYOC scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. How Tensor9 estimates costs explains the method and what the estimates include.EventBridge · Custom event units
Feature: EventBridge. Estimated monthly service charges by Custom event units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.
Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 96 vCPU, 384 GiB memory and 100 GiB SSD at 10,000 per second.
Curve assumptions
- Rules evaluated, matched targets and retries remain explicit. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
- Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
- Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
- Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
- Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve’s workload note.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Azure Database for PostgreSQL Flexible Server bills vCores with a fixed memory ratio per series; the vCPU and memory rates decompose the General Purpose and Memory Optimized v5 prices. High availability bills the standby’s compute and storage as a second copy. The minimum is the smallest Burstable server, which does not support high availability; the smallest General Purpose server (2 vCores) costs USD 133.62 per month. Additional IOPS, backup storage and reserved capacity are not selected.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: E96ds_v5 has 96 vCores and 672 GiB (https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-compute); Premium SSD storage holds up to 32,767 GiB (https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-storage).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
- AWS Price List API, AWSEvents offer: https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSEvents/current/us-east-1/index.json
- Azure Retail Prices API: https://prices.azure.com/api/retail/prices
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
plan-b861f9005b6aff9fc3cfc370aadd088e6a0c9776 / 2026-10-22.planning.2. Curve: workload-1.
Sources: AWS Price List API, AWSEvents offer, Azure Retail Prices API.
EventBridge → PostgreSQL Flexible Server: Authored native-usage planning example. Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.
Scenario source region: us-east-1. Scenario target region: eastus. Currency: USD.
Estimated allocation, not benchmark calibrated: sized at 2 vCPU, 8 GiB memory and 100 GiB SSD for this scenario.
Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.
Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.
Excluded costs and workload features:
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
- Translated reads: 0 operations.
- Translated writes: 0 operations.
- Translated resident physical data: 0 GiB-month.
- Native provider operations: 0 operations.
- Published payload: 0 GiB.
- Delivered payload: 0 GiB.
- Allocated execution CPU: 0 vCPU-hour.
- Allocated execution RAM: 0 GiB-hour.
- Independent resource allocation: 0 resource-hour.
- Independent inventory: 0 resource-month.
- Input tokens: 0 tokens.
- Output tokens: 0 tokens.
- Billable network: 0 GiB.
- Dependent object sink retained data: 0 GiB-month.
- Dependent object sink writes: 0 writes.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Azure Database for PostgreSQL Flexible Server bills vCores with a fixed memory ratio per series; the vCPU and memory rates decompose the General Purpose and Memory Optimized v5 prices. High availability bills the standby’s compute and storage as a second copy. The minimum is the smallest Burstable server, which does not support high availability; the smallest General Purpose server (2 vCores) costs USD 133.62 per month. Additional IOPS, backup storage and reserved capacity are not selected.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: E96ds_v5 has 96 vCores and 672 GiB (https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-compute); Premium SSD storage holds up to 32,767 GiB (https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-storage).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
plan-b861f9005b6aff9fc3cfc370aadd088e6a0c9776 / 2026-10-22.planning.2. Scenario: planning-example.
Sources: AWS Price List API, AWSEvents offer, Azure Retail Prices API.
Via Azure Event Grid
What this comparison covers
EventBridge delivery through Azure Event Grid is outside this profile’s offered contract. For EventBridge buses, rules and durable delivery to targets, use the PostgreSQL service adapter. This page compares how Event Grid itself works with EventBridge.Topics, filters and handlers
An Event Grid topic can deliver events as CloudEvents. Event subscriptions apply advanced filters and deliver matching events to handlers. Advanced filters support numeric and string conditions on supported fields, with syntax and limits that differ from EventBridge, so a matching field name does not mean the pattern behaves the same. Mapping EventBridge onto Event Grid would also need an adapter for the EventBridge API, and handlers that keep target payload selection, destination permissions and delivery results. Event Grid accepting an event does not mean it reached SQS, SNS or Lambda.Limitations
Where Event Grid and EventBridge differ- Retries and dead letters behave differently. Event Grid subscriptions use their own retry and event-age policies, and dead letters go to Blob Storage rather than an SQS dead-letter queue. See Event Grid delivery and retry.
- Scheduled rules are not supported. They need a separate scheduler and a way to deliver to the destination. Container Apps job schedules alone do not provide EventBridge’s behaviour.
- Target transformations, archives, replay, Pipes and the schema registry are not supported. None of them has a counterpart in this mapping.
Other considerations
Microsoft operates Event Grid topic storage and delivery. Your handlers still need authentication, network access and processing that tolerates duplicates. Review those separately from Event Grid’s retry policy when you evaluate a move.Example monthly charges
This Tensor9 BYOC scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. How Tensor9 estimates costs explains the method and what the estimates include. Native or deployment mapping. This mapping uses native Event Grid delivery rather than an EventBridge API endpoint. Event delivery follows the target service’s behavior; there is no EventBridge adapter request to measure. Cost estimates describe the selected service resources; operation coverage remains separate.EventBridge · Custom event units
Feature: EventBridge. Estimated monthly service charges by Custom event units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: East US; currency: USD.
Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 96 vCPU, 384 GiB memory and 100 GiB SSD at 10,000 per second.
Curve assumptions
- Rules evaluated, matched targets and retries remain explicit. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
- Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → East US, USD/month.
- Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
- Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
- Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve’s workload note.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Native/deployment comparison scope: This mapping uses native Event Grid delivery rather than an EventBridge API endpoint. Event delivery follows the target service’s behavior; there is no EventBridge adapter request to measure.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Azure Event Grid Basic (custom and system topics, domains) bills operations after 100,000 free a month: published events, advanced-filter matches and delivery attempts, each per 64 KB of payload. The family’s managed operations approximate publications plus delivery work. Event Grid namespaces (Standard tier) instead bill USD 0.04 per throughput-unit hour plus event and MQTT operations.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU (https://docs.cloud.google.com/sql/docs/postgres/instance-settings).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
- AWS Price List API, AWSEvents offer: https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSEvents/current/us-east-1/index.json
- Azure Retail Prices API: https://prices.azure.com/api/retail/prices
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
plan-656ce2b6cd8a54740cc930f862ce2db533e713fa / 2026-10-22.planning.2. Curve: workload-1.
Sources: AWS Price List API, AWSEvents offer, Azure Retail Prices API.
EventBridge → Azure Event Grid: Authored native-usage planning example. Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.
Scenario source region: us-east-1. Scenario target region: East US. Currency: USD.
Estimated allocation, not benchmark calibrated: sized at 2 vCPU, 8 GiB memory and 100 GiB SSD for this scenario.
Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.
Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.
Excluded costs and workload features:
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
- Translated reads: 0 operations.
- Translated writes: 0 operations.
- Translated resident physical data: 0 GiB-month.
- Native provider operations: 0 operations.
- Published payload: 0 GiB.
- Delivered payload: 0 GiB.
- Allocated execution CPU: 0 vCPU-hour.
- Allocated execution RAM: 0 GiB-hour.
- Independent resource allocation: 0 resource-hour.
- Independent inventory: 0 resource-month.
- Input tokens: 0 tokens.
- Output tokens: 0 tokens.
- Billable network: 0 GiB.
- Dependent object sink retained data: 0 GiB-month.
- Dependent object sink writes: 0 writes.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Native/deployment comparison scope: This mapping uses native Event Grid delivery rather than an EventBridge API endpoint. Event delivery follows the target service’s behavior; there is no EventBridge adapter request to measure.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Azure Event Grid Basic (custom and system topics, domains) bills operations after 100,000 free a month: published events, advanced-filter matches and delivery attempts, each per 64 KB of payload. The family’s managed operations approximate publications plus delivery work. Event Grid namespaces (Standard tier) instead bill USD 0.04 per throughput-unit hour plus event and MQTT operations.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU (https://docs.cloud.google.com/sql/docs/postgres/instance-settings).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
plan-656ce2b6cd8a54740cc930f862ce2db533e713fa / 2026-10-22.planning.2. Scenario: planning-example.
Sources: AWS Price List API, AWSEvents offer, Azure Retail Prices API.
Via Container Apps
How it works
Tensor9 turns each supported EventBridge scheduled rule into an Azure Container Apps Job with the same schedule. That is all this mapping does. There is no EventBridge API endpoint and no event bus, and the job does not deliver the scheduled event to the rule’s target. If your application needs EventBridge pattern matching,PutEvents and delivery to targets, use the PostgreSQL service adapter instead. A job schedule alone does not send the scheduled event to SQS.
Cron and rate schedules
Container Apps scheduled jobs use five-field cron in UTC. Tensor9 translates AWS six-field cron andrate expressions that can be written that way, and rejects expressions it cannot keep. Review the generated schedule and allow for job start-up time; a scheduled trigger does not guarantee immediate processing.
See Container Apps jobs for how Azure schedules and runs jobs.
Limitations
Where Container Apps Jobs and EventBridge differ- Event-pattern rules are not supported. Deployment rejects a rule with an
event_pattern; only scheduled rules translate. - Targets other than SQS are not supported, and SQS targets receive nothing. Deployment rejects non-SQS targets. An SQS target is accepted, but accepting it does not deliver the scheduled event to the queue.
- Target input overrides are not supported. Constant input, input paths and input transformers are rejected.
- EventBridge retries and dead-letter queues are not supported. Container Apps job retries and SQS queue redrive are separate policies you configure.
- Archives, replay, Pipes, the schema registry and cross-account buses are not supported. None of them has a counterpart in this mapping.
Other considerations
Microsoft runs the jobs. Estimate compute use from schedule frequency, run time and allocated resources. Any processing your application needs requires its own executable, destination credentials and network access; the schedule translation does not provide them.Example monthly charges
This Tensor9 BYOC scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. How Tensor9 estimates costs explains the method and what the estimates include. Native or deployment mapping. Scheduled jobs run as Container Apps jobs. This mapping does not expose an event bus or a PutEvents adapter endpoint; job execution is not fabric request latency. Cost estimates describe the selected service resources; operation coverage remains separate.EventBridge · Custom event units
Feature: EventBridge. Estimated monthly service charges by Custom event units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: East US; currency: USD.
Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 96 vCPU, 384 GiB memory and 100 GiB SSD at 10,000 per second.
Curve assumptions
- Rules evaluated, matched targets and retries remain explicit. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
- Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → East US, USD/month.
- Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
- Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
- Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve’s workload note.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Native/deployment comparison scope: Scheduled jobs run as Container Apps jobs. This mapping does not expose an event bus or a PutEvents adapter endpoint; job execution is not fabric request latency.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Azure Container Apps (Consumption plan) bills active vCPU-seconds, GiB-seconds and requests after a monthly free grant per subscription. Idle minimum replicas bill USD 0.000003 per vCPU-second and are not inferred; TCP apps bill per connection.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU (https://docs.cloud.google.com/sql/docs/postgres/instance-settings).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
- AWS Price List API, AWSEvents offer: https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSEvents/current/us-east-1/index.json
- Azure Retail Prices API: https://prices.azure.com/api/retail/prices
- Azure Container Apps pricing: https://azure.microsoft.com/en-us/pricing/details/container-apps/
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
plan-31f645677d120d117c82ffa4430248237b09c947 / 2026-10-22.planning.2. Curve: workload-1.
Sources: AWS Price List API, AWSEvents offer, Azure Retail Prices API, Azure Container Apps pricing.
EventBridge → Container Apps: Authored native-usage planning example. Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.
Scenario source region: us-east-1. Scenario target region: East US. Currency: USD.
Estimated allocation, not benchmark calibrated: sized at 2 vCPU, 8 GiB memory and 100 GiB SSD for this scenario.
Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.
Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.
Excluded costs and workload features:
- Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
- Destination application execution and separately billed downstream services; supply those allocations separately.
- Scheduler, Pipes, archive/replay and API destination prices; destination execution charges.
- Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
- Unmodeled dependent services, task execution and operations outside the selected workload family.
- Translated reads: 0 operations.
- Translated writes: 0 operations.
- Translated resident physical data: 0 GiB-month.
- Native provider operations: 0 operations.
- Published payload: 0 GiB.
- Delivered payload: 0 GiB.
- Allocated execution CPU: 0 vCPU-hour.
- Allocated execution RAM: 0 GiB-hour.
- Independent resource allocation: 0 resource-hour.
- Independent inventory: 0 resource-month.
- Input tokens: 0 tokens.
- Output tokens: 0 tokens.
- Billable network: 0 GiB.
- Dependent object sink retained data: 0 GiB-month.
- Dependent object sink writes: 0 writes.
- Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
- Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
- Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
- Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
- A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
- This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
- Native/deployment comparison scope: Scheduled jobs run as Container Apps jobs. This mapping does not expose an event bus or a PutEvents adapter endpoint; job execution is not fabric request latency.
- Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
- A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
- The durable events table, in-process matcher and delivery outbox run even when a native broker is selected in a proposed architecture.
- Native Pub/Sub/Event Grid rows are designs; cost coverage does not make those runtime paths served.
- Azure Container Apps (Consumption plan) bills active vCPU-seconds, GiB-seconds and requests after a monthly free grant per subscription. Idle minimum replicas bill USD 0.000003 per vCPU-second and are not inferred; TCP apps bill per connection.
- Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1_0_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
- Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing (https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
- Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full (https://docs.cloud.google.com/sql/docs/postgres/instance-settings). The 20 GiB reserve exceeds PostgreSQL’s 1 GB default max_wal_size; the remainder of that reserve is unmeasured.
- CPU tiers double from 2 vCPUs to the target’s largest node at 4 GiB per vCPU; each target’s documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
- No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
- Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU (https://docs.cloud.google.com/sql/docs/postgres/instance-settings).
- Stored GiB already includes the origin family’s physical footprint assumptions; no second storage amplification is applied.
- The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
- Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
plan-31f645677d120d117c82ffa4430248237b09c947 / 2026-10-22.planning.2. Scenario: planning-example.
Sources: AWS Price List API, AWSEvents offer, Azure Retail Prices API, Azure Container Apps pricing.
Costs
Estimated monthly service charges for each backend with a published cost model, at one sampled workload from that model’s cost curve. Adapter hosting and Tensor9 fees are excluded. How Tensor9 estimates costs explains the method, what the estimates include and how to read their qualifications.
Difference means backend minus origin; a positive difference means the backend costs more. Workloads and target configurations differ by model, so compare each row’s difference at its stated workload rather than charges across rows.
Cost curves across workload sizes, with every assumption and exclusion: EventBridge costs.
Service level agreements
Listed terms cover requests sent through this service adapter. They do not cover direct connections to the target service or replace the cloud provider’s own SLA. Each origin-to-target pair has its own terms or an explicit pending status. See the SLA tables, measurement rules, and scaling conditions.EventBridge to Container Apps
SLA status: Not applicable Scheduled jobs run as Container Apps jobs. This mapping does not expose an event bus or a PutEvents adapter endpoint; job execution is not fabric request latency.EventBridge to Azure Event Grid
SLA status: Not applicable This mapping uses native Event Grid delivery rather than an EventBridge API endpoint. Event delivery follows the target service’s behavior; there is no EventBridge adapter request to measure.EventBridge to PostgreSQL Flexible Server
Adapter-added latency. A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider’s SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.
What Tensor9 covers. These service levels cover the adapter between the origin API and target API. They do not replace the target provider’s SLA.
How latency is counted. Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.
Which terms apply. Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.
What this adapter does
Forazure::1.0.0::postgresql::flexible, the SLA separates event acceptance from delivery. The PostgreSQL-backed adapter persists events, evaluates enabled patterns and records one delivery task per matched target. Workers and the scheduler create and drain durable work separately. A slow destination can delay its delivery without slowing the producer’s acceptance response; slow adapter-owned rule lookup or delivery bookkeeping still counts as fabric time.
How the latency targets were chosen
Bounded event acceptance and matching: +25 ms monthly p99 (adapter-added).PutEvents. The PostgreSQL engine matches rules in-process and commits delivery-outbox work before acceptance. Rule lookup, matching, input transformation and adapter-owned outbox writes all count.
Bus, rule and target configuration: +20 ms monthly p99 (adapter-added). CreateEventBus, DeleteEventBus, DeleteRule, DescribeEventBus, DescribeRule, DisableRule, EnableRule, ListEventBuses, ListRules, ListTargetsByRule, PutRule, PutTargets, RemoveTargets. Durable catalog changes, pattern validation and target authorization precede the response; those metadata waits remain fabric work.
Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.
What counts toward latency
For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter’s own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it. For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request’s adapter duration first, then the monthly p99. Do not subtract one service’s p99 from another’s. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.Endpoint reachability and request failures
The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9’s responsibility even when the target is healthy. Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.Scaling and target-service capacity
Matching cost grows with events times rules, and delivery work grows with matched rules times targets. Scale handler CPU and delivery workers using both dimensions; watch delivery backlog and database connection pressure. The numeric request row deliberately bounds rules and fan-out. A customer with 2,000 rules needs a different envelope, not an assumption that more replicas eliminate per-event matching cost. Destination capacity and the customer’s retry/DLQ configuration remain separate. Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service’s capacity with Tensor9’s help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.Data and behavior guarantees
PutEvents must retain per-entry failure reporting. Accepted delivery work must survive an adapter restart according to the documented durable-store design. A destination can receive duplicates if it accepts a call just before the worker loses its acknowledgement. Input selection, pattern matching, target permissions and schedule syntax must follow the profile. The latency row does not promise exactly-once delivery, arbitrary cron precision or end-to-end delivery within 25 ms.Example and diagnosis
For busorder-events, submit five 2 KiB events with ten enabled rules and three targets per matching rule. This fits the acceptance row. Diagnose a slow producer by looking at catalog lookup, matching and outbox commit; diagnose a late consumer using delivery backlog and target errors. A fast PutEvents response alone does not prove delivery is healthy.
Use tensor9 explain and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider’s latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.
EventBridge to Cloud SQL for PostgreSQL
Adapter-added latency. A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider’s SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.
What Tensor9 covers. These service levels cover the adapter between the origin API and target API. They do not replace the target provider’s SLA.
How latency is counted. Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.
Which terms apply. Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.
What this adapter does
Forgoogle::1.0.0::cloudsql::postgresql, the SLA separates event acceptance from delivery. The PostgreSQL-backed adapter persists events, evaluates enabled patterns and records one delivery task per matched target. Workers and the scheduler create and drain durable work separately. A slow destination can delay its delivery without slowing the producer’s acceptance response; slow adapter-owned rule lookup or delivery bookkeeping still counts as fabric time.
How the latency targets were chosen
Bounded event acceptance and matching: +25 ms monthly p99 (adapter-added).PutEvents. The PostgreSQL engine matches rules in-process and commits delivery-outbox work before acceptance. Rule lookup, matching, input transformation and adapter-owned outbox writes all count.
Bus, rule and target configuration: +20 ms monthly p99 (adapter-added). CreateEventBus, DeleteEventBus, DeleteRule, DescribeEventBus, DescribeRule, DisableRule, EnableRule, ListEventBuses, ListRules, ListTargetsByRule, PutRule, PutTargets, RemoveTargets. Durable catalog changes, pattern validation and target authorization precede the response; those metadata waits remain fabric work.
Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.
What counts toward latency
For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter’s own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it. For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request’s adapter duration first, then the monthly p99. Do not subtract one service’s p99 from another’s. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.Endpoint reachability and request failures
The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9’s responsibility even when the target is healthy. Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.Scaling and target-service capacity
Matching cost grows with events times rules, and delivery work grows with matched rules times targets. Scale handler CPU and delivery workers using both dimensions; watch delivery backlog and database connection pressure. The numeric request row deliberately bounds rules and fan-out. A customer with 2,000 rules needs a different envelope, not an assumption that more replicas eliminate per-event matching cost. Destination capacity and the customer’s retry/DLQ configuration remain separate. Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service’s capacity with Tensor9’s help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.Data and behavior guarantees
PutEvents must retain per-entry failure reporting. Accepted delivery work must survive an adapter restart according to the documented durable-store design. A destination can receive duplicates if it accepts a call just before the worker loses its acknowledgement. Input selection, pattern matching, target permissions and schedule syntax must follow the profile. The latency row does not promise exactly-once delivery, arbitrary cron precision or end-to-end delivery within 25 ms.Example and diagnosis
For busorder-events, submit five 2 KiB events with ten enabled rules and three targets per matching rule. This fits the acceptance row. Diagnose a slow producer by looking at catalog lookup, matching and outbox commit; diagnose a late consumer using delivery backlog and target errors. A fast PutEvents response alone does not prove delivery is healthy.
Use tensor9 explain and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider’s latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.
EventBridge to Pub/Sub
SLA status: Not applicable This mapping uses native Pub/Sub delivery rather than an EventBridge API endpoint. Event delivery follows the target service’s behavior; there is no EventBridge adapter request to measure.EventBridge to PostgreSQL
Adapter-added latency. A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider’s SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.
What Tensor9 covers. These service levels cover the adapter between the origin API and target API. They do not replace the target provider’s SLA.
How latency is counted. Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.
Which terms apply. Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.
What this adapter does
Forpostgres::1.0.0::database, the SLA separates event acceptance from delivery. The PostgreSQL-backed adapter persists events, evaluates enabled patterns and records one delivery task per matched target. Workers and the scheduler create and drain durable work separately. A slow destination can delay its delivery without slowing the producer’s acceptance response; slow adapter-owned rule lookup or delivery bookkeeping still counts as fabric time.
How the latency targets were chosen
Bounded event acceptance and matching: +25 ms monthly p99 (adapter-added).PutEvents. The PostgreSQL engine matches rules in-process and commits delivery-outbox work before acceptance. Rule lookup, matching, input transformation and adapter-owned outbox writes all count.
Bus, rule and target configuration: +20 ms monthly p99 (adapter-added). CreateEventBus, DeleteEventBus, DeleteRule, DescribeEventBus, DescribeRule, DisableRule, EnableRule, ListEventBuses, ListRules, ListTargetsByRule, PutRule, PutTargets, RemoveTargets. Durable catalog changes, pattern validation and target authorization precede the response; those metadata waits remain fabric work.
Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.
What counts toward latency
For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter’s own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it. For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request’s adapter duration first, then the monthly p99. Do not subtract one service’s p99 from another’s. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.Endpoint reachability and request failures
The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9’s responsibility even when the target is healthy. Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.Scaling and target-service capacity
Matching cost grows with events times rules, and delivery work grows with matched rules times targets. Scale handler CPU and delivery workers using both dimensions; watch delivery backlog and database connection pressure. The numeric request row deliberately bounds rules and fan-out. A customer with 2,000 rules needs a different envelope, not an assumption that more replicas eliminate per-event matching cost. Destination capacity and the customer’s retry/DLQ configuration remain separate. Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service’s capacity with Tensor9’s help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.Data and behavior guarantees
PutEvents must retain per-entry failure reporting. Accepted delivery work must survive an adapter restart according to the documented durable-store design. A destination can receive duplicates if it accepts a call just before the worker loses its acknowledgement. Input selection, pattern matching, target permissions and schedule syntax must follow the profile. The latency row does not promise exactly-once delivery, arbitrary cron precision or end-to-end delivery within 25 ms.Example and diagnosis
For busorder-events, submit five 2 KiB events with ten enabled rules and three targets per matching rule. This fits the acceptance row. Diagnose a slow producer by looking at catalog lookup, matching and outbox commit; diagnose a late consumer using delivery backlog and target errors. A fast PutEvents response alone does not prove delivery is healthy.
Use tensor9 explain and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider’s latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.