When to create drains yourself
- You want drains for some projects only, or one drain for several projects.
- You want your own dataset and collection names.
- You want to route some log sources to their own dataset as well, for example
firewalllogs to a security team’s dataset. - You manage drains in your own scripts or infrastructure code.
Drain types
Use
ingestion.us.bronto.io for the US region. Every drain authenticates with the header x-bronto-api-key and an API key with the Ingestion role (see API Keys). Log, Speed Insights and Web Analytics drains also set x-bronto-dataset and x-bronto-collection, which decide where the data lands. Trace drains don’t need them: traces appear in Explore Traces, not in datasets.
What each drain contains:
- Logs: seven sources, in the field
source:lambda(functions),edge,static,build,external(external rewrites),firewallandredirect. Each record carriesdeploymentId; request records addenvironment,executionRegionand the request’sproxy.*fields, and function logs from traced requests carrytraceIdandspanId. See Functions, Builds and CDN, routing and firewall. - Traces: Vercel’s spans for each request (
vercel.edge-network,vercel.serverless-runtime). Spans from your own code reach Bronto directly through OpenTelemetry from code. - Speed Insights: Core Web Vitals from real users. Requires Speed Insights Plus. See Speed Insights.
- Web Analytics: page views and custom events. See Web Analytics.
- AI Gateway traces: one trace per model request. Vercel’s REST API docs don’t list this schema; create it in the dashboard. See Vercel AI SDK, AI Gateway and agents.
Create a drain yourself
In the dashboard
- Open Team Settings → Drains → Add Drain.
- Choose the data (logs, traces, Speed Insights or Web Analytics) and the projects.
- For logs, choose the sources and environments to send.
- Set the endpoint and format from the table above, and add the headers
x-bronto-api-key,x-bronto-datasetandx-bronto-collection.
Test log message records. Filter them out if you count events.
With the REST API
A log drain for one project, sent to the datasetvercel-logs in the collection my-app:
"schemas": { "analytics": { "version": "v2" } }; for Speed Insights, "speed_insights": { "version": "v1" }.
Filter what a drain sends
A filter decides which records a drain forwards. Use it to route: a second drain with a filter sends some of the records to another dataset as well, while the main drain sends everything. Set it on create or withPATCH /v1/drains/{id}. version must be "v2".
Only production build and firewall logs:
When you read a drain with
GET /v1/drains/{id}, its filter is returned in the field filterV2. The field filter stays empty, so check filterV2 to see which filter a drain applies.Formats, batching and delivery time
ndjsonsendsContent-Type: application/x-ndjson, one record per line.jsonsendsapplication/json, one JSON array per request. The connector and the drains in this guide use NDJSON.compression: "gzip"may not compress. Vercel’s docs say deliveries can be compressed, but on a test log drain over 20 minutes and 1,700 requests (up to 53 KB each) no request carriedContent-Encodingand every body was plain JSON. The cost is the same either way (see What drains cost).- Batches are small. In a test project with about 225 log records a minute, Vercel sent about 56 requests a minute: a median of 3 records per request, at most 65. The median record was 1.2 KB.
- Delivery is near real time. Half of the records arrived within 5 seconds of their timestamp, 95% within about a minute, all within about 2 minutes.
- Changes take minutes to apply. After a
PATCH, deliveries kept the old settings for 2 to 4 minutes.
Verify deliveries with a signature
When a drain has a secret, every request carries the headerx-vercel-signature: an HMAC-SHA1 of the request body, hex-encoded, keyed with the secret. Drains created through the REST API have no secret until you set one ("delivery": { "secret": "…" } on create or by PATCH).
Bronto’s endpoint authenticates drains by API key. The signature matters when a drain goes to your own receiver first, for example a forwarder that enriches records:
When deliveries fail
Vercel doesn’t buffer a failing drain. In a test, the receiving endpoint answered500 for 15 minutes:
- Vercel sent each batch twice: the retry came about 0.2 seconds after the first attempt (at most 0.5 seconds), then the batch was dropped.
- Of 1,803 records created in those 15 minutes, 1,767 (98%) were never delivered. Nothing was resent after the endpoint recovered.
- Deliveries resumed within a second of recovery.
What drains cost
Vercel charges **$0.50 per GB** for drains on Pro, measured as the uncompressed JSON of each record, whatever the delivery encoding. AI Gateway trace drains add $0.05 per 1,000 traces.
To see what drains cost per project, query Vercel’s billing API,
GET /v1/billing/charges. It returns one line per service and day (ServiceName: Drains Volume) with the ProjectId.
Bronto keeps everything a drain sends, so send everything, once. The volume that’s worth removing is duplicates: a trace drain also forwards your own spans, so if your code exports them directly as well, every span arrives twice (see OpenTelemetry from code). Use filters to route records, not to drop them.
Known limits
- Drains need a Pro or Enterprise plan.
- Changes take minutes to apply. After a
PATCH, deliveries keep the old settings for 2 to 4 minutes. A drain’s filter is infilterV2, not infilter. - A plain trace drain doesn’t carry AI Gateway traces. They need their own
ai_gatewaydrain.

