Antfly Lite
How the embedded single-file profile of Antfly works, what it shares with a normal instance, and how data moves between the two
- Antfly CLI built or installed
Antfly Lite is Antfly in one file. Documents, schemas, indexes, enrichments, and query-visible artifacts live in a local .aflite database that an application opens directly, with no server process. Choose Lite for development, desktop apps, edge workers, tests, and single-user deployments. Choose a normal instance when you need replication, shard placement, multi-node scaling, or cluster metadata. Everything else, from the index model to the query API, is the same code.
antfly lite init app.aflite
antfly lite status app.aflite
init refuses to overwrite an existing path. status reports the storage identity and the inference state:
{
"storage": {
"format": "aflite",
"engine": "native_single_file",
"format_version": 2
},
"inference": {
"mode": "caller_supplied_or_disabled",
"available_modes": [
"caller_supplied_artifacts",
"remote_provider",
"disabled_deferred"
],
"configured": false,
"no_inference_configured_ok": true
}
}
Two File Types, Two Jobs
| Extension | What it is | Use it for |
|---|---|---|
.aflite | The live embedded database | The file your application opens |
.afb | An Antfly Backup Bundle | Archival retention, object-storage uploads, repeatable migrations, restoring into a normal instance |
An .afb bundle's manifest names its representation: portable (logical records) or native (physical generations). Lite writes and reads the portable representation; a normal instance can also package native generations in the same envelope. AFB1 portable archives remain readable, and new bundles use AFB2, which declares the representation explicitly. The Lite backup and export commands emit a self-contained full bundle. AFB2 also defines delta bundles against an exact base for incremental repository workflows; a delta is never treated as a self-contained archive.
Never treat .aflite as the backup format. A normal Antfly can restore directly from one, but that is a convenience for promotion, not an archive. The .aflite open path accepts the documented native single-file format and fails explicitly on unknown versions or invalid headers; pre-release directory and LSM-container experiments are not read. To keep one of those, export it with the matching development build and restore the resulting portable AFB1 or AFB2 bundle.
Writes, Reads, and Indexes
Requests are the same JSON shapes as the normal API, passed as files. A batch write:
{
"inserts": {
"doc:lite:1": {
"title": "Local Antfly",
"body": "Antfly Lite stores this document in app.aflite."
}
},
"sync_level": "full_index"
}
antfly lite batch app.aflite --file writes.json
antfly lite lookup app.aflite --key doc:lite:1
A key-range scan (scan.json):
{
"from": "doc:",
"to": "doc;",
"include_documents": true,
"limit": 10
}
antfly lite scan app.aflite --file scan.json
Indexes use the same logical model as a normal instance. A full-text index (full-text-index.json):
{
"name": "body_text",
"kind": "full_text",
"config_json": "{\"fields\":[\"title\",\"body\"]}"
}
antfly lite index create app.aflite --file full-text-index.json
antfly lite run-until-idle app.aflite
A query against it (query.json). Note that the antfly lite CLI's query JSON
takes a nested match: {field, text} object here, unlike the public /db/v1
API's flat match: {match: string, field: string} shape used elsewhere in the
docs:
{
"full_text_search": {
"match": {
"field": "body",
"text": "local antfly"
}
},
"limit": 5
}
antfly lite query app.aflite --file query.json
Dense vector, sparse vector, graph, schema, and enrichment catalog operations are all available through the same antfly lite CLI and the embedded APIs.
Inference Is Optional
A Lite database with no inference configured is a complete, healthy state. It can store caller-supplied embeddings and sparse vectors, index and query them, hold enrichment definitions, and report through status whether inference-backed work is possible. A fresh database reports configured: false with no_inference_configured_ok: true.
The mode in the status inference block tells an application which path it is on:
| Mode | Meaning |
|---|---|
caller_supplied_artifacts | The application writes embeddings, sparse vectors, assets, chunks, and graph edges itself |
remote_provider | Lite calls an inference provider the application configured at open time |
local_embedded | A full build ships an embedded inference runtime |
manual_maintenance | A hosted profile exposes pending work for the application to drain with run-until-idle |
disabled_deferred | Definitions and documents are stored; model-backed work waits until a runtime is available |
Applications that configure a remote provider or embed a local runtime mark it at open time. Status then reports configured: true with remote_provider_configured: true or local_runtime_configured: true and local_runtime_available: true, so bindings branch on status rather than on enrichment failures. The capabilities block also carries retrieval flags (text_search, dense_vector_search, sparse_vector_search, hybrid_search, graph_search, caller_supplied_embeddings) for the same purpose.
antfly lite run-until-idle app.aflite drains whatever local maintenance work is available. Run it after writes and before a query or a backup when you want that work reflected.
The Same API Over HTTP
For SDKs and local tools, Lite serves the full standalone API:
antfly lite serve app.aflite --addr 127.0.0.1:8080
curl http://127.0.0.1:8080/db/v1/status
This is the same runtime as antfly standalone --storage-engine lite --storage-path app.aflite; lite serve is a shorter spelling, not a separate protocol. It accepts loopback hosts (127.0.0.1, localhost, ::1). For a non-loopback production listener, use the standalone command.
Backups, Snapshots, and Imports
antfly lite backup app.aflite --out app.afb # export is an alias
antfly lite restore app.afb --out restored.aflite
antfly lite snapshot app.aflite --out copy.aflite
backup writes a self-contained AFB2 bundle with the portable representation. Its manifest maps logical records to unique content digests, and a fixed trailer locates the digest index so a restore runs in bounded memory. A delta bundle, when a repository or export workflow supplies one, names the exact base-manifest digest it depends on and fails closed if that base is unavailable. restore creates a new Lite database from a bundle. snapshot copies a stable live checkpoint of the .aflite file itself, which is the right tool for local copies, test fixtures, and handing a database to another Lite application.
import loads a portable AFB1 or AFB2 bundle into a database that already exists:
antfly lite init empty.aflite
antfly lite import empty.aflite --from app.afb
antfly lite import restored.aflite --from app.afb --replace
--replace is required when the target holds data. Importing from another .aflite is a physical snapshot replacement, never a logical merge.
Moving Between Lite and a Normal Instance
Both directions are logical backup and restore. The portable stream carries documents and keys, schemas, index definitions, enrichment definitions and persisted state, caller-supplied vectors and artifacts that are already query-visible, and enough metadata to rebuild query-visible indexes. Storage-engine files (text indexes, dense vector segments, sparse postings, graph reverse indexes, checkpoints, free-space metadata) are rebuilt on the target, not copied.
Lite into a running instance. promote opens the .aflite read-only, stages a portable backup, restores it into the target table, and leaves the Lite file in place:
antfly lite promote app.aflite \
--target http://127.0.0.1:8080 \
--table docs \
--connection archive-writer \
--location file:///tmp/antfly_backups
antfly restore --input app.aflite --table docs --connection archive-writer --location file:///tmp/antfly_backups --url http://127.0.0.1:8080 does the same thing through the normal restore command. Either way --connection and --location are required: the target server reads the staged backup through that named connection, from a shared file://, s3://, or gs:// location it can reach. For a repeatable release or disaster-recovery workflow, make the .afb explicit first:
antfly lite backup app.aflite --out app.afb
antfly restore \
--input app.afb \
--table docs \
--connection archive-writer \
--location file:///tmp/antfly_backups \
--url http://127.0.0.1:8080
A normal instance into Lite. Back up the table with --format portable (Lite cannot read a native bundle), then restore or import it:
antfly backup \
--table docs \
--backup-id docs-export \
--connection archive-writer \
--format portable \
--out docs.afb \
--location file:///tmp/antfly_backups \
--url http://127.0.0.1:8080
antfly lite restore docs.afb --out docs.aflite
Lite is a single-node, single-shard source, so restoring into a normal instance maps it into the target table's placement model, and restoring the other way collapses the selected table into one file. This is how you build fixture databases, debug a production slice locally, or ship a seeded embedded application.
After either direction, drain and verify on the Lite side:
antfly lite status docs.aflite
antfly lite run-until-idle docs.aflite
antfly lite check docs.aflite
On a normal target, use its status and restore verification. The migration is complete when pending index and enrichment maintenance is drained or explicitly deferred. Caller-supplied artifacts arrive as stored data and stay queryable; deferred model-backed work stays pending until a runtime is available on the destination. Run run-until-idle before taking a migration backup when you want all locally available maintenance reflected in it.
Embedding Lite in Zig and Go
Zig applications use the antfly-embedded package. db.DB.createLite makes a native .aflite, db.DB.openLite opens one, and package-level helpers inspect and snapshot files without a DB handle:
const antfly = @import("antfly-embedded");
var db = try antfly.db.DB.createLite(allocator, "zig-app.aflite", .{});
defer db.close();
const report = try antfly.db.checkLiteFile(allocator, "zig-app.aflite");
_ = report.valid;
_ = try antfly.db.copyStableLiteSnapshotFile(
allocator,
"zig-app.aflite",
"zig-copy.aflite",
false,
);
antfly.api.checkLiteFileJson and antfly.api.copyStableLiteSnapshotFileJson return the same JSON reports the CLI and C ABI expose.
Go is the first binding above Zig and C:
go get github.com/antflydb/antfly/go/pkg/antflylite
package main
import (
"log"
"github.com/antflydb/antfly/go/pkg/antflylite"
)
func main() {
db, err := antflylite.Create("go-app.aflite")
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Batch([]antflylite.WriteIntent{{
Key: "doc:go:1",
Value: []byte(`{"title":"embedded go lite"}`),
}}, 1)
if err != nil {
log.Fatal(err)
}
status, err := db.StatusJSON()
if err != nil {
log.Fatal(err)
}
log.Printf("%s", status)
}
Create is the explicit first-use path; Open takes an existing file and never creates or upgrades one. Constants such as antflylite.InferenceModeCallerSuppliedArtifacts and antflylite.InferenceModeDisabledDeferred let you branch on status without hard-coding strings. Building from the source tree means building the C ABI first (see below, then go test -tags antflylite_capi ./... in go/pkg/antflylite). Two runnable templates live in the repository: examples/antfly-lite-go (create, write, lookup, status, backup) and examples/antfly-lite-retrieval-go (schema, full-text and dense indexes with caller-supplied embeddings, hybrid search, backup). Both are gated by zig build lite-test against the built libantfly.
Building from Source
From the zig directory, zig build lite installs the Lite-only CLI as zig-out/bin/antfly together with the libantfly library and its C header. It reuses the standalone runtime archives, including the API and inference runtimes that lite serve needs, and runs no tests. For the full Antfly CLI with the Lite commands and the C library, use the existing targets:
zig build antfly capi
When you embed a local inference runtime, pass -Dlite-local-inference-runtime=true so Lite status and the bindings advertise it; the flag declares the capability and does not package a separate runtime. zig build wasm builds and installs the embedded database and inference WASM bundle, and zig build wasm-test runs its Node smoke test. zig build lite-test runs the Lite backend, CLI, C ABI, Go binding, embedded example, and packaging checks in one pass.
Maintenance
antfly lite check app.aflite # integrity
antfly lite compact app.aflite # compact index work and reclaim space
antfly lite vacuum app.aflite # file-level vacuum only
For a production application, pair regular .afb backups with check.
Use Agent Skills
Everything above is also encoded in the Antfly skill, so a coding agent can execute this guide for you:
npx skills add antflydb/antfly-skills
Then prompt it with the outcome, for example "Embed Antfly Lite in my Go application with a single-file database and a full-text index", and use this page to judge the result.
Next Steps
- Quickstart: the same queries against a normal standalone instance
- Document Engine: how mappings, full-text, vector, and graph indexes compose under one query, in Lite and everywhere else
- Backup and Restore: the
.afbformat and restore options on a normal instance