This guide explains how we measure Event API performance, what our published numbers do and don't include, the limits you may encounter under high volume, and a step-by-step playbook for diagnosing latency you observe from your side.
If you're sending high volumes of events and seeing multi-second latency on your side while your requests still succeed, the delay often originates within the client's infrastructure—most commonly the connection pool. Our server-side processing is typically in the sub-second range. Jump to Latency Troubleshooting Guide.
If instead you're seeing HTTP 429, 503, or 403 responses, that sometimes indicates a limit or protection mechanism on our side responding — those are covered in Limits you may encounter.
We record request latency for every event request as a server-side metric. This captures the time from when a request reaches our edge server nodes until the response is returned to you. Please note that our latency metrics focus exclusively on processing time within our infrastructure and do not include overall network transit time or time spent queuing within your client-side infrastructure.
It measures the time from when a request arrives at our server to when we dispatch the response back to you. For the Event API this is typically in the low tens of milliseconds.
Included in the server-side number:
Request parsing and validation
Authentication / authorization (verifying the API token you send, on /authevent)
Event processing and persistence
Response generation
Not included in the server-side number (these happen outside our measurement window):
TLS handshake — happens once when a connection is first established, then the connection is reused, so it is not part of per-request processing time.
Network transit — time for packets to travel between your infrastructure and ours.
Client-side queuing — time a request spends waiting in your HTTP client's connection pool before it is ever sent to us.
Your own auth/token work — building the API token and Authorization header happens in your code before the HTTP request is made.
Why this matters for correlation:. Our clock starts when the request reaches us. If a request waits several seconds in your HTTP client's connection pool before being sent, that wait is invisible to our metrics by definition — the request simply arrives late, and then we process it in the usual few milliseconds. This is why a large gap between your end-to-end latency and our server-side latency points to something happening before the request leaves your infrastructure, and why the two numbers can't be fully reconciled against each other.
Both endpoints run the same event-processing path and show similar server-side performance. The difference is authentication:
/event — open endpoint. No API token required.
/authevent — requires an API token (with the send-events permission) supplied via the Authorization header, over HTTPS. Verifying that token is part of our server-side processing, but the overhead is small (typically under a millisecond).
The work of creating the token and building the Authorization header happens in your code, before the request is sent, so it is not part of our server-side time.
The Event API is a multi-tenant service with protections in place to keep it healthy for everyone. These limits are enforced per tenant where applicable, and when you hit one you get an explicit HTTP status code — not a silent slowdown. If your requests are succeeding but slow, you are not hitting these limits; see the Troubleshooting Guide instead.
|
HTTP status |
Meaning |
What it usually indicates |
|---|---|---|
|
401 Unauthorized |
Auth/channel mismatch |
Commonly indicates an auth/channel mismatch (e.g., sending a "trusted channel" event to the open /event endpoint). It can also be triggered by security mechanisms, such as an Intrusion Detection Service. |
|
403 Forbidden |
Blocked, or request origin not allowed |
A temporary block often triggered by our security infrastructure (e.g., automated WAF rules) if a specific IP or pattern of requests appears malicious, or (for browser/CORS traffic) the request Origin isn't in your allowed-origins list. |
|
406 Not Acceptable |
HTTP method not allowed for the endpoint |
Indicates an HTTP verb other than GET or POST (e.g., PUT, DELETE, or PATCH). The Event API accepts only GET and POST — a POST additionally requires a supported Content-Type. |
|
413 Payload Too Large |
Request body exceeds the maximum event size |
You may need to reduce batch size or payload size. |
|
415 Unsupported Media Type |
Content type not accepted |
Check your Content-Type header. Review Event API documentation for supported types. |
|
429 Too Many Requests |
Rate limited / concurrency limit reached |
Review your request volume and frequency. Optimize your event stream by batching or reducing redundant events. For more details, see Event Limits and Channels/Campaigns Limits. |
|
503 Service Unavailable |
Temporary backpressure (circuit-breaker protection). |
Review the request pattern to ensure the implementation is not overloading the service. Retry with exponential backoff if the issue persists. |
Key distinction: Rate limiting and backpressure protections announce themselves with 429 or 503 responses. These typically do not manifest as requests that hang for several seconds before succeeding with a 200. If you observe slow-but-successful requests, the latency is likely occurring before the request reaches our infrastructure. In these cases, we recommend investigating client-side factors, particularly connection pool configuration.
Use this when you observe high latency under load, but requests ultimately succeed and our server-side metrics for your tenant look normal.
Most HTTP client libraries pool and reuse network connections. Under high volume, if the pool is too small or misconfigured, new requests queue up waiting for a free connection. That wait is counted as "latency" by your application even though the request hasn't left your machine yet.
Symptoms and indicators:
Symptom: you see multi-second latencies, but the server reports normal (low-millisecond) response times.
Mechanism: all connections in the pool are busy, so new requests block until one frees up.
Why it's hard to correlate: the wait happens inside your HTTP client, before the request is sent, so it never appears in our server-side metrics.
1. HTTP client library
Identify the library and version (Apache HttpClient, OkHttp, Java HttpURLConnection, Python requests, Node.js http/https, etc.).
Check your HTTP client's connection pool settings. These configurations are a common source of latency under high load, so ensure they are tuned appropriately—specifically reviewing settings for maximum total connections, maximum connections per host, and connection wait times.
2. Client configuration
Connection pool sizing: maximum total connections and maximum connections per host (limiting connections per host is a common point of contention).
Timeouts: connection timeout, socket/read timeout, and — critically — the connection request timeout (how long a request waits for a connection from the pool). A connection request timeout of 5–10s is a common explanation for 5–10s "latencies."
Reuse a single, shared client instance; creating new clients per request adds significant overhead and creates redundant connection pools.
3. Architecture & load pattern
How many processes/threads/instances generate this traffic.
Whether calls are synchronous (blocking) or asynchronous.
Your approximate request rate (requests/second), and whether requests go out sequentially or in parallel.
Identify all services and infrastructure—such as proxies, API gateways, or other middleware—that interact with or generate this traffic. Examine each of these components for potential bottlenecks, verifying that HTTP connections and connection pooling are tuned appropriately for each hop in the request chain.
4. How you're measuring latency
Time from the moment you call the client method (execute(), send(), etc.) to when the response returns. If timing this way, you're including connection pool queuing time.
Or are you measuring actual network time (request leaves your system → response arrives)? This distinction is critical to interpreting your numbers.
5. Connection management
Confirm connection pool reuse is enabled and connections are reused rather than recreated per request.
Ensure clients/connections are properly closed/disposed.
If your library exposes it, instrument connection pool metrics: active connections vs. max, queue depth, and time spent waiting for a connection. These directly reveal pool exhaustion.
Right-size the connection pool. As a rule of thumb, provision 2–3× your concurrent request rate in available connections. Default pool sizes are frequently too small for high-volume sending.
Check timeout configuration. Make sure the connection request timeout isn't causing excessive queuing (or premature timeouts). Set socket/read timeouts sensibly.
Monitor pool metrics (active vs. max connections, queue depth, wait time). This is the fastest way to confirm exhaustion rather than guess.
Consider an async / non-blocking client for high volume, so threads aren't blocked holding connections while waiting.
Reuse client instances. Each HTTP client instance typically maintains its own connection pool; creating new clients per request defeats pooling entirely.
Test with a much larger pool (e.g. 100+ connections per route). If latency drops, connection pool exhaustion is confirmed as the root cause.
Another common cause for latency issues is often due to issues with the implementation architecture resulting in all or most traffic being sent to the API targeting the same user.
The MCP backend is heavily optimized for processing realtime traffic and will route all events for the same user to the same backend service instances. We have observed cases where an implementation might send ALL traffic using a common shared user id which results in traffic routing “hotspots”.
Examine the distribution of user ids and ensure you are not sending all traffic using a common shared user identifier.
Are requests succeeding (200) but slow? → client-side (this playbook). Getting 429/503/403? → see Limits.
Are you timing from the client method call (includes pool queuing) or true network time?
Is your per-host connection cap ≥ 2–3× your concurrent request rate?
Is your connection request timeout in the same ballpark as the latencies you see (e.g. 5–10s)?
Are you reusing a single shared client instance?
Have you instrumented your HTTP client connection pool metrics (active/max/queue depth/wait time)?
Does temporarily raising the pool size reduce latency?
If, after working through the Troubleshooting Guide, you still believe the latency is server-side, open a support case and include:
The endpoint (/event or /authevent) and your account/dataset.
A time window (with timezone) when the latency occurred.
Your measured latency and how you measured it (client method call vs. network time).
Your request rate and connection pool configuration (max total, max per host, connection-request timeout).
Any 429 / 503 / 403 responses you observed, with timestamps.
We can then pull our per-tenant server-side latency for that window and confirm whether the elevated time is on our side or ahead of us. In the cases we've investigated, when our per-tenant server-side latency is normal and no other tenants report similar issues, the cause has typically been on the client side — most often connection pool configuration.
005459127

We use three kinds of cookies on our websites: required, functional, and advertising. You can choose whether functional and advertising cookies apply. Click on the different cookie categories to find out more about each category and to change the default settings.
Privacy Statement
Required cookies are necessary for basic website functionality. Some examples include: session cookies needed to transmit the website, authentication cookies, and security cookies.
Functional cookies enhance functions, performance, and services on the website. Some examples include: cookies used to analyze site traffic, cookies used for market research, and cookies used to display advertising that is not directed to a particular individual.
Advertising cookies track activity across websites in order to understand a viewer’s interests, and direct them specific marketing. Some examples include: cookies used for remarketing, or interest-based advertising.