gRPC Message Size
Large event batches or queries that return many events can exceed gRPC message limits. Chronicle provides configuration options to adjust the maximum send and receive message sizes.
Default Settings
Section titled “Default Settings”By default, Chronicle sets both MaxReceiveMessageSize and MaxSendMessageSize to 100 MB (104,857,600 bytes). This is higher than the gRPC default of 4 MB and is suitable for most scenarios involving large event collections.
Configuring Message Sizes
Section titled “Configuring Message Sizes”You can configure the message sizes when creating a ChronicleClient or through options:
public static class GrpcMessageSizeConfiguration{ public static ChronicleClient Create() { var options = new ChronicleOptions { ConnectionString = "chronicle://localhost:35000", MaxReceiveMessageSize = 200 * 1024 * 1024, // 200 MB MaxSendMessageSize = 200 * 1024 * 1024 // 200 MB };
return new ChronicleClient(options); }}import io.cratis.chronicle.ChronicleOptions
fun optionsWithLargerMessages(): ChronicleOptions = ChronicleOptions.fromConnectionString("chronicle://localhost:35000") .withMaxReceiveMessageSize(200 * 1024 * 1024) // 200 MBimport io.cratis.chronicle.ChronicleOptions;
class MessageSizeConfiguration { ChronicleOptions create() { return ChronicleOptions.fromConnectionString("chronicle://localhost:35000") .withMaxReceiveMessageSize(200 * 1024 * 1024); // 200 MB }}Elixir does not support this workflow yet.import { ChronicleOptions } from '@cratis/chronicle';
function createOptionsWithLargerMessages(): ChronicleOptions { return ChronicleOptions.fromConnectionString('chronicle://localhost:35000', { maxReceiveMessageSize: 200 * 1024 * 1024, // 200 MB maxSendMessageSize: 200 * 1024 * 1024 // 200 MB });}Configuration via appsettings.json
Section titled “Configuration via appsettings.json”For ASP.NET Core applications, configure message sizes under the Cratis:Chronicle section of appsettings.json:
{ "Cratis": { "Chronicle": { "ConnectionString": "chronicle://localhost:35000", "MaxReceiveMessageSize": 209715200, "MaxSendMessageSize": 209715200 } }}Configuration via Environment Variables
Section titled “Configuration via Environment Variables”Message sizes can also be set using environment variables. .NET maps the __ separator onto nested configuration keys:
Cratis__Chronicle__MaxReceiveMessageSize=209715200Cratis__Chronicle__MaxSendMessageSize=209715200Server limits
Section titled “Server limits”The kernel enforces a receive limit of its own, and it defaults to the same 100 MB the clients allow themselves to send. Before this default existed the kernel accepted 4 MB, so a client on default options could be refused by the server it was configured to talk to. Set it through the kernel’s configuration:
{ "maxReceiveMessageSize": 209715200, "maxSendMessageSize": 209715200}Cratis__Chronicle__MaxReceiveMessageSize=209715200Cratis__Chronicle__MaxSendMessageSize=209715200The server’s send size is unlimited unless you set it. See Root Properties.
Understanding the Error
Section titled “Understanding the Error”If you encounter an error like:
Status(StatusCode="ResourceExhausted", Detail="Received message exceeds the maximum configured message size.")This indicates that the response from the server exceeds the client’s MaxReceiveMessageSize. Increase this value to accommodate larger responses. A call that fails with status ResourceExhausted while sending, for instance when appending a large event, points at the kernel’s maxReceiveMessageSize instead.
Recommendations
Section titled “Recommendations”- Default (100 MB): Suitable for most applications with moderate event batch sizes
- 200+ MB: Consider for applications that frequently query large event ranges or work with many events
- Performance considerations: Larger message sizes consume more memory. Balance your needs with available resources
- Server configuration: The kernel has its own limits, see Server limits. A message is only as large as the smaller of the two sides allows
Null Values
Section titled “Null Values”Setting either property to null will use the gRPC default (4 MB), which is generally not recommended for Chronicle applications:
public static class GrpcMessageSizeNullValues{ public static ChronicleOptions Create() => new() { MaxReceiveMessageSize = null, // Uses gRPC default of 4 MB - not recommended MaxSendMessageSize = null // Uses gRPC default of 4 MB - not recommended };}import io.cratis.chronicle.ChronicleOptions
fun optionsWithGrpcDefaults(): ChronicleOptions = ChronicleOptions.fromConnectionString("chronicle://localhost:35000") .withMaxReceiveMessageSize(null) // Uses gRPC default of 4 MB - not recommendedimport io.cratis.chronicle.ChronicleOptions;
class MessageSizeGrpcDefaults { ChronicleOptions create() { return ChronicleOptions.fromConnectionString("chronicle://localhost:35000") .withMaxReceiveMessageSize(null); // Uses gRPC default of 4 MB - not recommended }}Elixir does not support this workflow yet.import { ChronicleOptions } from '@cratis/chronicle';
function createOptionsWithGrpcDefaults(): ChronicleOptions { return ChronicleOptions.fromConnectionString('chronicle://localhost:35000', { maxReceiveMessageSize: null, // Uses gRPC default of 4 MB - not recommended maxSendMessageSize: null });}