Performance Implications of Using no-mistakes: A Technical Deep Dive

no-mistakes adds at most a few seconds of overhead to repository operations by trading modest CPU and memory usage (typically under 30 MiB) for safety-critical guarantees like deterministic rebase handling and audit-ready run records.

no-mistakes is a Go-based CLI that orchestrates complex Git workflows through a short-lived daemon and SQLite-backed persistence layer. While the tool intentionally prioritizes safety over raw throughput, understanding its performance implications helps you decide whether it fits your workflow and what optimization strategies to apply.

Architecture Components and Their Performance Impact

The performance characteristics of no-mistakes stem from its modular architecture, where each component contributes specific overhead trade-offs.

CLI Entry Point and Daemon Lifecycle

In cmd/no-mistakes/main.go, the CLI parses flags and spawns a daemon process that coordinates the entire run. The daemon (internal/daemon/manager.go) maintains a long-running run manager that watches the repository and streams events via IPC.

This architecture keeps the memory footprint under ~30 MiB even on modest machines. Because the daemon is deliberately short-lived (per-run), it releases all resources once the run finishes, preventing the memory bloat common in long-running background services.

SQLite Database and Storage Model

The internal/db/run.go file implements a SQLite-backed store that persists run metadata, findings, and awaiting-agent markers. The database uses a single-writer lock model, meaning steps execute sequentially with minimal contention.

Disk I/O is limited to a few writes per step for status updates and finding records. Typical write operations complete in under 1 millisecond, making the storage layer negligible compared to network or compute-bound operations.

Pipeline Execution and Concurrency

The internal/pipeline/executor.go orchestrates steps in strict sequential order. The implementation is single-threaded (steps are not parallelized), so CPU spikes are bounded by the most expensive individual step.

The executor uses a sync.Mutex only to protect the approval channel, resulting in negligible lock contention. This sequential design guarantees deterministic ordering but means you cannot parallelize independent steps within a single run.

LLM Agent Network Latency

When invoking large language models through internal/agent/agent.go, network latency dominates the wall-clock time. The local Go process overhead is tiny; the real cost is the HTTP request/response time to remote services like Claude, Codex, or Copilot.

The code launches agent subprocesses with cancellable contexts via shellenv.ConfigureShellCommand, preventing orphaned children that would otherwise waste CPU and keep file locks.

Process Management and Resource Cleanup

The internal/shellenv/shellenv.go wrapper starts subprocesses (e.g., git rebase, npm test) with proper process-group handling. Each external command runs in its own process group, allowing the parent to kill the entire tree on context cancellation.

This design prevents lingering workers and hidden CPU consumption. The internal/wizard/wizard.go file propagates context.Context through every long-running operation, enabling graceful early termination with only negligible overhead (a few pointer copies).

Real-World Performance Scenarios

Performance varies based on repository size and external dependencies:

Scenario Typical Wall-Clock Time Dominant Factor
Fast local repo, no agents 0.5 – 2 seconds Git operations (rebase, fetch)
Running tests with subprocesses 2 – 10 seconds Subprocess CPU & I/O
Invoking an LLM agent 5 – 30+ seconds Network latency & remote model compute
Large monorepo (~1 GB) 5 – 15 seconds Disk I/O for worktree creation & SQLite writes

The tool adds at most a few seconds of overhead beyond the raw work you would already perform. The biggest "slow-down" is the intentional round-trip to an LLM, which is an external factor you would pay for regardless of the CLI wrapper.

Design Choices That Limit Performance

Understanding these intentional constraints helps you optimize around them:

  1. Sequential pipeline – Guarantees deterministic ordering and avoids concurrent DB write complexity, but prevents parallel step execution.

  2. Cancellable contexts – Prevents runaway subprocesses, saving CPU and freeing file locks promptly when users abort operations.

  3. SQLite single-writer model – Keeps the database lightweight and avoids WAL mode complexity, but serializes all writes.

  4. Process-group handling – Guarantees complete cleanup of child processes (e.g., test runners) at the cost of additional process management overhead.

Practical Code Examples

Control execution timeouts to prevent runaway operations:

// Example: run a pipeline with a 30-second overall timeout.
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

err := noMistakesRun(ctx, []string{"--branch", "feature/foo"})
if err != nil {
    log.Fatalf("run failed: %v", err)
}

The noMistakesRun function creates an Executor (see executor.go) and respects the passed context, guaranteeing that any subprocess (git, npm, LLM agent) terminates when the timeout fires.

Manually spawn the daemon for advanced use cases:

// Example: manually spawn the daemon and watch events.
daemon, _ := daemon.NewManager(cfg, db, paths)
go daemon.Start(ctx)               // runs in its own goroutine
<-daemon.Ready()                   // wait until the daemon is ready
runID, _ := daemon.StartRun("my-branch")
fmt.Println("run started:", runID)

The daemon keeps a SQLite DB open for the whole run; once the run finishes, the daemon shuts down and releases resources.

Summary

  • Memory footprint remains under 30 MiB due to the short-lived daemon design.
  • Sequential execution in internal/pipeline/executor.go prevents parallel steps but eliminates lock contention.
  • SQLite single-writer model minimizes database overhead with sub-millisecond writes.
  • Network latency from LLM agents dominates wall-clock time, not the tool itself.
  • Process groups and cancellable contexts prevent resource leaks without significant CPU cost.

Frequently Asked Questions

How much memory does no-mistakes consume during a run?

The daemon (internal/daemon/manager.go) typically consumes under 30 MiB of memory during execution. Because the daemon is short-lived and per-run, it releases all resources immediately after completion, making it suitable for memory-constrained CI environments.

Why does no-mistakes execute pipeline steps sequentially instead of in parallel?

The internal/pipeline/executor.go implements a single-threaded execution model to guarantee deterministic ordering and simplify the SQLite single-writer concurrency model. While this prevents parallel step execution, it avoids complex race conditions and ensures audit-ready run records.

Can I reduce the overhead when working with large monorepos?

For repositories around 1 GB, overhead typically comes from disk I/O during temporary worktree creation (internal/paths/paths.go). You can optimize by ensuring fast disk I/O (SSD) and cleaning up unnecessary files before runs, as the tool creates temporary worktrees with 0o755 permissions that duplicate repository data during active runs.

Is the performance impact different when using LLM agents versus standard Git operations?

Yes. Standard Git operations add only 0.5–2 seconds of overhead, while LLM agents introduce 5–30+ seconds due to network latency and remote computation. The local CPU cost remains minimal in both cases; the bottleneck for agent steps is external network calls to services like Claude or Codex.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →