# Limits and defaults

## Protocol limits (`LIMITS`, from `@argala/core`)

| limit                | value   | what it bounds                          |
| -------------------- | ------- | --------------------------------------- |
| `maxRecordBytes`     | 512 KiB | plaintext record, before sealing        |
| `maxCiphertextChars` | 700,000 | base64url ciphertext of one record      |
| `maxOpsPerPush`      | 200     | records in one push                     |
| `maxPushBytes`       | 8 MiB   | one push body                           |
| `maxPullLimit`       | 500     | records in one pull page                |
| `maxLogLimit`        | 1000    | log entries in one page                 |
| `maxBlobBytes`       | 25 MiB  | one blob                                |
| `maxKindChars`       | 64      | a `kind` metadata value                 |
| `maxShardChars`      | 64      | a `shard` metadata value                |
| `maxRevSkewMs`       | 5 min   | how far ahead a revision may be stamped |

A relay may be configured with stricter limits. It may never be looser: a
client that respects these must never be rejected for it.

## Engine defaults

| option              | default                                   |
| ------------------- | ----------------------------------------- |
| `autoGrant`         | `true`                                    |
| `sign`              | `true`                                    |
| `requireSignatures` | `true`                                    |
| `pushDebounceMs`    | `250`                                     |
| `persistStorage`    | `true`                                    |
| `linking`           | `'observe'`                               |
| `popPins`           | `true`                                    |
| `verifyLog`         | `true`                                    |
| `checkpointEveryMs` | `300_000`                                 |
| `retry`             | `{attempts: 4, baseMs: 250, maxMs: 8000}` |
| `startAutoSync`     | `30_000` when called with no argument     |
| `metadata`          | none — partial sync is opt-in             |

## What it costs

Measured with `npm run argala:bench` and `npm run argala:bench:client` at 20,000 records.
Both scripts assert a bound, so a change in complexity fails the build.

|                              | per record | what it is                                          |
| ---------------------------- | ---------- | --------------------------------------------------- |
| write (queue locally)        | ~19µs      | a store write; the app never waits for more         |
| write (push)                 | ~560µs     | canonical JSON + one ECDSA signature + one AES seal |
| receive (pull)               | ~510µs     | one AES open + one ECDSA verification               |
| relay push, 200 records      | ~3ms       | flat from an empty graph to 100,000                 |
| relay pull page, 500 records | ~5ms       | flat                                                |

The overhead is negligible in interactive use. A bulk import of a hundred
thousand records takes a minute, not a moment.

---
