Skip to content

Performance Considerations

Formatter performance matters when applications publish or consume high message volumes.

The most important factors are:

  • serialization cost;
  • payload size;
  • memory allocations;
  • garbage collection pressure;
  • message throughput.

Payload Pipeline

A broker payload is ultimately a binary payload.

graph LR
    Object["CLR object"]
    Json["JSON"]
    Payload["byte[]"]
    RabbitMQ

    Object --> Json
    Json --> Payload
    Payload --> RabbitMQ

Different formatter implementations reach this payload in different ways.


MsJsonDataFormatter

MsJsonDataFormatter uses System.Text.Json and serializes directly to UTF-8 bytes.

graph LR
    Object["CLR object"]
    STJ["System.Text.Json"]
    Payload["byte[]"]

    Object --> STJ
    STJ --> Payload

This avoids creating an intermediate JSON string before producing the broker payload.


JsonDataFormatter

JsonDataFormatter uses JsonConvert and then converts the JSON string to bytes.

graph LR
    Object["CLR object"]
    JsonConvert
    Json["JSON string"]
    Encoding
    Payload["byte[]"]

    Object --> JsonConvert
    JsonConvert --> Json
    Json --> Encoding
    Encoding --> Payload

This model is simple and compatible with Newtonsoft.Json behavior.


RwJsonDataFormatter

RwJsonDataFormatter uses a reader/writer pipeline.

graph LR
    Object["CLR object"]
    Serializer["JsonSerializer"]
    Writer["JsonTextWriter"]
    StringWriter
    Json["JSON string"]
    Encoding
    Payload["byte[]"]

    Object --> Serializer
    Serializer --> Writer
    Writer --> StringWriter
    StringWriter --> Json
    Json --> Encoding
    Encoding --> Payload

It was introduced to reduce temporary allocations and garbage collection pressure in high-throughput scenarios.


What To Measure

Do not choose a formatter based only on theoretical performance.

Measure:

  • average serialization time;
  • average deserialization time;
  • allocated bytes per message;
  • Gen 0 / Gen 1 / Gen 2 collections;
  • throughput under realistic load;
  • payload size.

Practical Guidance

Use MsJsonDataFormatter when:

  • System.Text.Json is acceptable;
  • low allocation and direct UTF-8 serialization are desired;
  • the application is modern .NET.

Use RwJsonDataFormatter when:

  • Newtonsoft.Json is required;
  • allocation pressure must be reduced;
  • the workload is message-heavy.

Use JsonDataFormatter when:

  • simplicity matters more than allocation optimization;
  • Newtonsoft.Json compatibility is the main requirement.

Avoid Premature Optimization

Formatter choice should follow compatibility first, then performance.

Recommended decision order:

  1. Choose the serializer family required by the application.
  2. Confirm both publisher and subscriber can read the same payload format.
  3. Measure performance under realistic message volume.
  4. Optimize formatter choice if serialization becomes a bottleneck.