# ChaosBlade Prepare vs Create Commands: Key Differences Explained

> Understand the key differences between ChaosBlade prepare and create commands. Learn when to use them to setup your environment or launch chaos experiments effectively.

- Repository: [ChaosBlade/chaosblade](https://github.com/chaosblade-io/chaosblade)
- Tags: deep-dive
- Published: 2026-02-27

---

**The `prepare` command sets up the runtime environment (e.g., attaching JVM agents) without starting chaos experiments, while the `create` command launches actual chaos experiments (e.g., CPU load, network latency) and manages their full lifecycle.**

Understanding the distinction between the `prepare` and `create` commands in the [chaosblade-io/chaosblade](https://github.com/chaosblade-io/chaosblade) repository is essential for effective chaos engineering workflows. While both commands interact with the internal data layer and generate unique identifiers (UIDs), they serve fundamentally different purposes in the chaos experiment lifecycle. This article examines the architectural differences, data models, and source code implementations that separate these two critical commands.

## Core Purpose: Environment Setup vs Experiment Execution

The primary difference between `prepare` and `create` lies in their fundamental objectives within the chaos engineering workflow.

### What the Prepare Command Does

The `prepare` command establishes the necessary runtime environment for future experiments without actually injecting any chaos. According to the source code in [`cli/cmd/prepare.go`](https://github.com/chaosblade-io/chaosblade/blob/main/cli/cmd/prepare.go), this command handles tasks such as attaching a Java agent to a JVM process or deploying a sidecar to a Kubernetes cluster.

When executed, `prepare` generates a UID via `util.GenerateUid()` and inserts a **preparation record** into the database through `data.GetDS().InsertPreparationRecord()`. The record's status transitions from `Created` to `Running` upon successful completion of the setup logic, or to `Error` if the preparation fails.

### What the Create Command Does

The `create` command launches an actual chaos experiment and manages its complete lifecycle. As implemented in [`cli/cmd/create.go`](https://github.com/chaosblade-io/chaosblade/blob/main/cli/cmd/create.go), this command drives the execution of specific chaos actions such as CPU overload, network latency injection, or disk fill operations.

The `create` command builds an `ExperimentModel` and persists it via `data.GetDS().InsertExperimentModel()`. It supports both synchronous and asynchronous execution modes through the `--async` flag. When running asynchronously, it launches a background `nohup` process and immediately returns the UID, while synchronous execution blocks until the experiment completes or fails.

## Data Layer: Preparation Records vs Experiment Records

Both commands interact with distinct database tables and data models, reflecting their different roles in the system.

### Preparation Record Lifecycle

Preparation records are defined in [`data/preparation.go`](https://github.com/chaosblade-io/chaosblade/blob/main/data/preparation.go) and track the state of environment setup operations. The `PreparationRecord` struct includes fields for `Uid`, `ProgramType`, `ProcessName`, `Port`, and `Status`.

The status lifecycle for preparation records follows this path:
- `Created` → `Running` (successful setup)
- `Created` → `Error` (setup failure)
- `Running` → `Revoked` (when explicitly destroyed)

The `handlePrepareResponse` function in [`cli/cmd/prepare.go`](https://github.com/chaosblade-io/chaosblade/blob/main/cli/cmd/prepare.go) manages these transitions by calling `UpdatePreparationRecordByUid` with the appropriate status constants.

### Experiment Record Lifecycle

Experiment records are defined in [`data/experiment.go`](https://github.com/chaosblade-io/chaosblade/blob/main/data/experiment.go) and represent actual chaos experiments in execution. The `ExperimentModel` struct contains fields for `Uid`, `Command`, `SubCommand`, `Flag`, `Status`, and `Error`.

The status lifecycle for experiment records includes:
- `Created` (initial state)
- `Success` (completed successfully)
- `Error` (execution failed)
- `Destroyed` (explicitly stopped or cleaned up)

The `actionRunEFunc` in [`cli/cmd/create.go`](https://github.com/chaosblade-io/chaosblade/blob/main/cli/cmd/create.go) handles these transitions, updating the record via `UpdateExperimentModelByUid` after execution completes. Additionally, the optional `endpointCallBack` function can POST experiment results to an external HTTP endpoint for integration with monitoring systems.

## Command Implementation in Source Code

Examining the source code reveals the architectural patterns that distinguish these commands.

### Prepare Command Implementation (cli/cmd/prepare.go)

The `PrepareCommand` struct implements the command interface in [`cli/cmd/prepare.go`](https://github.com/chaosblade-io/chaosblade/blob/main/cli/cmd/prepare.go). The `Init` method registers the command with Cobra:

```go
func (pc *PrepareCommand) Init() {
    pc.command = &cobra.Command{
        Use:     "prepare",
        Aliases: []string{"p"},
        Short:   "Prepare to experiment",
        // ...
    }
}

```

The `insertPrepareRecord` function (lines 62-84) generates a UID and persists the initial record:

```go
func insertPrepareRecord(prepareType, processName, port, processId string) (*data.PreparationRecord, error) {
    uid, err := util.GenerateUid()
    // ...
    record := &data.PreparationRecord{Uid: uid, ProgramType: prepareType, ...}
    err = GetDS().InsertPreparationRecord(record)
}

```

The `handlePrepareResponse` function (lines 86-118) updates the record status based on execution results, transitioning to `Running` on success or `Error` on failure.

### Create Command Implementation (cli/cmd/create.go)

The `CreateCommand` struct in [`cli/cmd/create.go`](https://github.com/chaosblade-io/chaosblade/blob/main/cli/cmd/create.go) handles experiment lifecycle management. The `Init` method registers the command:

```go
func (cc *CreateCommand) Init() {
    cc.command = &cobra.Command{
        Use:     "create",
        Short:   "Create a chaos engineering experiment",
        // ...
    }
}

```

The core execution logic resides in `actionRunEFunc` (lines 104-229), which:

1. Builds the experiment model via `createExpModel`
2. Inserts the record using `actionCommand.recordExpModel`
3. Determines execution mode (sync vs async)
4. Executes the appropriate executor
5. Updates status and triggers optional endpoint callbacks

The `endpointCallBack` function (lines 32-49) provides optional HTTP reporting:

```go
func endpointCallBack(ctx context.Context, endpoint, uid string, response *spec.Response) {
    if endpoint != "" {
        // POST result to external endpoint
    }
}

```

## Practical Usage Examples

Understanding the distinction becomes clearer through concrete examples.

**Preparing a Java Environment**

```bash

# Attach the chaosblade-jvm agent to a Tomcat process

blade prepare jvm --process tomcat

# Output: Returns a UID (e.g., 1234567890abcdef)

# Status transitions: Created → Running

```

This command modifies the target JVM by attaching the ChaosBlade agent, but does not inject any chaos. The returned UID can be used later to revoke the preparation via `blade destroy <UID>`.

**Creating a Synchronous Experiment**

```bash

# Immediately start a CPU load experiment

blade create cpu load --cpu-percent 60

# Output: Returns UID, blocks until completion or interruption

# Status transitions: Created → Success/Error

```

This command immediately begins consuming 60% of CPU resources and blocks the terminal until the experiment is stopped or encounters an error.

**Creating an Asynchronous Experiment with Callback**

```bash

# Launch network latency in background with webhook reporting

blade create network delay --interface eth0 --time 2000 \
      --async --endpoint http://monitoring.example.com/chaos-callback

# Output: Immediately returns UID

# Background process runs nohup, later POSTs result to endpoint

```

This launches a 2000ms network delay experiment in the background, allowing the user to continue using the terminal. Upon completion, ChaosBlade POSTs the results to the specified endpoint.

## Summary

- **Purpose distinction**: The `prepare` command establishes runtime prerequisites (JVM agents, Kubernetes sidecars) without injecting chaos, while `create` launches actual experiments (CPU, network, disk attacks) and manages their lifecycle.

- **Data models**: `prepare` persists `PreparationRecord` entries in the preparation table with statuses (`Created`, `Running`, `Error`, `Revoked`), whereas `create` persists `ExperimentModel` entries in the experiment table with statuses (`Created`, `Success`, `Error`, `Destroyed`).

- **Execution modes**: `prepare` always runs synchronously to completion, while `create` supports both synchronous blocking execution and asynchronous background execution via the `--async` flag with optional webhook callbacks.

- **Source locations**: Implementation resides in [`cli/cmd/prepare.go`](https://github.com/chaosblade-io/chaosblade/blob/main/cli/cmd/prepare.go) (prepare logic, `insertPrepareRecord`, `handlePrepareResponse`) and [`cli/cmd/create.go`](https://github.com/chaosblade-io/chaosblade/blob/main/cli/cmd/create.go) (experiment logic, `actionRunEFunc`, `endpointCallBack`).

## Frequently Asked Questions

### Can I run a chaos experiment without using prepare first?

Yes, for many experiment types such as CPU load or network delay, you can run `blade create` directly without any prior preparation. However, for Java-based chaos experiments (JVM attacks), you must first run `blade prepare jvm` to attach the ChaosBlade agent to the target process before creating any JVM-related experiments.

### What happens to the preparation record after I destroy the experiment?

The preparation record remains in the database with its status updated to `Revoked` when you explicitly destroy it using `blade destroy <UID>`. Unlike experiment records that transition to `Destroyed`, preparation records track the lifecycle of the environment setup itself and maintain a distinct `Revoked` state to indicate the agent or sidecar has been removed.

### How do I check the status of a prepare or create command?

You can check the status of both preparation and experiment records using the `blade status` command followed by the UID. For example, `blade status 1234567890abcdef` queries the database and returns the current state (e.g., `Running`, `Success`, `Error`) along with error details if the operation failed. This works for both preparation records created by `prepare` and experiment records created by `create`.