Skip to content

Point Reads (Query)

Point reads retrieve the current state of a single entity by its ID. They are served entirely from the server’s in-memory entity table with no disk I/O.

The simplest way to query is through KindHandle<T>:

Player? result = await players.QueryAsync(EntityId.FromGuid(playerId));
if (result is { } player)
{
Console.WriteLine($"{player.Name}: {player.Health} HP");
}

Returns null if the entity does not exist or is tombstoned.

For more detail (including tombstone status and source set), use the low-level API:

var result = await client.QueryAsync(kindId, entityId);
switch (result.Status)
{
case QueryStatus.Alive:
// Entity exists. result.FieldData, result.Version, result.SourceSet are populated.
break;
case QueryStatus.Tombstone:
// Entity was retracted by all sources. result.Version is the last known version.
// Tombstoned entities are visible during the retention period (default: 5 minutes).
break;
case QueryStatus.NotFound:
// Entity has never existed, or the tombstone retention period has expired.
break;
}

Entity IDs are 32-byte opaque values. The EntityId helper class provides construction from common .NET types:

// From a GUID (16 bytes, zero-padded to 32)
ReadOnlyMemory<byte> id = EntityId.FromGuid(Guid.NewGuid());
// From a long (8 bytes, zero-padded to 32)
ReadOnlyMemory<byte> id = EntityId.FromLong(42L);
// From a string (SHA-256 hash, always 32 bytes)
ReadOnlyMemory<byte> id = EntityId.FromString("order-1234");

Round-trip conversions:

Guid guid = EntityId.ToGuid(id);
long num = EntityId.ToLong(id);
  • Point reads are in-memory lookups. Target latency is 5 microseconds at p50 and 20 microseconds at p99.
  • Reads do not block writes. The convergence engine is single-threaded per partition, and reads are served from the current in-memory state.
  • There is no read-your-own-writes guarantee within a coalescing window. A write followed immediately by a query may return the pre-write state if the write has not been flushed yet.