Message passing via a create vs an exercise

AFAICT, there are at least two ways to pass a message to a stream integration:

  1. Create a contract with the message payload and immediately archive it, and the integration listens to creates for that template.
  2. Create a stateless contract and exercise a non-consuming choice with the message payload in the arguments. Here the integration subscribes to transaction tree stream and listens for exercises.

Is one of these approaches more performant than the other? The first is a create + exercise and the second is a fetch + exercise. My intuition is that fetches are cheaper than creates, but I have no evidence one way or the other.

I’d generally stay away from 2. Daml should be written in a way that’s agnostic to the choice of integration, and 2 does not work if the integration uses the JSON API for example.

Consider that the Ledger API exposes primitives to create and exercise as a single operation. This means that the contract being “created” never needs to be persisted beyond the boundary of the transaction, meaning one less trip to the persistence layer. So, performance-wise, I would say using a CreateAndExercise command should be faster.

However, performance is an infinitely complex topic and what I really recommend is to measure, assess and improve if and where needed. Are you aware of this difference being a performance bottleneck in your application? If not, I would solely base your decision based on how well this interacts with the rest of your application and the composability of your approach with other parts of your Daml model.

Intuitively I’d probably use the first option but I’m not 100% sure of the specific problem you are trying to solve.

Yes, this is probably a case of premature optimization on my part. From the integration point-of-view it’s slightly easier to use the flat transaction stream, so I’ll go with option 1 as well. Thanks for the help.

1 Like

Neither works for the JSON API. From docs: