Serialization Optimizations in Java applications

Table of Contents

Serialization Optimizations

The Surprising CPU Saver.

Profiling showed that 15% of CPU time was spent in Jackson serialization. Switch to a more efficient configuration.

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();

        // Use afterburner module for faster serialization
        mapper.registerModule(new AfterburnerModule());

        // Only include non-null values
        mapper.setSerializationInclusion(Include.NON_NULL);

        // Disable features we don't need
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        return mapper;
    }
}

For our most performance-critical endpoints, I replaced Jackson with Protocol Buffers:

syntax = "proto3";
package com.example.proto;

message ProductResponse {
  int64 id = 1;
  string name = 2;
  string description = 3;
  double price = 4;
  int32 inventory = 5;
}
@RestController
@RequestMapping("/api/products")
public class ProductController {
    // Jackson-based endpoint
    @GetMapping("/{id}")
    public Mono<ResponseEntity<Product>> getProduct(@PathVariable Long id) {
        // Original implementation
    }

    // Protocol buffer endpoint for high-performance needs
    @GetMapping("/{id}/proto")
    public Mono<ResponseEntity<byte[]>> getProductProto(@PathVariable Long id) {
        return service.getProductById(id)
            .map(product -> ProductResponse.newBuilder()
                .setId(product.getId())
                .setName(product.getName())
                .setDescription(product.getDescription())
                .setPrice(product.getPrice())
                .setInventory(product.getInventory())
                .build().toByteArray())
            .map(bytes -> ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(bytes));
    }
}

This change reduced serialization CPU usage by 80% and decreased response sizes by 30%