Understanding Reads

eeCLOUD reads are designed to be deterministic, order-aware and optimized for time-ordered data. This guide explains how to think about reading in eeCLOUD and how to choose the right method.

Why eeCLOUD Does Not Provide a Traditional ReadById

In many systems, ReadById is the primary access pattern. eeCLOUD focuses on a different model: time-ordered data and memory snapshots.

For most real-world use cases (sessions, device state, configurations, user timeline, latest event), the question is not "give me record X" but rather "give me the most relevant record now".

Key idea: eeCLOUD reads are built around Order, Reference, Index and Address.

Single-Record Reads and the Order Parameter

Several read methods are logically single-record reads. When multiple matches exist, the Order parameter decides which record is returned.

OrderSingle-record result
DESC (default)Most recent record (last inserted)
ASCOldest record (first inserted)
// Latest record
await app.ReadData("myApp", "sessions");

// First record
await app.ReadData("myApp", "sessions", Order.ASC);
Use DESC for "current state" patterns. Use ASC for baseline / bootstrap patterns.

The Deterministic Handle: Address

The most deterministic way to read a specific record is using its address (MemoryArea.address). The address is the stable handle used by update and delete operations.

var single = await app.ReadData("myApp", "users", address);
If you need to modify or delete a record later, store its address.

Read Patterns

1) Read latest (or first) record from a Memory

// Latest (default)
await app.ReadData("myApp", "config");

// First
await app.ReadData("myApp", "config", Order.ASC);

2) Read by id

eeCLOUD supports id-based reads, but they are still order-aware when multiple matches exist.

await app.ReadData("myApp", "users", id);
await app.ReadData("myApp", "users", id, Order.DESC, deleted: false);

3) Read by index

await app.ReadIndexData("myApp", "users", index);

4) Read by field and value

await app.ReadData("myApp", "users", "email", "[email protected]");

5) Read by reference

Reference-based reads are the fastest way to retrieve user/tenant/device owned data.

// Latest record for a given reference
await app.ReadRefData("myApp", "orders", userId);

// Read by reference + index
await app.ReadRefData("myApp", "orders", userId, index);

6) Read by combinations

// index + id
await app.ReadData("myApp", "orders", index, id);

// reference + id
await app.ReadRefData("myApp", "orders", userId, id);

// reference + index + id
await app.ReadRefData("myApp", "orders", userId, index, id);

// reference + field/value
await app.ReadData("myApp", "orders", userId, "status", "paid");

Deleted Records

Many reads accept a deleted parameter. When false (default), soft-deleted records are excluded. When true, soft-deleted records are included.

// Include soft-deleted data
await app.ReadData("myApp", "users", id, Order.DESC, deleted: true);
Soft delete is reflected by MemoryArea.deleted and MemoryArea.delete.

From Reads to Stable Updates

A common pattern is:

// 1) Read latest
var mem = await app.ReadRefData("myApp", "sessions", userId);

// 2) Take the address
var addr = mem.area[0].address;

// 3) Update deterministically
await app.UpdateValue("myApp", "sessions", addr, "active", false);
This pattern avoids ambiguity: flexible reads, deterministic modifications.
An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.