LogIn
I don't have account.
Sponsored -53%
Zebronics #1 Best Seller

ZEBRONICS Blanc Slim Wireless Mouse — Rechargeable, BT + 2.4GHz (Black)

Up to 1600 DPI · Silent clicks · 63g · Multicolor LED

★★★★★ 4.0 (9,512) 5K+ bought last month
₹376 M.R.P. ₹799Save ₹423
Buy Now
Adℹ

Achieving 10x Faster Serialization in .NET: A High-Performance Guide

Ajeet Pawar
55 Views

#performance

Amazon Pay offer
Adℹ

In the world of high-performance backend engineering, serialization is often the "silent killer." We spend weeks optimizing database queries and fine-tuning load balancers, only to let our CPU cycles wither away translating objects into strings.

In .NET, serialization is the process of converting an object's state into a byte stream or string (typically JSON or XML) for storage or transmission. In a modern microservices architecture, serialization happens at every hop: an API receives a JSON request, fetches data from a cache (deserialization) , queries a database and finally sends a JSON response.

When you scale to millions of requests, even a 5ms serialization overhead becomes a massive bottleneck, leading to increased latency, higher cloud egress costs and aggressive Garbage Collection (GC) pressure. This guide explores how to move beyond default configurations to achieve 10x throughput.

Understanding Serialization in .NET

At its core, serialization is a bridge between the structured world of the Heap and the flat world of the Network. Historically, .NET relied heavily on reflection-based serialization.

The Cost of Reflection

Traditional serializers like Newtonsoft.Json (Json.NET) use Reflection to inspect types at runtime. While flexible, this approach requires the CPU to "discover" properties, attributes and constructors every time an object is processed. Even with internal caching, the metadata lookup and dynamic invocation introduce significant overhead compared to pre-compiled code.

Memory and the GC

Serialization isn't just a CPU problem. it's a memory problem. Inefficient serializers create thousands of short-lived string objects and intermediate buffers. This triggers the Garbage Collector (GC) to run more frequently, causing "Stop-the-World" pauses that spike your P99 latency.

Why Serialization Becomes a Performance Bottleneck

The bottleneck usually stems from three main factors:

  • Allocation Heavy Patterns: Creating new strings for every property name.

  • Deep Object Graphs: Recursively traversing complex relationships.

  • Synchronous I/O: Blocking threads while waiting for a large JSON payload to be written to a stream.

Example: The "Slow" Pattern

// Conventional, but slow for high-throughput systems
public string GetSerializedData(UserPreferences prefs)
{
    // High allocation, reflection-based
    return JsonConvert.SerializeObject(prefs); 
}

In a high-scale system, the code above creates a new string in the Large Object Heap (LOH) if the JSON is big enough, leading to fragmentation and performance degradation.

Benchmarking Serialization Performance

Before optimizing, you must measure. In the .NET ecosystem, BenchmarkDotNet is the industry standard. It provides nanosecond-level precision and tracks memory allocations.

When benchmarking, focus on:

  • Mean Execution Time: How long does a single operation take?

  • Allocated Memory: How many bytes were allocated per operation?

  • Gen 0/1/2 Collections: How often did the GC have to clean up after your serializer?

Techniques to Achieve 10x Faster Serialization

1. Migrate to System.Text.Json

Introduced in .NET Core 3.0, System.Text.Json was built from the ground up for performance. It leverages Span and Utf8JsonReader/Writer to process data directly in UTF-8, avoiding expensive string conversions.

Because it works directly with UTF-8 encoded data, it avoids many costly conversions between strings and byte arrays. This reduces memory allocations and significantly improves serialization and deserialization performance, which is especially important for high-throughput APIs, microservices, and data-intensive applications.

Another advantage is that System.Text.Json is built into modern .NET runtimes, meaning there is no need to install additional libraries for most use cases.


// Serialize Object to JSON
string json = JsonSerializer.Serialize(user);

// Deserialize JSON to Object
User user = JsonSerializer.Deserialize<User>(json);

2. Leverage Source-Generated Serialization

Starting with .NET 6, System.Text.Json introduced source-generated serialization, which moves much of the serialization metadata generation from runtime to compile time. Traditionally, serializers relied on reflection to inspect types during execution. Source generators eliminate this overhead by generating optimized serialization code during the build process.

This approach improves performance and reduces startup overhead, which is especially useful in high-throughput APIs, microservices and large-scale applications.

Define a Source Generation Context


using System.Text.Json.Serialization;

[JsonSourceGenerationOptions(WriteIndented = false)]
[JsonSerializable(typeof(UserDTO))]
internal partial class MyJsonContext : JsonSerializerContext
{
}

In this example:

  • JsonSerializable(typeof(UserDTO)) tells the compiler to generate serialization metadata for UserDTO.
  • JsonSourceGenerationOptions allows configuration such as formatting and naming policies.
  • The partial class MyJsonContext is completed automatically during compilation.

Serialize Using the Generated Context

string json = JsonSerializer.Serialize(myUser, MyJsonContext.Default.UserDTO);

This uses the pre-generated metadata instead of reflection.

Deserialize Using the Generated Context

UserDTO user = JsonSerializer.Deserialize(json, MyJsonContext.Default.UserDTO);

The deserializer also uses the generated metadata for faster processing.

Why It's Faster

Source-generated serialization improves performance because:

  • Reflection is avoided, reducing runtime overhead.
  • Metadata for serialization is precomputed at compile time.
  • The JIT compiler can better optimize the generated serialization logic.
  • Startup time improves, which is important for cloud services and microservices.

For performance-sensitive applications, combining System.Text.Json with source-generated serializers can significantly reduce serialization overhead and improve overall throughput.

3. Switch to Binary Formats (ProtoBuf / MessagePack)

If you control both the client and the server for example in internal microservices or service-to-service communication JSON may not be the most efficient format. In such cases, binary serialization formats like Protocol Buffers (ProtoBuf) or MessagePack can offer significantly better performance.

Unlike JSON, which stores property names as text, binary formats store data in a compact binary representation. This results in:

  • Smaller payload sizes
  • Faster serialization and deserialization
  • Reduced network bandwidth usage

These advantages make binary formats particularly useful for high-performance distributed systems.

Example Using ProtoBuf

First, define a class using ProtoBuf attributes:


using ProtoBuf;

[ProtoContract]
public class UserDTO
{
    [ProtoMember(1)]
    public int Id { get; set; }
    [ProtoMember(2)]
    public string Name { get; set; }
}

Here:

  • [ProtoContract] marks the class as serializable by ProtoBuf.
  • [ProtoMember(n)] defines the field order used in the binary format.

Serialize Object to Binary


using ProtoBuf;
using System.IO;

using var stream = new MemoryStream();
Serializer.Serialize(stream, user);
byte[] data = stream.ToArray();

This converts the object into a compact binary representation.

Deserialize Binary to Object


using ProtoBuf;
using System.IO;

using var stream = new MemoryStream(data);
UserDTO user = Serializer.Deserialize<UserDTO>(stream);

This reconstructs the object from the binary data.

Why It's Faster

Binary formats improve performance because:

  • Field names are not stored repeatedly in the payload
  • Data is encoded in a compact binary structure
  • Serialization requires less parsing compared to JSON

For systems where performance and network efficiency are critical, using ProtoBuf or MessagePack can significantly reduce serialization overhead and improve throughput.

4. Use Span and Memory-Efficient APIs

Modern versions of .NET provide low-level APIs that allow you to work directly with UTF-8 byte buffers instead of allocating intermediate strings. By writing JSON directly into a buffer using interfaces like IBufferWriter or working with Span/ReadOnlySpan, you can significantly reduce memory allocations and improve performance.

This approach is particularly useful in high-performance APIs, streaming pipelines and networking scenarios where avoiding unnecessary allocations can reduce GC pressure.

Example: Writing JSON with Utf8JsonWriter

Utf8JsonWriter allows you to write JSON directly into a buffer.


using System.Buffers;
using System.Text.Json;

var buffer = new ArrayBufferWriter<byte>();
using (var writer = new Utf8JsonWriter(buffer))
{
    writer.WriteStartObject();
    writer.WriteNumber("Id", 1);
    writer.WriteString("Name", "Alice");
    writer.WriteEndObject();
}

byte[] jsonBytes = buffer.WrittenSpan.ToArray();

Here:

  • ArrayBufferWriter implements IBufferWriter.
  • JSON is written directly into a byte buffer without creating intermediate strings.

Example: Using JsonSerializer with IBufferWriter


using System.Buffers;
using System.Text.Json;

var buffer = new ArrayBufferWriter<byte>();
JsonSerializer.Serialize(buffer, user);
byte[] jsonBytes = buffer.WrittenSpan.ToArray();

This serializes the object directly into the buffer, avoiding unnecessary conversions.

Why It's Faster

Using Span-based and buffer-based APIs improves performance because:

  • It avoids creating intermediate strings
  • It reduces memory allocations
  • It minimizes garbage collection pressure
  • It works directly with UTF-8 byte data

For performance-critical applications such as high-throughput web APIs, real-time systems and streaming services, these memory efficient APIs can significantly improve serialization efficiency.

5. Reduce Object Graph Complexity

Serialization performance is closely related to the size and complexity of the object graph being serialized. The more properties, nested objects and relationships a class contains, the more work the serializer must perform. Large entities especially those coming directly from ORM frameworks like Entity Framework, often contain unnecessary fields, navigation properties, circular references and lazy-loading proxies that slow down serialization.

A common best practice is to create Serialization DTOs (Data Transfer Objects) that include only the fields required by the API response or data transfer. Instead of serializing the entire database entity, you map the entity to a simplified DTO.

This approach improves performance, reduces payload size and avoids issues such as circular reference errors.

Example: Database Entity (Complex Object)


public class UserEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public List<OrderEntity> Orders { get; set; }
}

This entity may include relationships, navigation properties and additional metadata that are not required in an API response.

Example: Serialization DTO (Simplified)


public class UserDTO
{
    public int Id { get; set; }
    public string Name { get; set; }
}

The DTO only contains the fields that need to be exposed.

Mapping Entity to DTO


UserDTO dto = new UserDTO
{
    Id = userEntity.Id,
    Name = userEntity.Name
};

Then serialize the DTO:

string json = JsonSerializer.Serialize(dto);

Why This Improves Performance

Reducing object graph complexity provides several benefits:

  • Fewer properties to serialize
  • Smaller JSON payload size
  • No circular reference issues
  • Better control over exposed data

For high-performance APIs and microservices, using dedicated serialization DTOs instead of full database entities is an effective way to improve both performance and maintainability.

Real-World Performance Comparison

Serializer Speed (Relative) Memory Allocated Best For
Newtonsoft.Json 1x (Baseline) High Legacy apps, complex features
System.Text.Json 2.5x - 3x Low Standard Web APIs
STJ + Source Gen 4x - 6x Minimal High-scale microservices
ProtoBuf-Net 10x+ Near Zero Internal RPC / gRPC

Common Serialization Mistakes

  • Default Settings Overuse: Keeping WriteIndented = true in production increases payload size because it adds extra whitespace for formatting. This is useful for debugging but unnecessary for production APIs.

  • Ignoring Case Sensitivity: Using PropertyNameCaseInsensitive = true can slightly slow down deserialization because the serializer must perform additional comparisons. If possible, keep consistent property naming instead.

  • Re-instantiating Options: Creating a new JsonSerializerOptions instance for every serialization call prevents the internal metadata cache from being reused, which hurts performance. Instead, reuse a single static instance of JsonSerializerOptions.

Best Practices for High-Performance Serialization

1. Reuse Options

Avoid creating JsonSerializerOptions repeatedly. Instead, reuse a single static instance so the serializer can reuse its internal metadata cache.


static readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

2. Stream, Don't String

Instead of serializing to a string and then writing it to a response, serialize directly to the response stream. This reduces memory allocations and improves throughput.

await JsonSerializer.SerializeAsync(responseStream, data, _options);

3. Use UTF-8 Data

System.Text.Json works natively with UTF-8. Try to keep data in byte[] or Span form as long as possible and avoid unnecessary conversions to string.

byte[] jsonBytes = JsonSerializer.SerializeToUtf8Bytes(data);

4. Trim Unused Properties

Reduce payload size by excluding unnecessary fields using [JsonIgnore]. Smaller objects serialize faster and produce smaller network responses.


public class User
{
    public int Id { get; set; }
    [JsonIgnore]
    public string InternalToken { get; set; }
}

Conclusion

Achieving significantly faster serialization is not the result of a single configuration change. Instead, it comes from combining the right tools, efficient APIs and thoughtful design choices. Serialization performance is closely tied to how efficiently your application uses CPU and memory, so small improvements in this area can have a noticeable impact on overall system performance.

Modern .NET applications benefit greatly from using System.Text.Json, especially when combined with source-generated serialization. This approach removes much of the reflection overhead traditionally associated with JSON serialization and allows the runtime to execute optimized, compile-time generated code.

In scenarios where both the client and server are under your control such as internal services or microservice architectures switching to binary serialization formats like Protocol Buffers (ProtoBuf) or MessagePack can further reduce payload size and improve processing speed.

A practical starting point is to benchmark the parts of your application where serialization occurs most frequently, such as API responses, caching layers or message queues. Performance tools and profiling can help identify the hottest paths where serialization overhead is highest.

In many real-world systems, meaningful performance improvements come from simple changes such as replacing older serialization calls, reducing object complexity or switching to more efficient APIs. By applying these improvements thoughtfully, you can reduce latency, lower memory usage and improve the scalability of your applications.

Responses (0)

Write a response

CommentHide Comments

No Comments yet.

"},"4":{"id":4,"name":"ZEBRONICS Blanc mouse ad","otherData":"{}","contentFormat":2,"content":"
Sponsored -53%
Zebronics #1 Best Seller

ZEBRONICS Blanc Slim Wireless Mouse — Rechargeable, BT + 2.4GHz (Black)

Up to 1600 DPI · Silent clicks · 63g · Multicolor LED

★★★★★ 4.0 (9,512) 5K+ bought last month
₹376 M.R.P. ₹799Save ₹423
Buy Now
"},"2":{"id":2,"name":"Crousal Ads","otherData":"{}","contentFormat":2,"content":"
Sponsored -34%
iQOO Amazon's Choice

iQOO Z10 Lite 5G — Cyber Green, 4GB RAM, 128GB Storage

Dimensity 6300 · 50MP Sony AI Camera · 6000 mAh · IP64

★★★★★ 4.0 (2,052) 500+ bought last month
₹18,997 M.R.P. ₹28,999Save ₹10,002
Buy Now
"},"1":{"id":1,"name":"Banner Ads","otherData":"{}","contentFormat":2,"content":"\n
\n \n \n \"Amazon\n \n
"}}},"blogDetails":{"isWriter":false,"likes":0,"isLikedByUser":false,"tagIds":[229,287],"tags":[{"id":229,"name":".NET Core","maskingName":"dot-net-core","isFeatured":true},{"id":287,"name":"Performance","maskingName":"performance","isFeatured":false}],"comments":[],"bookmark":{"isBookmarked":false,"count":0},"author":{"userId":"MjlfNF84LVsyMF0ybi10Q19BTmdlX19JdA==","name":"Ajeet Pawar"},"viewCount":54,"showBannerImage":false,"seoTags":".NET serialization performance, System.Text.Json performance, faster JSON serialization .NET, .NET serialization optimization, source generated serialization, ProtoBuf serialization .NET, MessagePack .NET, high performance serialization .NET, Utf8JsonWriter .NET, Span serialization .NET, JsonSerializerOptions performance, optimize .NET API performance","content":"

In the world of high-performance backend engineering, serialization is often the \"silent killer.\" We spend weeks optimizing database queries and\nfine-tuning load balancers, only to let our CPU cycles wither away translating objects into strings.

\n

In .NET, serialization is the process of converting an object's state into a byte stream or string (typically JSON or XML) for storage or transmission.\nIn a modern microservices architecture, serialization happens at every hop: an API receives a JSON request, fetches data from a cache (deserialization)\n, queries a database and finally sends a JSON response.

\n

When you scale to millions of requests, even a 5ms serialization overhead becomes a massive bottleneck, leading to increased latency, higher cloud\negress costs and aggressive Garbage Collection (GC) pressure. This guide explores how to move beyond default configurations to achieve 10x throughput.

\n

Understanding Serialization in .NET

\n

At its core, serialization is a bridge between the structured world of the Heap and the flat world of the Network. Historically, .NET relied\nheavily on reflection-based serialization.

\n

The Cost of Reflection

\n

Traditional serializers like Newtonsoft.Json (Json.NET) use Reflection to inspect types at runtime. While flexible, this approach requires the CPU\nto \"discover\" properties, attributes and constructors every time an object is processed. Even with internal caching, the metadata lookup and dynamic\ninvocation introduce significant overhead compared to pre-compiled code.

\n

Memory and the GC

\n

Serialization isn't just a CPU problem. it's a memory problem. Inefficient serializers create thousands of short-lived string objects and\nintermediate buffers. This triggers the Garbage Collector (GC) to run more frequently, causing \"Stop-the-World\" pauses that spike your P99 latency.

\n

Why Serialization Becomes a Performance Bottleneck

\n

The bottleneck usually stems from three main factors:

\n\n

Example: The \"Slow\" Pattern

\n
// Conventional, but slow for high-throughput systems\npublic string GetSerializedData(UserPreferences prefs)\n{\n    // High allocation, reflection-based\n    return JsonConvert.SerializeObject(prefs); \n}\n
\n

In a high-scale system, the code above creates a new string in the Large Object Heap (LOH) if the JSON is big enough, leading to fragmentation\nand performance degradation.

\n

Benchmarking Serialization Performance

\n

Before optimizing, you must measure. In the .NET ecosystem, BenchmarkDotNet is the industry standard. It provides nanosecond-level precision and\ntracks memory allocations.

\n

When benchmarking, focus on:

\n\n

Techniques to Achieve 10x Faster Serialization

\n

1. Migrate to System.Text.Json

\n

Introduced in .NET Core 3.0, System.Text.Json was built from the ground up for performance. It leverages Span and Utf8JsonReader/Writer\nto process data directly in UTF-8, avoiding expensive string conversions.

\n

Because it works directly with UTF-8 encoded data, it avoids many costly conversions between strings and byte arrays. This reduces memory allocations and significantly improves serialization and deserialization performance, which is especially important for high-throughput APIs, microservices, and data-intensive applications.

\n

Another advantage is that System.Text.Json is built into modern .NET runtimes, meaning there is no need to install additional libraries for most use cases.

\n
\n// Serialize Object to JSON\nstring json = JsonSerializer.Serialize(user);\n\n// Deserialize JSON to Object\nUser user = JsonSerializer.Deserialize<User>(json);\n
\n

2. Leverage Source-Generated Serialization

\n

Starting with .NET 6, System.Text.Json introduced source-generated serialization, which moves much of the serialization metadata\ngeneration from runtime to compile time. Traditionally, serializers relied on reflection to inspect types during execution. Source generators\neliminate this overhead by generating optimized serialization code during the build process.

\n

This approach improves performance and reduces startup overhead, which is especially useful in high-throughput APIs, microservices\nand large-scale applications.

\n

Define a Source Generation Context

\n
\nusing System.Text.Json.Serialization;\n\n[JsonSourceGenerationOptions(WriteIndented = false)]\n[JsonSerializable(typeof(UserDTO))]\ninternal partial class MyJsonContext : JsonSerializerContext\n{\n}\n
\n

In this example:

\n\n

Serialize Using the Generated Context

\n
string json = JsonSerializer.Serialize(myUser, MyJsonContext.Default.UserDTO);\n
\n

This uses the pre-generated metadata instead of reflection.

\n

Deserialize Using the Generated Context

\n
UserDTO user = JsonSerializer.Deserialize(json, MyJsonContext.Default.UserDTO);\n
\n

The deserializer also uses the generated metadata for faster processing.

\n

Why It's Faster

\n

Source-generated serialization improves performance because:

\n\n

For performance-sensitive applications, combining System.Text.Json with source-generated serializers can significantly reduce serialization\noverhead and improve overall throughput.

\n

3. Switch to Binary Formats (ProtoBuf / MessagePack)

\n

If you control both the client and the server for example in internal microservices or service-to-service communication JSON may not be the most\nefficient format. In such cases, binary serialization formats like Protocol Buffers (ProtoBuf) or MessagePack can offer significantly better\nperformance.

\n

Unlike JSON, which stores property names as text, binary formats store data in a compact binary representation. This results in:

\n\n

These advantages make binary formats particularly useful for high-performance distributed systems.

\n

Example Using ProtoBuf

\n

First, define a class using ProtoBuf attributes:

\n
\nusing ProtoBuf;\n\n[ProtoContract]\npublic class UserDTO\n{\n    [ProtoMember(1)]\n    public int Id { get; set; }\n    [ProtoMember(2)]\n    public string Name { get; set; }\n}\n
\n

Here:

\n\n

Serialize Object to Binary

\n
\nusing ProtoBuf;\nusing System.IO;\n\nusing var stream = new MemoryStream();\nSerializer.Serialize(stream, user);\nbyte[] data = stream.ToArray();\n
\n

This converts the object into a compact binary representation.

\n

Deserialize Binary to Object

\n
\nusing ProtoBuf;\nusing System.IO;\n\nusing var stream = new MemoryStream(data);\nUserDTO user = Serializer.Deserialize<UserDTO>(stream);\n
\n

This reconstructs the object from the binary data.

\n

Why It's Faster

\n

Binary formats improve performance because:

\n\n

For systems where performance and network efficiency are critical, using ProtoBuf or MessagePack can significantly reduce serialization overhead\nand improve throughput.

\n

4. Use Span and Memory-Efficient APIs

\n

Modern versions of .NET provide low-level APIs that allow you to work directly with UTF-8 byte buffers instead of allocating intermediate strings.\nBy writing JSON directly into a buffer using interfaces like IBufferWriter or working with Span/ReadOnlySpan, you can\nsignificantly reduce memory allocations and improve performance.

\n

This approach is particularly useful in high-performance APIs, streaming pipelines and networking scenarios where avoiding unnecessary allocations\ncan reduce GC pressure.

\n

Example: Writing JSON with Utf8JsonWriter

\n

Utf8JsonWriter allows you to write JSON directly into a buffer.

\n
\nusing System.Buffers;\nusing System.Text.Json;\n\nvar buffer = new ArrayBufferWriter<byte>();\nusing (var writer = new Utf8JsonWriter(buffer))\n{\n    writer.WriteStartObject();\n    writer.WriteNumber(\"Id\", 1);\n    writer.WriteString(\"Name\", \"Alice\");\n    writer.WriteEndObject();\n}\n\nbyte[] jsonBytes = buffer.WrittenSpan.ToArray();\n
\n

Here:

\n\n

Example: Using JsonSerializer with IBufferWriter

\n
\nusing System.Buffers;\nusing System.Text.Json;\n\nvar buffer = new ArrayBufferWriter<byte>();\nJsonSerializer.Serialize(buffer, user);\nbyte[] jsonBytes = buffer.WrittenSpan.ToArray();\n
\n

This serializes the object directly into the buffer, avoiding unnecessary conversions.

\n

Why It's Faster

\n

Using Span-based and buffer-based APIs improves performance because:

\n\n

For performance-critical applications such as high-throughput web APIs, real-time systems and streaming services, these memory efficient APIs\ncan significantly improve serialization efficiency.

\n

5. Reduce Object Graph Complexity

\n

Serialization performance is closely related to the size and complexity of the object graph being serialized. The more properties, nested objects\nand relationships a class contains, the more work the serializer must perform. Large entities especially those coming directly from ORM frameworks\nlike Entity Framework, often contain unnecessary fields, navigation properties, circular references and lazy-loading proxies that slow down\nserialization.

\n

A common best practice is to create Serialization DTOs (Data Transfer Objects) that include only the fields required by the API response or data\ntransfer. Instead of serializing the entire database entity, you map the entity to a simplified DTO.

\n

This approach improves performance, reduces payload size and avoids issues such as circular reference errors.

\n

Example: Database Entity (Complex Object)

\n
\npublic class UserEntity\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n    public string Email { get; set; }\n    public List<OrderEntity> Orders { get; set; }\n}\n
\n

This entity may include relationships, navigation properties and additional metadata that are not required in an API response.

\n

Example: Serialization DTO (Simplified)

\n
\npublic class UserDTO\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n}\n
\n

The DTO only contains the fields that need to be exposed.

\n

Mapping Entity to DTO

\n
\nUserDTO dto = new UserDTO\n{\n    Id = userEntity.Id,\n    Name = userEntity.Name\n};\n
\n

Then serialize the DTO:

\n
string json = JsonSerializer.Serialize(dto);\n
\n

Why This Improves Performance

\n

Reducing object graph complexity provides several benefits:

\n\n

For high-performance APIs and microservices, using dedicated serialization DTOs instead of full database entities is an effective way to improve\nboth performance and maintainability.

\n

Real-World Performance Comparison

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
SerializerSpeed (Relative)Memory AllocatedBest For
Newtonsoft.Json1x (Baseline)HighLegacy apps, complex features
System.Text.Json2.5x - 3xLowStandard Web APIs
STJ + Source Gen4x - 6xMinimalHigh-scale microservices
ProtoBuf-Net10x+Near ZeroInternal RPC / gRPC
\n

Common Serialization Mistakes

\n\n

Best Practices for High-Performance Serialization

\n

1. Reuse Options

\n

Avoid creating JsonSerializerOptions repeatedly. Instead, reuse a single static instance so the serializer can reuse its internal metadata\ncache.

\n
\nstatic readonly JsonSerializerOptions _options = new JsonSerializerOptions\n{\n    PropertyNamingPolicy = JsonNamingPolicy.CamelCase\n};\n
\n

2. Stream, Don't String

\n

Instead of serializing to a string and then writing it to a response, serialize directly to the response stream. This reduces memory allocations\nand improves throughput.

\n
await JsonSerializer.SerializeAsync(responseStream, data, _options);\n
\n

3. Use UTF-8 Data

\n

System.Text.Json works natively with UTF-8. Try to keep data in byte[] or Span form as long as possible and avoid unnecessary conversions\nto string.

\n
byte[] jsonBytes = JsonSerializer.SerializeToUtf8Bytes(data);\n
\n

4. Trim Unused Properties

\n

Reduce payload size by excluding unnecessary fields using [JsonIgnore]. Smaller objects serialize faster and produce smaller network responses.

\n
\npublic class User\n{\n    public int Id { get; set; }\n    [JsonIgnore]\n    public string InternalToken { get; set; }\n}\n
\n

Conclusion

\n

Achieving significantly faster serialization is not the result of a single configuration change. Instead, it comes from combining the right tools,\nefficient APIs and thoughtful design choices. Serialization performance is closely tied to how efficiently your application uses CPU and memory,\nso small improvements in this area can have a noticeable impact on overall system performance.

\n

Modern .NET applications benefit greatly from using System.Text.Json, especially when combined with source-generated serialization. This approach\nremoves much of the reflection overhead traditionally associated with JSON serialization and allows the runtime to execute optimized, compile-time\ngenerated code.

\n

In scenarios where both the client and server are under your control such as internal services or microservice architectures switching to binary\nserialization formats like Protocol Buffers (ProtoBuf) or MessagePack can further reduce payload size and improve processing speed.

\n

A practical starting point is to benchmark the parts of your application where serialization occurs most frequently, such as API responses,\ncaching layers or message queues. Performance tools and profiling can help identify the hottest paths where serialization overhead is highest.

\n

In many real-world systems, meaningful performance improvements come from simple changes such as replacing older serialization calls, reducing\nobject complexity or switching to more efficient APIs. By applying these improvements thoughtfully, you can reduce latency, lower memory usage\nand improve the scalability of your applications.

","categoryId":76,"subCategoryId":76,"contentFormat":5,"blogId":49,"userId":"MjlfNF84LVsyMF0ybi10Q19BTmdlX19JdA==","title":"Achieving 10x Faster Serialization in .NET: A High-Performance Guide","url":"achieving-10x-faster-serialization-in-net-a-high-performance-guide","bannerImage":"","seoDescription":"Learn how to achieve faster JSON serialization in .NET using System.Text.Json, source generators, ProtoBuf, and memory-efficient APIs","generatedOn":"2026-03-09T14:49:55","updatedOn":"2026-03-09T14:49:55"},"popularContents":[{"id":163,"title":"Top 50 SQL Interview Questions and Answers (Beginner to Intermediate)","url":"top-sql-interview-questions-and-answers-beginner-to-intermediate","description":null,"seoDescription":"Top 50 SQL Interview Questions and Answers (Beginner to Intermediate). Top SQL Interview Questions for fresher. Frequently asked SQL interview questions with answers","contentType":2,"generatedOn":"2026-10-14T22:54:06.0065019Z","viewCount":0},{"id":138,"title":"DSA Patterns for Coding Interviews: Complete LeetCode Roadmap (Beginner to Advanced)","url":"dsa-patterns-for-coding-interviews-complete-leetcode-roadmap-beginner-to-advanced","description":null,"seoDescription":"Master every LeetCode pattern for coding interviews. Learn Arrays, Sliding Window, Graphs, Dynamic Programming, Trees, Heaps and more with 250+ curated problem","contentType":5,"generatedOn":"2026-10-14T22:54:06.007032Z","viewCount":0},{"id":34,"title":"System Design Deep Dive: 25 Essential Interview Questions","url":"system-design-deep-dive-25-essential-interview-questions","description":null,"seoDescription":"","contentType":5,"generatedOn":"2026-10-14T22:54:06.007022Z","viewCount":0},{"id":167,"title":"Meesho SDE-1 Online Assessment Interview Experience (Remote) - Rejected","url":"meesho-sde-1-online-assessment-interview-experience-remote-rejected","description":null,"seoDescription":"Read a real Meesho SDE-1 online assessment experience with coding questions, DSA topics, solutions, difficulty level, preparation tips and interview insights.","contentType":5,"generatedOn":"2026-10-14T22:54:06.0070341Z","viewCount":0},{"id":35,"title":"Cursor vs Copilot : Which AI Coding Assistant Wins in 2025?","url":"cursor-vs-copilot-which-ai-coding-assistant-truly-wins-in-2025","description":null,"seoDescription":"Compare Cursor vs GitHub Copilot on speed, context awareness, multi-file support, pricing and code quality to choose the best AI coding assistant for developers","contentType":5,"generatedOn":"2026-10-14T22:54:06.0070268Z","viewCount":0},{"id":166,"title":"System Design Interview – BIGGEST Mistakes to Avoid","url":"system-design-interview-biggest-mistakes-to-avoid","description":null,"seoDescription":"Learn the biggest mistakes to avoid in a system design interview, from unclear requirements to poor trade-off analysis. Includes real-world cases, advanced insights and examples to help you ace your next system design interview.","contentType":2,"generatedOn":"2026-10-14T22:54:06.0065073Z","viewCount":0},{"id":168,"title":"Amazon SDE-2 Interview Experience (3 Years Experience)","url":"amazon-sde-2-interview-experience-3-years-experience","description":null,"seoDescription":" Read a real Amazon SDE-2 interview experience covering the online assessment, coding rounds, object-oriented design, leadership principles and system design.","contentType":5,"generatedOn":"2026-10-14T22:54:06.0070357Z","viewCount":0},{"id":130,"title":"Rippling SDE-2 Interview Experience (4+ Years Experience) | Offer Received | Coding, LLD & System Design","url":"rippling-sde-2-interview-experience-4-years-experience-offer-received-coding-lld-system-design","description":null,"seoDescription":"Detailed Rippling SDE-2 interview experience with complete 5 rounds, coding questions, rules engine design, system design and preparation tips.","contentType":5,"generatedOn":"2026-10-14T22:54:06.0070286Z","viewCount":0},{"id":135,"title":"Spinny SDE-1 Interview Experience (Selected)","url":"spinny-sde-1-interview-experience-selected","description":null,"seoDescription":"Spinny SDE-1 Interview Experience (Selected) | 4 Rounds Breakdown: Coding, LLD, Java, SQL + Real Interview Questions","contentType":5,"generatedOn":"2026-10-14T22:54:06.0070304Z","viewCount":0},{"id":197,"title":"My Adobe SDE Interview Experience (Aug 2026) 5 Rounds, Selected","url":"my-adobe-sde-interview-experience-aug-2026-5-rounds-selected","description":null,"seoDescription":"Real Adobe SDE interview: 5 rounds, 4 DSA problems (Rotate Array, BSTs, Kth Smallest Matrix), code review & behavioral round. Full solutions + tips.","contentType":5,"generatedOn":"2026-10-14T22:54:06.007037Z","viewCount":0}],"latestContents":[{"id":219,"title":"6 Tools That Made My Life Easier as a Software Engineer","url":"6-tools-that-made-my-life-easier-as-a-software-engineer","description":null,"seoDescription":"The 6 developer tools I use daily as a software engineer: Git, VS Code, Docker, Postman, Chrome DevTools, and AI assistants, with real tips, mistakes, and trade","contentType":5,"generatedOn":"2026-10-14T22:54:06.0062035Z","viewCount":0},{"id":218,"title":"When Should a Business Use Multiple AI Agents Instead of One?","url":"when-should-a-business-use-multiple-ai-agents-instead-of-one","description":null,"seoDescription":"Single agent or multi-agent AI? Learn the 4 signals that justify splitting agents by knowledge, permissions, and risk, plus routing and handoff tips.","contentType":5,"generatedOn":"2026-10-14T22:54:06.0062084Z","viewCount":0},{"id":216,"title":"AI in Clinical Trials Market Estimated to Experience a Hike in Growth by 2035","url":"ai-in-clinical-trials-market-estimated-to-experience-a-hike-in-growth-by-2035","description":null,"seoDescription":"The exclusive information about market dynamics serves as a valuable guide to predict economic scenarios and initiatives taken to enhance future growth. Our mar","contentType":5,"generatedOn":"2026-10-14T22:54:06.0062098Z","viewCount":0},{"id":217,"title":"AI in Clinical Trials Market Estimated to Experience a Hike in Growth by 2035","url":"ai-in-clinical-trials-market-estimated-to-experience-a-hike-in-growth-by-2035","description":null,"seoDescription":"The exclusive information about market dynamics serves as a valuable guide to predict economic scenarios and initiatives taken to enhance future growth. Our mar","contentType":5,"generatedOn":"2026-10-14T22:54:06.0062113Z","viewCount":0},{"id":215,"title":"What Happens When an AI Agent Doesn't Know the Answer?","url":"what-happens-when-an-ai-agent-doesnt-know-the-answer","description":null,"seoDescription":"Most AI agents fail quietly. They guess instead of saying \"I don't know.\" Here's how to design better fallback and human-handoff behavior.","contentType":5,"generatedOn":"2026-10-14T22:54:06.0062125Z","viewCount":0},{"id":214,"title":"Greedy Algorithms Explained: How They Work, When They Fail and How to Use Them","url":"greedy-algorithms-explained-how-they-work-when-they-fail-and-how-to-use-them","description":null,"seoDescription":"Learn greedy algorithms step by step with C# code Dijkstra, Huffman coding, knapsack and MSTs plus when greedy fails and how to prove it's correct","contentType":5,"generatedOn":"2026-10-14T22:54:06.006214Z","viewCount":0},{"id":213,"title":"Amazon SDE II Interview Experience (Bangalore, Selected) ~ Aug 2026","url":"amazon-sde-ii-interview-experience-bangalore-selected-aug-2026","description":null,"seoDescription":"Amazon SDE II interview experience from Bangalore covering 4 rounds, DSA, LLD, system design, Leadership Principles, coding questions and selection.","contentType":5,"generatedOn":"2026-10-14T22:54:06.006219Z","viewCount":0},{"id":212,"title":"How to Get 10x Better AI Answers Without Writing Better Prompts : 10 Proven Techniques","url":"how-to-get-10x-better-ai-answers-without-writing-better-prompts-10-proven-techniques","description":null,"seoDescription":"Get better AI answers without complex prompts. Learn 10 practical techniques using context, examples, tools, feedback, and verification.","contentType":5,"generatedOn":"2026-10-14T22:54:06.0062202Z","viewCount":0},{"id":211,"title":"I Interviewed for a Microsoft SDE I Role. Here's Everything That Happened.","url":"i-interviewed-for-a-microsoft-sde-i-role-heres-everything-that-happened","description":null,"seoDescription":"My real Microsoft SDE I interview experience, all 4 rounds, the exact DSA problems with fully tested solutions, the WhatsApp system design round","contentType":5,"generatedOn":"2026-10-14T22:54:06.0062214Z","viewCount":0},{"id":140,"title":"PolicyBazaar Software Development Engineer (SDE) Interview Experience | DSA, Core CS & System Design","url":"policybazaar-software-development-engineer-sde-interview-experience-dsa-core-cs-system-design","description":null,"seoDescription":"Detailed PolicyBazaar SDE interview experience covering 3 rounds: DSA coding, core CS assessment and system design with key learnings and insights.","contentType":5,"generatedOn":"2026-10-14T22:54:06.0062226Z","viewCount":0}],"relatedContents":[{"id":32,"title":"HashSet.CreateSetComparer() in C#","url":"hashsett-createsetcomparer-in-c-sharp","description":null,"seoDescription":"","contentType":5,"generatedOn":"2026-10-14T22:54:06.0115985Z","viewCount":0},{"id":31,"title":"What Happens If You Override Equals() but Not GetHashCode() in C#","url":"what-happens-if-you-override-equals-but-not-gethashcode-in-c-sharp","description":null,"seoDescription":"","contentType":5,"generatedOn":"2026-10-14T22:54:06.0116005Z","viewCount":0},{"id":18,"title":"How to Efficiently Use LINQ Intersect in C# with Large Collections","url":"how-to-efficiently-use-linq-intersect-in-c-sharp-with-large-collections","description":null,"seoDescription":"","contentType":5,"generatedOn":"2026-10-14T22:54:06.0116027Z","viewCount":0},{"id":29,"title":"SortedDictionary in C# – Beginner to Advanced Guide","url":"sorteddictionary-in-c-sharp","description":null,"seoDescription":"Learn how to use SortedDictionary in C# from basics to advanced. Covers syntax, examples, performance and real-world use cases for efficient coding.","contentType":2,"generatedOn":"2026-10-14T22:54:06.0116042Z","viewCount":0},{"id":16,"title":"Collections in C#","url":"collections-in-c-sharp","description":null,"seoDescription":"Explore Collections in c# | c# collections | type of collection in c# | collection classes and operations, LinkedList , stack, queue, dictionary, hashset","contentType":2,"generatedOn":"2026-10-14T22:54:06.0116061Z","viewCount":0},{"id":154,"title":" Static Class vs Singleton in C#","url":"static-class-vs-singleton-in-c-sharp","description":null,"seoDescription":"Static Class vs Singleton in C#: A Complete Deep Dive","contentType":2,"generatedOn":"2026-10-14T22:54:06.0116075Z","viewCount":0},{"id":36,"title":"C# Tutorial","url":"c-sharp-tutorial","description":null,"seoDescription":"c sharp tutorial | c# tutorial | c sharp learning plan","contentType":2,"generatedOn":"2026-10-14T22:54:06.0116087Z","viewCount":0},{"id":39,"title":"Exploring the General Structure of a C# Program","url":"general-structure-of-c-sharp-program","description":null,"seoDescription":"Structure of c# program | c sharp program or code structure ","contentType":2,"generatedOn":"2026-10-14T22:54:06.0116101Z","viewCount":0},{"id":137,"title":"Top C# Properties Interview Questions and Answers","url":"top-c-sharp-properties-interview-questions-and-answers","description":null,"seoDescription":"Top C# Properties Interview Questions and Answers. Prepare for your next tech c# interview with these top c# interview questions and expert answers.","contentType":2,"generatedOn":"2026-10-14T22:54:06.0116116Z","viewCount":0}]}}},"source":{"isMobile":false}}; window.__CLIENT_RENDER__ = false;