> For the complete documentation index, see [llms.txt](https://bucketdb.sullux.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bucketdb.sullux.com/usage/migrations.md).

# Migrations

BucketDB enforces strict immutable structures. This means you **cannot modify an existing schema version**. Once `version: 1` is written, the data blocks are locked to that binary layout forever.

Instead, BucketDB uses a **Copy-on-Write Blue/Green Migration Pattern**. This is handled natively by the cluster's timesharing authority via the **Storage-Level Migration Daemon** to guarantee zero downtime.

## The Problem with Modifying Schemas

In traditional RDBMS systems, adding a column often locks a table, preventing reads/writes until the server rewrites the physical pages. In a highly distributed environment, locking an S3 bucket is impossible and downloading/rewriting all blocks synchronously would cause massive timeouts.

In earlier versions of BucketDB, developers had to write manual ETL scripts or handle versioned rows dynamically at query time. As of v0.2.0, the database handles this entirely in the background at the storage layer.

## The Zero-Downtime Migration Process

Because migrating gigabytes of storage blocks takes time, you must orchestrate your application deployment alongside the BucketDB schema daemon.

### Step 1: Define Version 2 (V2)

In your application code, register the new schema.

```javascript
// Register V2 with the new field
db.registerSchema({
  name: 'users',
  version: 2, // Increment version
  fields: {
    id: { typeId: 10, maxLength: 36 },
    email: { typeId: 10, maxLength: 255 },
    age: { typeId: 1 } // New field
  },
  primaryKey: 'id'
});
```

### Step 2: Deploy Dual-Schema Readers

Deploy an update to your application. At this stage:

* Your application logic must be prepared to **read** documents in either V1 or V2 format (e.g., handling missing fields gracefully or utilizing BucketDB's array aliases for backwards compatibility).

### Step 3: Trigger the Storage Daemon

You trigger the background daemon by updating the target version.

```javascript
// This writes the new target version into the Target Versions Section of Block 0
await db.setTargetSchemaVersion('users', 2);
```

#### What happens internally?

The node holding the timesharing authority (the Leader) spins up the `SchemaDaemon`.

1. **Detection:** It detects a discrepancy between the target version in `Block 0` and the actual version of the data blocks in the index.
2. **Blue/Green Transformation:** It reads the old `V1` data blocks, translates the rows into the new `V2` binary layout (padding new fields with default values, and dropping removed fields), and writes them to entirely new S3 data blocks.
3. **Atomic Pointer Swap:** Once all blocks are transformed, it performs an atomic conditional PUT on `Block 0`. It swaps the active block pointers from the old schema version to the new one.
4. **Garbage Collection:** The old S3 data blocks are now orphaned (no longer referenced by `Block 0`) and will be safely purged by the standard `db.gc()` process.

During this time, your application is still reading and writing normally. The `QueryExecutor` simply reads the old blocks until the atomic pointer swap occurs.

### Step 4: Deploy V2 Writers

Once the migration is fully complete (all blocks in the `Block 0` index indicate V2), deploy a second update to your application. Now, your application logic should **write** documents using the V2 schema exclusively.

### Step 5: Deprecate V1 (Cleanup)

Once you are certain no rogue clients are still caching or writing V1 data, you can remove any V1 fallback logic from your codebase.

Run `db.gc()` to purge the orphaned V1 S3 data blocks, freeing up storage capacity.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bucketdb.sullux.com/usage/migrations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
