Delivery and offline
Batching, retries, the offline queue, and settings fetched from the dashboard.
Batching
Logs wait in memory and go out together in one request to POST /{projectId}/logs/batch. A batch is sent:
- as soon as
batchSizelogs are waiting (default 10); - every
flushIntervalMs(default 5,000 ms); - when you call
await logger.flush(); - when the visitor leaves or hides the page.
At most 1,000 logs wait at once; beyond that the oldest are dropped, with a console warning. Two logs with the same message and the same timestamp in one batch are sent once.
The API takes 100 logs per request
batchSize at 100 or less. If Apperio can’t be reached for a while and more than 100 logs pile up, every later flush is refused too, and nothing more from that page arrives.Retries
- If a request fails with a network error or a 5xx response, the SDK tries again, up to
maxRetriesmore times (default 3). - It waits
retryDelayMsbefore the first retry (default 1,000 ms) and doubles the wait each time, with a little random jitter, up to 60 seconds. - A 4xx response, such as 401, 403, 400 or 429, isn’t retried: it would fail the same way.
- If every attempt fails, or the request was refused, the logs go back to the front of the queue and the next flush tries again.
While this happens you see messages such as Apperio: Network error on attempt 1 in the console.
When the visitor leaves
A normal request is cancelled when the page unloads. So when the page is hidden or unloaded, the SDK sends what is waiting with keepalive, which the browser finishes in the background. Browsers cap these requests, so up to about 40 KB of logs go that way and anything beyond in a normal request, as a best effort. There are no retries at this point. This needs no code from you.
Offline queue
In a browser, when the device goes offline, new logs go to a separate queue instead of being sent. When the connection comes back, the queue is sent in one request. It is on by default and only uses memory, so a queue is lost if the tab closes.
import { Apperio } from 'apperio';
const logger = new Apperio({
apiKey: 'your-api-key',
projectId: 'your-project-id',
offline: {
maxQueueSize: 100,
prioritizeCritical: true,
onOffline: () => console.info('Offline: holding logs'),
onOnline: () => console.info('Back online'),
onSyncComplete: (count) => console.info(`Sent ${count} queued logs`),
},
});| Option | Default | What it does |
|---|---|---|
maxQueueSize | 500 | Most logs held while offline. |
prioritizeCritical | true | When the queue is full, drop the oldest log that isn’t an error or fatal first. Otherwise drop the oldest. |
onOffline, onOnline | none | Called when the browser goes offline or comes back. |
onSyncComplete | none | Called with the number of queued logs sent after reconnecting. |
Set maxQueueSize to 100 or less
Remote config
Off by default. Turn it on to let Settings › SDK Config in the dashboard adjust a running SDK:
import { Apperio } from 'apperio';
const logger = new Apperio({
apiKey: 'your-api-key',
projectId: 'your-project-id',
remoteConfig: {
enabled: true,
refreshIntervalMs: 300000, // default: every 5 minutes
onConfigUpdate: (config) => console.info('Apperio settings updated', config),
},
});The SDK fetches the settings when it starts and then on every interval. Once fetched, these replace the values in your code:
- Minimum Log Level
- Batch Size and Flush Interval
- the sanitization preset (Strict Mode)
The preset replaces any sanitization settings you passed in code, including custom rules. Everything else on that page, such as environment, service name, the auto-capture switches, and the sensitive fields and custom rules you enter there, doesn’t change a running SDK. Set those in code.
Other exports
The package also exports CircuitBreaker, compressPayload and HealthMetricsCollector. The Apperio class doesn’t use them when sending logs, and you don’t need them to use Apperio, so they aren’t covered here. AutoInstrumentation and BreadcrumbManager are exported too; the logger creates and manages them for you. See Configuration for everything the logger itself supports.