Metadata Passthrough
ConvergeDB supports attaching opaque metadata to ASSERT, PATCH, and RETRACT operations. Metadata describes the cause of a mutation (for example, which user triggered it or which reducer produced it), not the result.
Key properties
Section titled “Key properties”- Transient. Metadata is not stored in the entity table or WAL. It lives only in the accumulator during the coalescing window and is forwarded to subscribers in the resulting notification.
- Last-write-wins. If multiple writes to the same entity within a coalescing window carry metadata, only the metadata from the last write is forwarded.
- Not in queries. Metadata is absent from QUERY responses, bootstrap snapshots, and scan results. It is only available in live subscriber notifications.
- Size limit. Maximum 65,535 bytes per operation (u16 length prefix). See Limits.
Sending metadata
Section titled “Sending metadata”Attach metadata bytes to any write operation:
var metadata = new MetadataBuilder() .Set("ci", callerIdentityBytes) .Set("rd", "UpdatePlayerPosition") .Build();
await players.AssertAsync(player, metadata: metadata);await players.PatchAsync(patch, metadata: metadata);await players.RetractAsync(entityId, metadata: metadata);Receiving metadata in subscribers
Section titled “Receiving metadata in subscribers”Metadata is available on the ChangeNotification via the Metadata property:
await foreach (var change in players.SubscribeAsync(bootstrap: false)){ if (change.Metadata.Length > 0) { var meta = MetadataReader.Parse(change.Metadata); string? caller = meta.GetString("ci"); string? reducer = meta.GetString("rd"); Console.WriteLine($"Changed by {caller} via {reducer}"); }}Wire format
Section titled “Wire format”Metadata is encoded as a trailing metadata_len(u16) + metadata(bytes) on ASSERT, PATCH, and RETRACT frames. Old clients that do not send metadata simply omit the trailing bytes. Old subscribers that do not understand metadata ignore the trailing bytes in STATE notifications. This makes metadata backward-compatible in both directions.
When to use metadata
Section titled “When to use metadata”Metadata is useful when subscribers need to know why an entity changed, not just what changed:
- Audit trails. Attach the caller identity and the operation that triggered the mutation.
- Reducer attribution. In game server architectures, attach the reducer name so subscribers can distinguish between different game logic paths that produced the same entity state.
- Correlation IDs. Attach a request ID for distributed tracing across services.
If you only need to know what changed, use ChangedFields instead.