Akter

CLI

The akter command comes from @rikalabs/akter-cli. Install it at the same version as @rikalabs/akter, and run it with bunx akter or npx akter. akter --help and akter <command> --help list every flag.

CommandWhat it does
akter devRuns your app locally
akter storage checkChecks that a bucket works with Akter
akter inspect, log, snapshot, replay, retentionOperator requests to a running server
akter forkCopies an actor's history into a new actor

akter dev⁠

Terminal
bunx akter dev

Imports src/app.ts, which must default-export an App.make(...), and serves it on 127.0.0.1:8080 with a filesystem store in .akter/store.

FlagDefaultMeaning
--entrysrc/app.tsThe app module
--dir.akter/storeThe store directory
--port8080The port
--devtoolsoffSends traces to Effect DevTools
--devtools-urlws://localhost:34437Where DevTools listens

Every request is anonymous, so actors need an access function that admits Anonymous callers while you develop. /metrics is on. If AKTER_OPERATOR_TOKEN is set, the operator endpoint is on too, and that token can inspect, read logs, snapshots, outcomes and audits, and replay.

akter storage check⁠

Terminal
bunx akter storage check --bucket my-app-production --endpoint https://s3.example.com --region auto
bunx akter storage check --directory .akter/store

Runs seven probes against a bucket or a directory, and prints each result with what it measured:

  1. Conditional create race. Concurrent writes with If-None-Match produce exactly one winner.
  2. Compare-and-swap race. Concurrent writes with If-Match produce at most one winner.
  3. List after write. A new key is listed right away, and a deleted key isn't.
  4. Ordered listing. Keys list in byte order and page correctly.
  5. Overwrite refreshes last-modified. Rewriting the same bytes moves the timestamp forward.
  6. Per-key write rate. Rapid writes to one key succeed or are throttled, and never fail any other way.
  7. Batch delete. One multi-key delete removes every key.
FlagDefaultMeaning
--bucketThe bucket to check
--endpointThe S3 endpoint, for providers other than AWS
--regionThe bucket's region
--prefixA key prefix inside the bucket
--directoryCheck a directory instead of a bucket
--writers16Concurrent writers in each race
--rounds10Rounds of each race and of the listing probe
--writes10Back-to-back writes in the write-rate probe
--settle-ms2000Wait between the two writes of the last-modified probe
--jsonoffPrints one JSON document

Credentials come only from the environment: AKTER_STORAGE_ACCESS_KEY_ID, AKTER_STORAGE_SECRET_ACCESS_KEY and AKTER_STORAGE_SESSION_TOKEN, or the matching AWS_* variables. The bucket, endpoint, region and prefix can also come from AKTER_STORAGE_BUCKET, AKTER_STORAGE_ENDPOINT, AKTER_STORAGE_REGION and AKTER_STORAGE_PREFIX.

The check writes only under check/<run>/ and deletes what it wrote. It ends with Passed: all 7 probes. or names the probes that failed.

Operator commands⁠

These send requests to a running server's /operator endpoint, which is on only when the server has operatorAuth. Each needs a capability in the operator's grant.

CommandCapabilityShows or does
akter inspect actor <Type> <id>inspectAn actor's stored state, lists and pending work
akter inspect shard <n>inspectA shard's log position, checkpoints and owner
akter log tail <shard> [--from <offset>] [--follow]log.readThe shard's recorded commands
akter log export <shard> [--from <offset>]log.readThe same, as NDJSON
akter snapshot <shard>snapshot.readThe shard's latest checkpoint and pages
akter replay <shard> [--current]replayReplays a shard; --current uses the running build
akter retention <duration>retention.setSets how long the store keeps history

Reading stored replies and errors also needs outcomes.read.

FlagDefaultMeaning
--urlhttp://127.0.0.1:8080The server
--tenantdefaultThe tenant
--reasonoperator inspectionWhy, recorded in the audit log
--token-envAKTER_OPERATOR_TOKENThe environment variable holding the token

The URL must be HTTPS, except on localhost. For an actor whose id isn't a string, pass --id-json and give the id as JSON.

akter fork⁠

Terminal
akter fork Room lobby --at 120 --to lobby-copy --directory .akter/store
akter fork Room lobby --before 2026-10-12T18:00:00Z --bucket my-app-production --to-prefix forks/

Copies the actor lobby as it was at an earlier point into a new actor. It works on the store directly rather than through a server, so it loads your app module (--app, default src/app.ts). That module must default-export the app and export an authorizeOperator(token) function that returns an Effect of the operator's grant, which needs the fork capability.

Choose the source with --directory, or --bucket with optional --prefix and --endpoint. Choose the point in history with one of:

FlagPoint
--at <n>After the actor's first n commands
--before <timestamp>Just before an ISO timestamp
--offset <n> --index <i>A position in the shard's log

--to names the new actor; --to-directory and --to-prefix write it to another store. --with-work also copies pending timers and open jobs. A fork doesn't copy presence or pending sends.

The point must still be inside the store's history retention.

Exit codes⁠

CodeMeaning
0Success, or help and version output
1The server refused the request, or a storage probe failed
2Bad arguments, missing credentials, an app that won't load, or an unreachable endpoint