Paybond agent middleware adds policy enforcement and evidence around side-effecting tool calls. For architects sizing agent workloads or comparing guarded vs unguarded tool latency, the important fact is simple: network round trips dominate — not local policy parsing or evidence JSON construction.
This guide describes the typical online path per guarded tool call, what adds latency, what the dev trace dashboard does not measure, and how to observe middleware overhead honestly in production. For integration mechanics, see Agent middleware. For the trace event model, see Middleware trace.
No published Kit p50/p99
Paybond does not publish middleware latency benchmarks. Hosted latency depends on region, tenant load, Harbor health, and your tool handler time. Use Gateway upstream SLIs and your own APM around guarded tool boundaries — not fabricated percentile tables.
What middleware adds
Middleware work splits into two buckets:
| Bucket | Examples | Typical cost |
|---|---|---|
| Local (small) | Policy YAML load, registry resolution, evidence payload build, payee/recognition signing | Sub-millisecond to low milliseconds on the same host |
| Network-bound (dominant) | POST /verify, POST /v1/spend/decisions/{id}/complete, evidence submit, optional MPP voucher finalize | One or more HTTP hops per phase — usually low tens to low hundreds of ms per hop on healthy hosted infra |
For fast tools (cache lookups, lightweight API calls), Paybond hops often exceed handler time. For slow tools (human approval, large file uploads, multi-second vendor APIs), middleware overhead is usually a smaller fraction of end-to-end latency.
Per guarded tool call — typical online path
The interceptor in kit/ts/src/agent/interceptor.ts (Python parity in paybond_kit.agent) runs a serial cycle for each registered side-effecting tool:
Kit middleware Gateway Harbor
| | |
|-- POST /verify --------->| auth + tenant scope |
| | Postgres idempotency |
| | optional spend-policy eval |
| |-- POST /verify (mTLS) ------->| capability verify
|<-- allow + decision_id --|<------------------------------|
| | |
| [local tool handler — not Paybond overhead] |
| | |
|-- POST .../complete ---->| finalize spend decision |
| | optional MPP voucher finalize |
| |-- internal finalize --------->| (stripe_mpp session)
|<-- consumed/released -----|<------------------------------|
| | |
|-- evidence submit ------>| sandbox guardrails OR |
| | recognition + fraud gate + |
| |-- POST .../evidence --------->| predicate VM
|<-- predicate result ------|<------------------------------|
Phases in order:
- Authorize —
POST /verifythrough Gateway. Harbor validates the capability token and spend amount; Gateway may apply spend-policy locks and idempotency in Postgres before/after the Harbor forward. - Execute — Your tool handler. Paybond does not instrument vendor latency beyond
durationMson thetool_executedtrace event. - Complete —
POST /v1/spend/decisions/{decision_id}/completemarks the spend decision consumed (or released on handler failure). Stripe MPP session mode may add an internal Harbor voucher finalize hop during completion. - Evidence — Auto-evidence after a successful handler:
- Sandbox bind — Gateway-composed
guardrailsevidence route (simulator lifecycle). - Production attach — Local payee + agent-recognition signing, then
POST /harbor/intents/{id}/evidencewith Gateway recognition verification and fraud hardening before Harbor proxy.
- Sandbox bind — Gateway-composed
Settlement confirm (released / refunded) is a separate Harbor mutation — not included in per-tool middleware latency unless your integration calls it inline after each tool.
Tenant isolation
Every hop uses tenant scope from authenticated credentials (API key, operator session). Kit never sends a client-supplied tenant id. Gateway rejects tenant mismatches before forwarding to Harbor.
Latency factors
| Factor | Effect | Mitigation |
|---|---|---|
| Serial verify → complete → evidence | Three or more HTTP round trips per guarded tool call | Batch work into fewer side-effecting tools; combine read-only steps outside Paybond |
| Split authorize / execute | Frameworks like Vercel AI may call authorize before execute | Authorization cache reuses a fresh verify for 120 seconds when operation, spend, and tool name match — see below |
| Gateway spend policy | Postgres evaluation and row locks on /verify | Scope policies narrowly; avoid global per-tenant locks across unrelated operations |
| mTLS Gateway ↔ Harbor | Fixed TLS + forward cost on every Harbor proxy | Co-locate regions; monitor Gateway→Harbor error SLI (production operations §3.2) |
| Harbor upstream timeout | Gateway Harbor clients use a 30s per-request timeout | Treat sustained approach to timeout as infra incident, not retry storm |
| SDK retry policy | Default 3 attempts on 429 / 5xx with exponential backoff (cap 5s per wait) and Retry-After (cap 30s); Cloudflare edge hints cap at 8s | Use idempotency keys; keep upstream healthy to avoid tail latency on blips |
| Production evidence path | Recognition proof verify + fraud gate + Harbor evidence proxy | Pre-validate payloads with paybond policy validate-evidence before production attach |
verify_capability rate limit | Default 240 requests per tenant per minute | Size agent concurrency; split tenants or stagger bursts |
| MPP voucher verify limit | Separate limiter when x-paybond-payment-authorization is present (default 120/min, env-tunable) | Session-mode metering adds verify-side work — expect extra Gateway time |
Offline dev (--offline) | Zero Paybond network hops | Local rehearsal only — not representative of production latency |
Qualitative overhead model
Without publishing fabricated percentiles:
- Expect roughly one RTT per Paybond phase on healthy hosted infrastructure — often ~20–150ms per hop within the same region, plus handler time.
- Multi-hop serial calls dominate for sub-100ms tools.
- Transient upstream errors can add several seconds of SDK retry backoff on tail paths.
- Signal lifecycle latency (intent outcome → reputation) operates on hours scale — not per-tool-call middleware time.
Authorization cache (split approve / execute)
Some agent frameworks separate tool approval from tool execution (for example Vercel AI SDK human-in-the-loop). Paybond caches a successful authorize result for 120 seconds (AUTHORIZATION_CACHE_TTL_SEC in kit/ts/src/agent/authorization-cache.ts).
The cache key is toolCallId:operation. A cached entry is reused in wrapExecute only when operation, requestedSpendCents, and toolName still match. Expired entries are evicted on the next authorize.
When it helps: approve now, execute seconds later without a second /verify.
When it does not apply: single-shot wrapExecute without a prior authorizeToolCall always calls /verify once. Mismatched spend or renamed tools miss the cache.
What dev trace shows — and what it does not
paybond dev trace and traceSink events label middleware phases, not network profiling.
| Trace event | What it measures |
|---|---|
tool_selected | Registry resolution — timestamp only |
spend_authorized | Authorize phase completed — no RTT field |
tool_executed | Handler wall time via durationMs only |
spend_finalized | Complete phase completed — no RTT field |
evidence_submitted | Evidence phase completed — no RTT field |
The durationMs on tool_executed is your local handler, not Paybond authorize or evidence latency. Use the trace dashboard to debug whether each phase ran and in what order — see Middleware trace — not to size production p99.
Hosted sandbox smoke may print trace_url and console dossier links; those surfaces still omit per-hop network timing until you add your own instrumentation around Kit calls.
Production observability
Kit runs in your infrastructure. Paybond observes middleware from the Gateway and Harbor side:
| Signal | Where | Use for |
|---|---|---|
| Gateway→Harbor error rate | Load balancer / gateway metrics | Upstream blips affecting every guarded call |
harbor_unreachable / harbor_unavailable | Gateway JSON errors | Incident correlation with middleware failures |
| OpenTelemetry | Gateway, Harbor when OTEL_EXPORTER_OTLP_ENDPOINT is set | Service-side spans — not Kit-internal |
| Console intent dossier | /console/operations/intents/{id} | Post-hoc audit of authorize → evidence → settlement |
| Signal lifecycle | Indexer lag SLIs | Intent-outcome reputation — not per-tool latency |
Recommended partner pattern:
- Wrap guarded tool entry/exit in your APM (OpenTelemetry, Datadog, etc.) with
intent_id,operation, andtool_call_idattributes. - Alert on Gateway→Harbor SLIs from Production operations v1 §3.2.
- Treat
predicate_passed: falseas a business outcome — not a retryable transport error (Disputes and evidence).
Reducing perceived latency
Practical patterns that preserve guardrails:
- Fewer side-effecting tools — consolidate paid vendor calls behind one guarded operation when policy allows.
- Read-only tools outside the registry — do not register passthrough tools that never spend.
- Pre-validate evidence —
paybond policy validate-evidencecatches schema issues before production attach signing. - Healthy idempotency keys — reuse stable keys per
toolCallIdso retries do not multiply Harbor work. - Regional co-location — run agents in the same region as your Gateway deployment when possible.
- Offline rehearsal —
paybond dev loop --offlinefor policy and trace UX without network variance.