Reference
Service limits & data freshness
What the Service commits to, what it measures, and what your app should expect when a limit applies. Where the Terms of Service refer to the Documentation for usage limits, or for what the SDK keeps on a device, this is the page they mean.
Pharen never samples the data it receives. The only sampling is sampling you configure.
Availability
There is no availability commitment or service-level agreement: the Terms make no uptime representation. We communicate incidents and material operational changes to the contact on your account.
Availability is measured all the same, from outside the platform:
- Every five minutes, an external monitor sends
GET /readyto each of the two hosts:ingest.pharen.ai, where the SDK sends data, andapi.pharen.ai, which answers the console and the CLI and serves the hosted pages. - A check is up when it answers
200within the monitor's timeout./readyanswers503when the Service cannot reach its database, so the address, the routing, the process and its database are all counted. - A host's availability for a month is its up checks over all its checks, to two decimal places. An outage shorter than one five-minute interval may go unrecorded, and a longer one is counted to the nearest five minutes.
- The monitor does not check certificates. Certificates are checked separately, every week.
Measurement began in October 2026. A month nobody measured is never counted as a month at 100%.
Data freshness
Pharen doesn't commit to how long data takes to reach the console or a query after the app records it. What sets the pace on the device is the SDK. In the current iOS SDK:
- While the app runs, the SDK attempts a batch every
flushIntervalSeconds(30 by default), and again each time the app moves to the background. A batch carries up toflushBatchSizeevents (50 by default) or 1 MB of encoded events, whichever it reaches first. - A fatal crash is written to disk when it happens and sent on the app's next launch, so it arrives only once the app is opened again, within the crash-report limits under On the device.
- An offline device sends what it holds when it is back online. A batch waiting out a rate limit or a hold arrives later than it would have.
How often the SDK sends is SDK behaviour, not a commitment, and it can change between SDK releases; each release's notes say what it does.
Rate limits
Each limit is a budget that refills continuously and allows short bursts. A request over its budget is refused with 429 and an error code; where the response carries Retry-After, it is the number of whole seconds to wait before trying again.
| What is limited | The budget belongs to | Refused with |
|---|---|---|
| Requests the SDK makes with an ingest key, such as event batches, identity and configuration | The app and environment the key names. A batch costs one unit per event it carries | 429 rate.limited, with Retry-After |
| Queries from a query key or a signed-in person, including over MCP | The app and environment queried (the environment, for a lookup across apps), shared by every key and person querying it | 429 ratelimit.exceeded, with Retry-After |
| Requests with a publishable key (the report page and widget) | The key, as a share of the app's budget, and on top of it each network address | 429 ratelimit.key, with Retry-After; or ratelimit.ip, without it |
| Sign-in, onboarding, install pages and the hosted report page | Each network address | 429, without Retry-After |
| Creating or changing a link whose destination the Service screens | Your workspace | 429 rate.limited, with Retry-After |
Diagnostic uploads also count against a storage quota for each app and for your workspace; an upload past it is refused with 429 diagnostics.quota_exceeded, without Retry-After, until older bundles age out.
The iOS SDK handles a 429 for you: the events stay queued, the next attempt waits as long as Retry-After says, and no event is given up after a number of attempts. A rate limit never drops data by itself; only a queue that fills while it waits does, as On the device describes.
Your own code calling the API should do the same: wait out Retry-After where it is present, and back off where it is not. If your app needs more than its budget allows, write to [email protected].
How long data is kept
The windows the Service applies to each kind of data are listed in Privacy & consent.
On the device
Until the Service accepts it, data waits on the device, within these limits:
- The event queue holds
maxQueueDepthevents (10,000 by default; you set it). Past that, room is made by dropping the oldest event your own instrumentation recorded — tracked events, screens, timings — and only once none of those is left the oldest of the SDK's core events: the session boundary, crashes, errors and hangs, identity, and what a person sent. Detail goes before sessions. - A crash report is kept until the Service confirms an outcome for it, with no age limit. A device sends the first five crash reports of each build, then one a day, and an app that crashes at every launch reports the first, third, tenth and thirtieth crash of the run; each report held back is deleted once it is counted onto the next one sent, so the crash count stays exact.
- On iOS, diagnostic bundles waiting to upload are limited to 5 bundles and 25 MB in total, and are deleted after 30 days; past the count or size limit, the oldest goes first. A reporter's contact address waiting to send is limited to 20 records and 30 days.
Data that exists only on a device is lost if the app is removed or its data is cleared, and never arrives from a device that is lost or never runs the app again. Privacy & consent lists what the SDK keeps on the device for other reasons.
During a limit hold
When use in a period reaches your plan's allowances (or a trial's), the Service holds further data until the hold ends, as the Terms describe: for example, when the allowances are raised or the next period begins. During the hold the Service keeps accepting crash reports, hangs that ended the app, and what people submit under the content purpose, and events in your development and staging environments up to the allowance your plan includes for them; the environment comes from the key a build carries, not from the build itself.
The Service tells the SDK to hold what it sends until the limit lifts. The SDK goes on sending, on its ordinary schedule — after any backoff an earlier refusal armed, five minutes at most — crash reports, a hang that ended the app, and everything a person sent — feedback reports and survey answers. Everything else it records waits on the device, within the limits above, in the order it was recorded, and is sent when the hold ends. Until a device has received the hold, an event the Service refuses for now waits at the head of the queue and the events recorded after it wait with it, up to the device's next configuration refresh; crash reports have an upload of their own and never wait behind it.
While your workspace is suspended
The Service tells the SDK that ingestion is suspended. The SDK keeps what it records on the device, within the limits above, and sends it once service is restored; nothing is discarded because of the suspension. Data a person asks to have deleted, such as on a withdrawal of consent, is still deleted.
When your agreement ends
The Service stops accepting data from your apps, and anything the SDK still holds on a device is never delivered. The SDK is designed to handle that refusal internally: it does not crash your app, shows nothing to your users, and does not stop your app from working. It keeps collecting within the limits above and retries on a backoff. One cost remains: if a crash report is waiting when the app starts, each launch still spends the SDK's startup wait for crash reports (2 seconds by default) on an upload the Service refuses. To stop all of this, ship an update without the SDK before your agreement ends. An update reaches only the devices that install it; installs that never update keep running the SDK as described here.
An account with no plan
When a trial ends without a plan, or a plan ends on a notice that ended only the plan, the agreement continues but the Service accepts no new data from your apps. The SDK goes on recording, and each event it sends is refused and deleted from the device, so none of it arrives later, even if the account takes a plan. Where no paid term is in effect, the Terms let either side end the agreement on 15 days' written notice. We ordinarily give that notice once 90 days have passed since the trial or plan ended or, for an account that was not offered a trial and has never had a plan, since it was created. An account whose trial has not yet begun has no set period.