Skip to main content
Empirical gives every project a key-value store. Tests, shards of the same run, later test runs and Empirical’s agents all read and write the same entries, so you can hand data from one place to another without a database of your own. Every entry expires, so the store cleans up after itself. Conditional writes let parallel shards coordinate safely: only one of them can create a key, and a write can be made to apply only if nothing changed since you read it. All test repositories managed by Empirical have this built-in — no additional setup is required.

When to use it

  • Verify background work in a later run. A test that triggers a slow job (an analytics import, a nightly export) can record what it started and exit. A test in the next run reads the key and checks the result, instead of waiting minutes inside one test.
  • Share data between tests and shards. Store an ID, a token or a URL created by one test and read it from another, even on a different shard.
  • Coordinate parallel work. Playwright’s lock option holds across shards on Empirical. For anything else, use a conditional write to make sure only one shard sets something up, or to hold a short lease on a shared resource.
  • Track resources to clean up. Record environments or accounts your tests create, with an expiry, so a later test or agent can find and remove them.

Usage

Read and write values

Use the kv fixture in tests, or KVClient anywhere else. ttl is required and is in seconds.

Check on work from a previous run

entries iterates every entry under a key prefix, across pages.

Conditional writes

set takes ifAbsent to write only when the key does not exist, or ifVersion to write only when the entry has not changed since you read it. When the condition fails, set throws KvPreconditionFailedError, and its current property holds the entry as it is now. For example, to let only one shard seed shared data:
Every write increases the entry’s version, and every write returns the new entry. Pass its version to set, refresh or delete to act only if no one else has written since:

Methods

Locks across shards

Playwright’s test locks keep tests that share a lock name from running at the same time, but only within one shard. On Empirical, the same lock option also holds across every shard of a test run, with no code changes:
Each locked test holds a short lease in the KV store while it runs, renews it until the test finishes, and releases it afterwards. If a shard dies, its lease expires within a minute. Time a test spent waiting shows up in the test report as a lock annotation. Locks are scoped to one test run: two separate runs do not wait for each other. Cross-shard locks need Playwright 1.63 or later and the @empiricalrun/playwright-utils fixtures.

Keys, values and limits

Use : to namespace keys, for example exports:pending:42, so related entries share a prefix you can list. Entries are scoped to your project; values are visible to anyone with access to it, so do not store secrets.

API

The store is also available over the Empirical API under /api/kv, for scripts, CI jobs and agents: list, get, put, refresh and delete, with If-None-Match: * and If-Match: <version> for conditional writes.