Skip to content
Scalpels home

Scalpels is officially launching on October 31, 2026. Special early adopter pricing is available now.

← All documentation

Documentation

Assay

Configuration

Updated

Assay works with no configuration beyond what the install writes. Everything on this page is optional tuning. Server settings are environment variables on your Assay environment in Laravel Cloud; change them there and redeploy. Settings for the applications that report to Assay live in those applications; see Connecting your apps and Capturing content.

Assay has no settings screen. In-app administration is limited to members, sessions and installation credentials under Settings, and content access overrides at /assay/access.

Values Scalpels and Laravel Cloud manage

Value Managed by What it does
ASSAY_ERASURE_KEY Scalpels, generated once at install The dedicated key for erasure tombstones and subject lookups. Separate from APP_KEY. Never replace or remove it: every past erasure depends on it, and Assay refuses subject-bearing telemetry without a valid key.
Database, queue and storage settings Laravel Cloud Injected for the Postgres database, managed queue and bucket the install attached. Do not add variables that shadow them.

The erasure journal is written to the application's default filesystem disk under the assay/erasures prefix. On Laravel Cloud that is the bucket the install attached, so the journal survives deploys and database restores.

Retention

Variable Default Effect
ASSAY_RUN_CONTENT_RETENTION_DAYS 30 Days captured run content is kept.
ASSAY_USAGE_RETENTION_DAYS 395 Days usage metadata is kept.
ASSAY_DATASET_RETENTION_DAYS 365 The default lifetime of a dataset item, counted from when it was added. Set no-expiry to make the default no expiry. A dataset can still choose its own retention when it is created.
ASSAY_QUEUE_FAILED_RETENTION_HOURS 72 Hours the encrypted residue of failed ingest jobs is kept. It is never kept longer than run content.
ASSAY_RETENTION_BATCH_SIZE 1000 Rows deleted per batch by the daily pruning job.

Retention pruning runs daily at 02:00. Shortening a period takes effect at the next run.

Ingest limits

Variable Default Effect
ASSAY_INGEST_MAX_BODY_BYTES 8388608 (8 MiB) Largest request body Assay accepts.
ASSAY_INGEST_MAX_RECORDS 500 Most records in one batch.
ASSAY_INGEST_MAX_SOURCES 16 Most sources in one batch.
ASSAY_INGEST_QUEUE Cloud's default queue connection The queue connection accepted batches are processed on.

The client splits a batch and retries when Assay rejects it as too large, so you rarely need to change these. If you lower ASSAY_INGEST_MAX_RECORDS, keep each client's ASSAY_BATCH_SIZE at or below it.

Run reconciliation

Variable Default Effect
ASSAY_STALE_AFTER_MINUTES 30 Minutes after first receipt before a run with no final record is marked incomplete (or failed_or_lost for a non-agent operation). The same window decides how long content sent for a record that has not arrived yet is held before it is dropped.
ASSAY_STALE_BATCH_SIZE 1000 Runs reconciled per scheduler pass.
ASSAY_CONTENT_ATTACH_BATCH_SIZE 1000 Held content records reconciled per scheduler pass.
ASSAY_ERASURE_BATCH_SIZE 1000 Rows deleted per batch during a subject erasure.

Scheduled work

The install enables Laravel Cloud's scheduler, which runs:

Command When What it does
assay:reconcile-stale-runs Every minute Marks runs that never finished.
assay:reconcile-content-attaches Every minute Applies held content whose target record has arrived and drops expired orphans.
assay:queue:prune-residue Every minute Prunes encrypted failed-job residue past its limit.
assay:retention:prune Daily at 02:00 Applies the retention periods above.

Each command can also be run by hand inside the Assay environment to check it. Assay's maintenance commands act on the environment they run in; they have no --local switch and no remote mode.