KiloLock

ci lint go license

Website: kilolock.com Docs: kilolock.dev Cloud: kilolock.cloud

Terraform state without the global lock.

KiloLock is an open-source Terraform/OpenTofu HTTP backend that stores state in PostgreSQL as a normalized graph instead of a flat tfstate blob.

Use it as a drop-in remote backend with vanilla Terraform/OpenTofu today. When your state grows, KiloLock adds queryable state, resource history, repair workflows, and foundations for narrower locking and parallel-safe operations.

Why KiloLock exists

Terraform's standard HTTP backend model treats state as one snapshot: pull, lock, write back. That is simple and compatible, but painful for large shared states where unrelated engineers should not block each other.

KiloLock keeps the compatible HTTP backend path while storing backend state as a graph-aware PostgreSQL model. That enables queryable state, resource-level history, repair workflows, and future resource-aware coordination.

The deeper problem is not only that tfstate files get large. It is that infrastructure often becomes one big coordination problem. Splitting Terraform projects can help, but it can also turn one monolith into a distributed monolith with more pipelines and more fragile dependencies. KiloLock is aimed at that coordination layer.

Usage modes

ModeStatusUse this when
Terraform/OpenTofu HTTP backendStable baselineYou want a drop-in remote backend compatible with vanilla Terraform/OpenTofu. Start here.
KL state engineExperimental / power-user laneYou want sliced state fetches, narrower reservations, native state operations, repair workflows, and large-state collaboration experiments.

If you are new to KiloLock, start with the HTTP backend lane first. You do not need to adopt the KL state engine to get value from the project.

Quick Start: local HTTP backend

Start the local OSS stack:

cp .env.example .env
docker-compose up --build -d

Point Terraform or OpenTofu at KiloLock:

terraform {
  backend "http" {
    address        = "http://localhost:8080/v1/states/example"
    lock_address   = "http://localhost:8080/v1/states/example"
    unlock_address = "http://localhost:8080/v1/states/example"
    lock_method    = "LOCK"
    unlock_method  = "UNLOCK"
  }
}

Then run:

terraform init
terraform apply

Optionally inspect what was written:

make build
export PATH="$(pwd)/bin:$PATH"
kl status example
kl query "SELECT type, COUNT(*) FROM resources GROUP BY type ORDER BY 2 DESC"
kl history example

That local stack is enough for:

  • a normal Terraform/OpenTofu remote backend flow
  • SQL-style inspection of resources and states
  • state history and repair workflows
  • local evaluation before moving to a fuller self-hosted setup

For local docker-compose, use the direct state endpoint for unlocks as shown above. The separate POST /v1/state-unlock/... route is mainly for cloud/managed-edge compatibility where UNLOCK with a body may not be forwarded reliably.

If you want a fuller operator-style setup with klc, bootstrap, and multi-instance routing, use docs/runbooks/self-hosted-bootstrap.md.

What works today

  • Drop-in Terraform/OpenTofu HTTP backend.
  • PostgreSQL-backed normalized state graph.
  • SQL querying across resources and states.
  • Resource history and repair workflows.
  • File-scoped and targeted plan/apply helpers.
  • Provider-aware refresh and drift visibility.
  • Backend-driven quota preview and plan admission checks.
  • Reservations and apply orchestration foundations.
  • Self-hosted control plane for operator workflows.
  • Docker Compose local stack and prod-like self-hosted stack.

Advanced / experimental

The KL state engine is the power-user path. It is where KiloLock experiments with workflows that are not possible with a flat-file backend alone:

  • sliced state fetches
  • narrower graph reservations
  • native exact-address state operations
  • resource-aware repair workflows
  • foundations for parallel-safe operations on large shared state

Examples:

KL_PROTOCOL=state-engine kl state rm example --address time_sleep.slow_b
KL_PROTOCOL=state-engine kl state mv example --from time_sleep.slow_a --to module.demo.time_sleep.slow_a
examples/big-state/state-engine-demo.sh lanes

Treat this lane as evolving. The compatible HTTP backend lane is still the safest place to start.

Components

KiloLock currently ships three main binaries:

  • kl: operator and developer CLI
  • kld: backend/runtime server
  • klc: control-plane server

Build them with:

make build

This produces:

  • ./bin/kl
  • ./bin/kld
  • ./bin/klc

To use the local binaries in your current shell:

export PATH="$(pwd)/bin:$PATH"

KiloLock still executes the real IaC CLI in the background. Terraform must be installed on the machine where you run the examples and CLI workflows in this repo.

State safety and escape hatches

KiloLock is designed to be safe to adopt incrementally:

  • the baseline path is the standard Terraform/OpenTofu HTTP backend protocol
  • raw state is still preserved and served through the backend interface
  • advanced native workflows are separated from the stable backend lane
  • operator-focused repair and rollback commands exist when something goes wrong

Useful examples:

kl status example
kl history example
kl rollback resource --address time_sleep.slow_a --to @1
kl apply abort --state example --latest

Relevant runbooks:

When should I use this?

KiloLock is a good fit when:

  • you want a self-hosted Terraform/OpenTofu backend with more visibility than object storage plus a lock table
  • you want to query state directly instead of treating it as an opaque blob
  • you need resource history, drift visibility, or repair workflows
  • you have a large shared state and want a path toward narrower coordination over time
  • you want to start with a compatible backend now and evaluate more advanced workflows later

What KiloLock is not

KiloLock is not:

  • a replacement for the Terraform or OpenTofu CLI
  • a promise that every advanced large-state workflow is fully stable today
  • a hosted SaaS product inside this OSS repository
  • only an architecture experiment; the baseline backend and operator workflows are usable now

Hosted-business features such as customer portal UX, billing/signup glue, and cloud-specific deployment packaging live outside this OSS repo.

Architecture and docs map

Start here:

For query and operator workflows:

For the experimental state-engine lane:

For deeper implementation history:

Versioning

KiloLock derives its build version automatically from Git tags that match vX.Y.Z.

  • exact tag on HEAD -> X.Y.Z
  • commits after a tag -> next patch prerelease like X.Y.(Z+1)-dev.N
  • no tag yet -> 0.1.0-dev.N

Useful checks:

kl version
kl version --json
kld version --json
curl -s http://localhost:8080/versionz

/versionz is the machine-readable runtime endpoint for the backend service.

Roadmap

Current OSS shape:

  • v0: queryable state
  • v1: provider-aware refresh and drift surfacing
  • v2: scoped/orchestrated apply on shared state
  • v3: state-engine protocol for sliced state, narrower locking, and native state operations

The roadmap direction is simple:

  • keep the vanilla-compatible backend path strong
  • make state more queryable and repairable
  • push coordination and safety higher into the backend for large shared states

Contributing, security, license, and governance

KiloLock is Apache 2.0 open source. The OSS project remains self-hostable and auditable; a future managed service does not change that.