Write Model & Data Lifecycle

eeCLOUD writes are designed for managed DaaS usage: send data through API Key scoped Applications, keep ownership and chronology explicit, then evolve records through deterministic lifecycle operations.

Lifecycle at a Glance

A record in eeCLOUD typically follows this lifecycle:

WRITE -> READ -> UPDATE -> DELETE -> RESTORE -> ERASE
Key idea: Reads may be flexible and order-aware. Mutations should become deterministic through address.

Basic Write

The simplest DaaS write is payload-only. eeCLOUD assigns the engine metadata automatically.

This is the typical starting point for a new Application on the Free plan before a team decides whether that workload should move to a paid subscription.

await ee.Memory("users").WriteAsync(new
{
    name = "John",
    role = "admin"
});

Write with Reference

reference is the main way to attach a logical owner to the record. In practice it often represents a tenant, user, device or session.

await ee.Memory("orders").WriteAsync(
    new { total = 99.90m, status = "created" },
    reference: 1001
);

Reference-based modeling is important because it aligns with the strongest DaaS read patterns of eeCLOUD.

Write with ID and Index

When the application already has stable business identifiers, you can send them during the write.

await ee.Memory("devices").WriteAsync(
    id: "sensor-01",
    data: new { firmware = "1.0.4", online = true },
    reference: 1001
);

await ee.Memory("devices").WriteAsync(
    id: "sensor-01",
    index: "IDX-SENSOR-01",
    data: new { firmware = "1.0.4", online = true },
    reference: 1001
);

Write with Business Date

Use date when the business event time matters and is different from the persistence timestamp. eeCLOUD stores both the logical date and the engine-generated create timestamp.

await ee.Memory("events").WriteAsync(
    data: new { type = "boot" },
    reference: 1001,
    date: DateTime.UtcNow.AddMinutes(-10)
);

Batch Write

For ingestion workloads, the SDK supports batch writes through both the compatibility WriteAsync(List<WriteRequest>) overload and the explicit WriteBatchAsync(...) contract.

var batch = new List<WriteRequest>
{
    new(new { value = 21.4 }, reference: 1001),
    new(new { value = 21.8 }, reference: 1001),
    new(new { value = 22.1 }, reference: 1001)
};

await ee.Memory("telemetry").WriteAsync(batch);
await ee.Memory("telemetry").WriteBatchAsync(new List<WriteBatchRequest>
{
    new("sensor-01", Guid.NewGuid().ToString("N"), DateTime.UtcNow, new { value = 21.4 }, 1001),
    new("sensor-01", Guid.NewGuid().ToString("N"), DateTime.UtcNow, new { value = 21.8 }, 1001)
});

Object Graph Write

Use object graph writes when you want the platform to persist a richer object model instead of a plain JSON record flow.

await ee.Memory("devices").WriteObjectAsync(
    id: "sensor",
    index: "sensor-01",
    data: new
    {
        meta = new { region = "eu-west" },
        telemetry = new[] { 23.4m, 23.7m }
    }
);

Clusterized Write

Set clusterized: true when the data model benefits from physical partitioning by reference. This is especially relevant for large multi-tenant or high-cardinality workloads.

await ee.Memory("orders").WriteAsync(
    id: "order-0001",
    data: new { total = 99.90m },
    reference: 1001,
    clusterized: true
);

Update Operations

The official SDK exposes full-record updates, identity updates and value updates.

await ee.Memory("users").UpdateAsync(address, new
{
    name = "John",
    role = "owner"
});

await ee.Memory("users").UpdateIdAsync(address, "user-0001");
await ee.Memory("users").UpdateIndexAsync(address, "IDX-USER-0001");
await ee.Memory("users").UpdateValueAsync(address, "active", true);

Increase Operations

Numeric counters can be incremented directly through the SDK.

await ee.Memory("metrics").IncreaseAsync(address, "hits", 1);
await ee.Memory("wallets").IncreaseAsync(address, "balance", 2.5m);

Delete, Restore and Erase

eeCLOUD supports a full deletion lifecycle:

  • Delete marks data as deleted
  • Restore recovers soft-deleted data
  • Erase permanently removes data
await ee.Memory("users").DeleteAsync(address);
await ee.Memory("users").RestoreAsync(address);
await ee.Memory("users").EraseAsync(address);

Design Guidelines

  • Use reference when the data belongs to an owner
  • Use id for business grouping and index for unique logical lookups
  • Use date for business time and rely on create for persistence time
  • Prefer address-based updates after the first read or write result
  • Enable clusterized only when the dataset scale justifies physical partitioning