Java RTO API Best Practices

Context and Session Threading Model Considerations


  • Use the 'One Session, One Context' threading model whenever possible. The 'Multiple Session, One Context' and 'Multiple Sessions, Multiple Contexts' models can potentially increase message processing throughput, but at the expense of additional processing.

There are three different Threading Models to consider when designing an application:

  1. One Session One Context. A single Session is used with a single Context.
  2. Multiple Sessions One Context. Multiple Sessions are serviced using one Context.
  3. Multiple Sessions Multiple Contexts. Application provides or uses a number of threads, each containing a single Context and each Context contains one or more Sessions.

For majority of cases, the 'One Session, One Context' model is sufficient for publisher and consumer application design.

An application designer may want to move to 'Multiple Sessions, One Context' if there is a need to prioritize messages where higher value messages maybe sent/received across different Sessions,for example, through different TCP connections. This approach can potentially increase throughput as well. This means that it may be necessary to forward received messages to downstream application internal queues such that messages are processed by additional application message processing threads. All received messages can be processed by the same message and event callback functions, or Session specific ones by creating additional callbacks.

With 'Multiple Sessions, Multiple Contexts', a designer can reduce the Context Thread processing burden of the 'Multiple Sessions, One Context' model where all Sessions must wait in the select loop before being processed. In this model, each Session can be separated into its own Context thread, and therefore enhance the processing performance that OS multi-threading provides. However, due to the increased number of threads, this approach requires expansive thread context switching, hence places more burden on the CPU and is more resource intensive.

Memory Management

The Java RTO API is designed to cause no garbage collection within the JVM. However, to prevent garbage collection, applications using the Java RTO API must also be designed correctly.

Modifying the Global Pool Buffer Sizes

When the Java RTO API is initialized, you can optionally modify the default global data buffer sizes for the five pools that are used.

When you call the Solclient.init(...) function to initialize the C API, you can pass in Solclient.GLOBAL_PROPERTIES.DBQUANTASIZE_<0-4> “DBQUANTASIZE” to specify the size (in bytes) of the data buffers for each of the five pools.

For more information, refer to Products.

Configuring Message Buffer Sizes

When creating a Session, an application can configure the following memory and resource allocation-related Session property parameters:


    The Session buffer size used for transmitting messages for the TCP Session. This parameter specifies the maximum amount of messages to buffer (as measured in bytes). For maximum performance, when sending small messages, the Session buffer size should be set to multiple times the typical message size.

    The C API always accepts at least one message to transmit. So even if the size of a single message exceeds the set buffer size, it is accepted and transmitted, as long as the current buffered data is zero. However, no further messages are accepted until the amount of data buffered is reduced below the set buffer size.


    The receive buffer size (in bytes) for the subscriber data socket. A default value of 150,000 is used. If this property is set to 0, the receive buffer size uses the operating system default.

    On Windows platforms the receive socket buffer size must be much larger than the send socket buffer sizes to prevent data loss when sending and receiving messages. For example, the default send socket and internal buffer sizes are set to 90,000, and the default receive socket buffer size is set to 150,000. If you change the default sizes, it is recommended that you maintain a similar sizing ratio.


    This parameter allows the send buffer size (in bytes) for the publisher data socket to be set by the application. A default value of 90,000 is used. If this property is set to 0, the send buffer size uses the operating system default.

Object Pooling

Whenever possible, objects should not be allocated and freed, but instead pre‑allocated and reused. This includes all of the objects provided within the Java RTO API, but also all other objects within the application. Solace recommends that application designers follow the object pool pattern to accomplish this.

The object pool pattern involves using and re-using a pool of initialized objects rather than destroying and recreating objects as needed. New objects should be created only when the pool contains no usable objects, so that the number of total objects in use is kept as low as possible.

Get vs. Take

When using MessageHandle.getRxMessage() to acquire messages, the Java RTO API retains ownership of the message and its allocated memory. The message will be freed automatically by the API after the message callback has completed. For best performance, Solace recommends using MessageHandle.getRxMessage().

When using MessageHandle.takeRxmessage(MessageHandle) to acquire messages, the application takes ownership of the message. Destroying the message with Handle.destroy() becomes the responsibility of the application. Using MessageHandle.takeRxmessage(MessageHandle) invokes a copy inside the Java RTO API.

The same distinction between get and take applies to the equivalent methods in SessionHandle, FlowHandle, and CacheSessionHandle.

TCP Send and Receive Buffer Size


  • Adjust the TCP send and receive buffer sizes to optimize TCP performance, particularly when publishing large messages or for WAN performance optimization.

For TCP, the bandwidth-delay product refers to the product of a data link’s capacity and its round-trip delay time. The result expresses the maximum amount of data that can be on the network at any given time. A large bandwidth-delay product is expected for a WAN environment due to the intrinsic long round-trip delay, and as such TCP can only achieve optimum throughput if a sender sends a sufficiently large quantity of data to fill the maximum amount of data that the network can accept. This means that the TCP send and receive buffer size needs to be adjusted.

Specific to Windows platform, the receive socket buffer size must be much larger than the send socket buffer size to prevent data loss when sending and receiving messages. The recommended ratio is 3 parts send buffer to 5 parts receive buffer.

TCP’s socket send and receive buffer sizes can be configured through the API’s session properties setting. The session property parameters and default values are shown below. If the value of zero is used for setting these properties, the operating system’s default size is used.

  • SessionHandle.PROPERTIES.SOCKET_RCV_BUF_SIZE; 150,000 bytes
  • SessionHandle.PROPERTIES.SOCKET_SEND_BUF_SIZE; 90,000 bytes

Session Establishment

Blocking Connect


  • Connect blocking calls serializes each and every session connect and increases session establishment delay. If serialization is not necessary, disable blocking connect to improve overall session connect speed.

Enable blocking connect serializes each and every individual session connect when there are many sessions configured within a Context. Doing so will increase the connection time. If serialization is not important, consider disabling blocking connect.

The blocking connect property is SessionHandle.PROPERTIES.CONNECT_BLOCKING.

Host Lists


  • Host Lists should always be used. This is applicable to Replication failover support, and software event broker's hostlist High Availability (HA) support. Host Lists should not be used in Active/Active Replication deployments.

For replication failover support, client applications should be configured with a host list of two addresses, one for each of the Guaranteed Messaging enabled virtual router at each site. If a connection fails for one host it would be reasonable to immediately attempt to connect to the to-be-active replication host before retrying the same host. Hence, it's recommended to set the reconnect retires per host to 1.

Host lists shouldn't be used in an active/active replication deployment where client applications are consuming messages from endpoints on the replication active message VPN on both sites.

Similarly, for software event broker HA failover support, if the switchover-mechanism is set to hostlist instead of ip-address-takeover, the client application should provide a host list of two addresses.

For further details on hostlist configuration, please refer to HA Configuration for Software Event Brokers.

Client API Keep-alive


  • The Client Keep-alive interval should be set to the same order of magnitude as the TCP Keep-alive setting on the client profile.

There are two types of keep-alive mechanisms between the client application and the event broker.

There is the TCP Keep-alive that operates at the TCP level that is sent by the event broker to the client application. This is the TCP Keep-alive mechanism described in RFC 1122. The client application’s TCP stack responds to the event broker’s TCP Keep-alive probe. By default, the event broker sends out a keep-alive message after it detects idle connection for 3 seconds. It then sends 5 probes at the interval of 1 keep-alive probe per second. Hence, the event broker will flag a client to have failed TCP keep-alive if it receives no response after 8 seconds.

There is also the Client API Keep-alive that occurs concurrently to the TCP Keep-alive. This is the API’s built-in keep-alive mechanism, and operates on top of TCP at the API level. This is sent from the API to the event broker. By default, a Client Keep-alive is sent at the interval of once every 3 seconds, and up to 3 keep-alive responses can be missed before the API declares that the event broker is unreachable; that is, after 9 seconds.

These keep-alive mechanisms exist so that they will be able to advise the application or the event broker that its peer has died before it's able to notify the corresponding party. The keep-alive mechanism is also used to prevent disconnection due to network inactivity. However, if either mechanism is set much more aggressively, that is, with a shorter detecting time, than the other, the connection can be prematurely disconnected. For example, if the Client API Keep-alive is set at a 500 ms interval with 3 keep-alive responses while the TCP Keep-alive remains unchanged at the default, then the client API Keep-alive will trigger aggressive disconnection.

High Availability Failover and Reconnect Retries


  • The reconnect duration should be set to last for at least 300 seconds when designing applications for High Availability (HA) support.

When using a High Availability (HA) appliance setup, a failover from one appliance to its mate will typically occur within 30 seconds. However, applications should attempt to reconnect for at least 5 minutes. Below is an example of setting the reconnect duration to 5 minutes using the following session property values:

  • connect retries: 1
  • reconnect retries: 20
  • reconnect retry wait: 3,000 ms
  • connect retries per host: 5

Refer to Configuring Connection Time-Outs and Retries for instructions on setting connect retries, reconnect retries, reconnect retry wait and connect retires per host parameters.

Replication Failover and Reconnect Retries


  • The number of reconnect retries should be set to -1 so that the API will retry indefinitely during a replication failover.

In general, the duration of a replication failover is non-deterministic as it may require operational intervention for the switch, which can take up to tens of minutes, or hours. Hence, it's recommended to set the number of reconnect retires to -1 so that the API will try to indefinitely reconnect for a replication aware client application.

Refer to Reconnect Retries for instructions on how to set the reconnect retries parameter.

Replication Failover and Session Re-Establishment


  • API versions higher than 7.1.2 are replication aware, and automatically handle session re-establishment when a replication failover occurs. Client applications running lower API versions must re-establish a session upon reconnect.

Prior to 7.1.2, sessions need to be re-established after a replication failover when a client is publishing Guaranteed messages in a session that has been disconnected, because, while the reconnect is successful, the flow needs to be re-established since the newly connected event broker in the Replication site doesn't t have any flow state information, unlike the case for HA failover where this information is synchronized. The recommendation is to catch the unkonw_flow_name event and re-establish a new session to get the flow created. From version 7.1.2 onwards, the API is replication aware and transparently handles session re-establishment .

File Descriptor Limitation


  • The number of Solace sessions created by an application shouldn't exceed the number of file descriptors supported per process by the underlying operating system. For Unix variants, this number is 1024, and for Windows it's 63.

File descriptor limits in Unix platforms restrict the number of files that can be managed per process, and this is 1024 by default. Hence, an application shouldn't create more than 1023 Sessions per Context. A session represents a TCP/IP connection, and such a connection occupies one file descriptor. A file descriptor is an element - usually a number - that allows you to identify, in this case, a stream of data from the socket. Open a file to read information from disk also occupies one file descriptor.

File descriptors are called ‘file’ because initially they only identified files, although more recently, they can be used to identify files on disk, sockets, pipes, and so on.

Similarly, on Windows platforms, a single Context can only manage at most 63 Sessions.

Subscription Management

The following best practices can be used for managing subscriptions:

  • If you are adding or removing a large number of subscriptions, set the Wait for Confirm flag (SessionHandle.SolEnum.SubscribeFlags.WAIT_FOR_CONFIRM) on the final subscription to ensure that all subscriptions have been processed by the event broker. However, to increase performance, it is recommended that you do not set Wait for Confirm on all other subscriptions except for the last.
  • In the event of a Session disconnect, you can have the API reapply subscriptions that were initially added by the application when the Session is reconnected. To reapply subscriptions on reconnect, enable the Reapply Subscriptions Session property (SessionHandle.PROPERTIES.REAPPLY_SUBSCRIPTIONS). Using this setting is recommended.

Sending Messages

Blocking Send


  • Send-blocking calls automatically limit the publishing rate at which an event broker can accept messages. Use non-blocking send to increase application performance.

In send-blocking mode, the calling thread for each send function call is blocked until the API accepts the message, and hence, the sending rate is automatically limited to the rate at which the event broker can accept the message. The send call remains blocked until either:

  • it's accepted by the API, or
  • the associated blocking write timeout expires.

Compared to non-blocking mode, send calls that cannot be accepted by the API will immediately return a would_block error code to the client application. In the meantime, the client application can continue to process other actions. Subsequently, the API will receive a can_send event which signifies that the client application can retry the send() function call again.

The send blocking parameter is SessionHandle.PROPERTIES.SEND_BLOCKING.

Batch Send


  • Use the batch sending facility to optimize send performance. This is particularly useful for performance benchmarking a client application.

Use the batch-sending facility to optimize send performance. This is particularly useful for performance benchmarking client applications.

A group of up to 50 messages can be sent through a single API call. This allows messages to be sent in a batch. The messages can be either Direct or Guaranteed. When batch-sending messages through the send-multiple API, the same Delivery mode, that is Direct or Persistent mode, should be set for all messages in the batch. Messages in a batch can be set to different destinations.

In addition to using the batch-sending API, messages should be pre-allocated and reused for batch-sending whenever possible. Specifically, don't reallocate new messages for each call to the batch-sending API.

The batch-sending API call is SessionHandle.send().

Time-to-Live Messages


  • Set the TTL attribute on published guaranteed messages to reduce the risk of unconsumed messages unintentionally piling up in the queue if the use-case allows for discarding old or stale messages.

Publishing applications should consider utilizing the TTL feature available for Guaranteed Messaging. Publishers can set the TTL attribute on each message prior to sending to the event broker. Once the message has been spooled, the message will be automatically discarded (or moved to the queue’s configured Dead Message Queue, if available) should the message not be consumed within the specified TTL. This common practice reduces the risk of unconsumed messages unintentionally piling up.

Alternatively, queues have a max-ttl setting, and this can be used instead of publishers setting the TTL on each message sent. See Configuring Max Message TTLs for instructions on setting max-ttl for a queue.

Configuring respect-ttl

Queues should be configured to respect-ttl as, by default, this feature is disabled on all queues. Refer to Enforcing Whether to Respect TTLs for instructions on how to set up respect-ttl.

Receiving Messages

Memory Management when Receiving Messages


  • When receiving messages, it's recommended to allow the API to retain ownership of the message. If ownership is passed to the application, it must ensure that the message is freed after use.

In general, message buffers received by the callback are owned by the API. These message buffers are freed automatically by the API after the message callback has completed. However, the ownership can be passed on to the application. In such a scenario, the application must free the message when it's finished to release the memory.

Handling Duplicate Message Publication


  • Publishing duplicate messages can be avoided if the client application uses the Last Value Queue (LVQ) to determine the last message successfully spooled by the event broker upon restarting.

When a client application is unexpectedly restarted, it's possible for it to become out-of-sync with respect to the message publishing sequence. There should be a mechanism by which it can determine the last message that was successfully published to, and received by, the event broker in order to correctly resume publishing without injecting duplicate messages.

One approach is for the publishing application to maintain a database that correlates between the published message identifier and the acknowledgment it receives from the event broker. This approach is completely self-contained on the client application side, but can introduce processing latencies if not well managed.

Another approach is to make use of the Last Value Queue (LVQ) feature, where the LVQ stores the last message spooled on the queue. A publishing client application can then browse the LVQ to determine the last message spooled by the event broker. This allows the publisher to resume publishing without introducing duplicate messages.

Refer to Configuring Max Spool Usage Values for instructions on setting up LVQ.

Handling Redelivered Messages


  • When consuming from endpoints, a client application should appropriately handle redelivered messages.

When a client application restarts, unexpectedly or not, and rebinds to a queue, it may receive messages that it had already processed as well as acknowledged. This can happen because the acknowledgment can be lost on route to the event broker due to network issues. The redelivered messages will be marked with the redelivered flag.

A client application that binds to a non-exclusive queue may also receive messages with the redelivered flag set, even though the messages are received by the client application for the first time. This is due to other clients connecting to the same non-exclusive queue which disconnects without the application acknowledging the received messages. These messages are then redelivered to other client applications that bind to the same non-exclusive queue.

The consuming application should contain a message processing mechanism to handle the above mentioned scenarios.

Dealing with Unexpected Message Formats


  • Client applications should be able to handle unexpected message formats. In the case of consuming from endpoints, a client application should acknowledge received messages even if those messages are unexpectedly formatted.

Client applications should be able to contend with unexpected message formats. There shouldn't be any assumptions made about a message's payload; for example, a payload may contain an empty attachment. Applications should be coded such that they will avoid crashing, as well as logging the message contents and sending an acknowledgment back to the event broker if using Guaranteed Messaging. If client applications crash without sending acknowledgments, then when they reconnect, the same messages will be redelivered causing the applications to fail again.

Client Acknowledgment


  • Client Applications should acknowledge received messages as soon as they have completed processing those messages when client acknowledgment mode is used.

Once an application has completed processing a message, it should acknowledge the receipt of the message to the event broker. Only when the event broker receives an acknowledgment for a Guaranteed Message will the message be permanently removed from its message spool. If the client disconnects without sending acknowledgments for some received messages, then those messages will be redelivered. For the case of an exclusive queue, those messages will be delivered to the next connecting client. For the case of a non-exclusive queue, those messages will be redelivered to the other clients that are bound to the queue.

There are two kinds of acknowledgments:

  • API (also known as Transport) Acknowledgment. This is an internal acknowledgment between the API and the event broker and isn't exposed to the application. The Assured Delivery (AD) window size, acknowledgment timer, and the acknowledgment threshold settings control API Acknowledgment. A message that isn't transport acknowledged will be automatically redelivered by the event broker.
  • Application Acknowledgment. This acknowledgment mechanism is on top of the API Acknowledgment. Its primary purpose is to confirm that message processing has been completed, and that the corresponding messages can be permanently removed from the event broker. There are two application acknowledgment modes: auto-acknowledgment and client acknowledgment. When auto-acknowledgment mode is used, the API automatically generates application-level acknowledgments on behalf of the application. When client acknowledgment mode is used, the client application must explicitly send the acknowledgment for the message ID of each message received.

Refer to the Receiving Guaranteed Messages for a more detailed discussion on the different acknowledgment modes.

Do Not Block in Callbacks

Applications must not block in and should return as quickly as possible from message receive, event and timer callbacks so that the calling thread can process the next message, event or timer and perform internal API housekeeping. The one exception is for transacted sessions. Applications can call API-provided blocking functions such as commit, rollback and send from within the message receive callback of a transacted session.

Queues and Flows

Receiving One Message at a Time


  • Setting max-delivered-unacked-msgs-per-flow to 1 and AD Window Size to 1 to ensure messages are delivered from the event broker to the client application one message at a time and in a time-consistent manner.

An API only sends transport acknowledgments when either,

  1. it has received the configured acknowledgment threshold worth of configured Assured Delivery (AD) window messages (i.e. 60%)
  2. a message has been received and the configured AD acknowledgment time as passed since the last acknowledgment was sent (i.e. 1 seconds), whichever comes first.

The application acknowledgment piggybacks on the transport acknowledgment for the delivery from the client application to the event broker. And the event broker only releases further messages once it receives the acknowledgment.

Therefore, while setting max-delivered-unacked-msgs-per-flow to 1 will ensure that messages are delivered to the client application one at a time, if the AD window size is not 1, then condition 1 will not be immediately fulfilled. This will result in a reception delay variation since the API will only send the acknowledgment after condition 2 is fulfilled, and is therefore not consistent with the expected end-to-end message receipt delivery delay.

Refer to Configuring Max Permitted Number of Delivered Unacked Messages for instructions on how to configure max-delivered-unacked-msgs-per-flow on queues.

Setting Temporary Endpoint Spool Size


  • Exercise caution if a client application frequently creates temporary endpoints to ensure that the sum of all temporary endpoint spool sizes does not exceed the total spool size provisioned for the Message VPN.

By default, the message spool quota of a Message VPN and endpoint is based on an over-subscription model. For instance, it's possible to set the message spool quota of multiple endpoints to the same quota as that of an entire Message VPN. Temporary endpoints created by a client application default to 4000 MB for the Solace application and 1500 MB for the software event broker. When temporary endpoints are used extensively by a client application, the message spool over-subscription model can quickly get out-of-control when temporary endpoints are being created on-demand. Therefore, it's recommended that a client application overwrite an endpoint’s default message spool size to a value that is inline with expected usage, especially if temporary endpoints are heavily used.

AD Window Size and max-delivered-unacked-msgs-per-flow


  • The AD window size configured on the API should not be greater than the max-delivered-unacked-msgs-per-flow value that is set for a queue on the event broker.

max-delivered-unacked-msgs-per-flow controls how many messages the event broker can deliver to the client application without receiving back an acknowledgment. The Assured Delivery (AD) window size controls how many messages can be in transit between the event broker and the client application. So, if the AD window size is greater than max-delivered-unacked-msgs-per-flow, then the API may not be able to acknowledge the messages it receives in a timely manner. Effectively, the AD window size is bounded by the value set for max-delivered-unacked-msgs-per-flow. For instance, if the AD window size is set to 10, and max-delivered-unacked-msgs-per-flow is set to 5, then the event broker will effectively be limited to send out 5 messages at a time regardless of the client application’s AD window size setting of 10.

Refer to Configuring Max Permitted Number of Delivered Unacked Messages for instructions on how to set up max-delivered-unacked-msgs-per-flow on queues.

Number of Flows and AD Window Size


  • Size the expected number of flows per session, and its associated AD window size, to within the available memory limit of the client application host, and within the default work units allocated per client egress queue on the event broker.

The API buffers received Guaranteed messages and, in general, also owns the messages and is responsible for freeing them. The amount of buffers used by a client is primarily determined by multiplying the Assured Delivery (AD) window size by the number of flows used per session. For example, if a receiving client application is using flows with an AD window size of 255 to bind to 10 different queues on an event broker, then the maximum buffer usage, given an average message size of 1 M, will be 2560 MB. If there are 10 such clients running on the same host, then 25.6 G of memory will be required.

Similarly, the event broker dedicates a per-client egress queue to buffer the to be transmitted messages to the client application. By default, this is 20,000 work units, or an equivalent of 40 M worth of buffer as each work unit is 2048 bytes. For a per-client egress queue to support 2560 MB worth of buffering, the number of work units for this particular client will need to be increased to 130,560. Hence, depending on application usage, it's recommended that you dimension the AD window size in relation to the number of expected flows per session such that it will be within the default 20,000 work units worth of buffer per client connection.

Error Handling and Logging

Logging and Log Level


  • Client Application Debug level logging should not be enabled in production environments.

Client Application Event logging can have a significant impact on performance, and so, in a production environment, it's not recommended to enable debug level logging.

Verbose log levels such as debug and info may cause the JVM to perform garbage collection. This will unintentionally contradict the design principle behind the JavaRTO API which is to cause no garbage collection within the JVM.

Handling Session Events / Errors


  • Client Applications should register an implementation of the Session Event handler interface / delegate / callback when creating a Session to receive Session events.

Client applications should register an implementation of the Session Event Handler interface / delegate / callback when creating a Session to receive Session events. A complete list of Session Event is listed in the table below. Subsequently, Session events should be handled appropriately based on client application usage.

Session Events

JavaRTO (SolEnum. SessionEventCode) Description


The oldest transmitted Persistent/Non Persistent message that has been acknowledged.


Guaranteed Delivery Publishing is not available.


The send is no longer blocked.


The Session attempted to connect but was unsuccessful.


The Session was established and then went down.


The session property modification failed.


The session property modification completed.


The endpoint create/delete command failed.


The endpoint create/delete command completed.


The automatic reconnect of the Session was successful, and the Session was established again.


The Session has gone down, and an automatic reconnect attempt is in progress.


The appliance rejected a published message.


After successfully reconnecting a disconnected session, the API received an unknown publisher flow name response when reconnecting the Guaranteed Delivery publisher flow.


The API discarded a received message that exceeded the Session buffer size.


The application rejected a subscription (add or remove).


The subscribe or unsubscribe operation has succeeded.


The Topic Endpoint unsubscribe command failed.


The Topic Endpoint unsubscribe completed.


The Session is established


The appliance’s Virtual Router Name changed during a reconnect operation.

Handling Flow Events / Errors


  • Client applications should register an implementation of the Flow Event handler interface / delegate / callback when creating a Flow to receive Flow events.

Client applications should register an implementation of the Flow Event Handler interface / delegate / callback when creating a Flow to receive Flow events. Flow error / events should be handled appropriately based on client application usage.

Flow Events

JavaRTO (SolEnum. FlowEventCode) Description


The Flow is established


The Flow was established and then disconnected by the appliance, likely due to operator intervention.


The Flow attempted to connect but was unsuccessful.


The Session for the Flow was disconnected.


The Flow has become active.


The Flow has become inactive.


When Flow Reconnect is enabled, instead of a DOWN_ERROR event, the API generates this event and attempts to rebind the Flow.

If the Flow rebind fails, the API monitors the bind failure and terminates the reconnecting attempts with a DOWN_ERROR unless the failure reason is one of the following:

  • Queue Shutdown
  • Topic Endpoint Shutdown
  • Service Unavailable

For more information about Flow Reconnect, refer to Flow Reconnect.


The Flow has been successfully reconnected.

Event Broker Configuration that Influences Client Application Behavior

Max Redelivery


  • By default, messages are to be redelivered indefinitely from endpoints to clients. Set the maximum redelivery option on endpoints at the event broker, when appropriate, to limit the maximum number of message redeliveries per message.

The maximum redelivery option can be set on an endpoint to control the number of deliveries per message on that endpoint. After the maximum number of redeliveries by the endpoint is exceeded, messages are either discarded or moved to the Dead Message Queue (DMQ), if it's configured and the messages are set to DMQ eligible.

There are benefits for client applications when the number of redeliveries on an endpoint is not infinite (by default the redelivery mode is set to redelivery forever). For instance, if a client application is unable to handle unexpected poison messages, the message will eventually be discarded or moved to DMQ where further examination can take place.

Reject Message to Sender on Discard


  • reject-msg-to-sender-on-discard on an endpoint should be enabled unless there are good reasons not to.

When publishing guaranteed messages to an event broker, messages can be discarded for reasons such as message-spool full, maximum message size exceeded, endpoint shutdown, and so on. If the message discard option on the endpoint, that is, reject-msg-to-sender-on-discard, is enabled, then the client application will be able to detect that discarding is happening and take corrective action such as pausing publication. There is no explicit support at the API to pause publication; this should be carried out by the client application logic.

One reason to consider disabling reject-msg-to-send-on-discard is the situation where there are multiple queues subscribing to the same topic that the Guaranteed messages are published to, and the intent is for other queues to continue receiving messages even if one of the queues is deemed unable to accept messages.