Backend Development 8 min read

Why Creating a New ObjectMapper Slows Your SpringBoot App – Up to 300× Faster with a Singleton

This article benchmarks the cost of instantiating a new ObjectMapper for each JSON conversion in a SpringBoot project, demonstrates a singleton implementation that boosts read performance by 18× and write performance by up to 300×, and shows how to add custom serializers without sacrificing speed.

macrozheng
macrozheng
macrozheng
Why Creating a New ObjectMapper Slows Your SpringBoot App – Up to 300× Faster with a Singleton

In a SpringBoot project, converting between objects and JSON strings often involves creating a new

ObjectMapper

instance for each operation, which looks harmless but can severely degrade performance.

<code>public UserEntity string2Obj(String json) throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    return objectMapper.readValue(json, UserEntity.class);
}

public String obj2String(UserEntity userEntity) throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    return objectMapper.writeValueAsString(userEntity);
}
</code>

Although functional, this pattern is considered a performance anti‑pattern by developers focused on efficiency.

A benchmark is a scientific method for measuring performance; JMH is a tool for building, running, and analyzing nanosecond‑level benchmarks for Java and JVM languages.
<code>@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 3, time = 1)
public class JsonJMHTest {
    String json = "{\"id\":122345667,\"email\":\"[email protected]\",\"price\":12.25}";
    UserEntity userEntity = new UserEntity(13345L, "[email protected]", BigDecimal.valueOf(12.25));

    @Benchmark
    public UserEntity objectMapper2ObjTest() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(json, UserEntity.class);
    }

    @Benchmark
    public String objectMapper2StringTest() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.writeValueAsString(userEntity);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JsonJMHTest.class.getSimpleName())
                .build();
        new Runner(opt).run();
    }
}
</code>

Test environment:

<code># JMH version: 1.36
# VM version: JDK 17.0.3, OpenJDK 64‑Bit Server VM, 17.0.3+7‑LTS
# Mac AppleM1/16GB
</code>

Results show that creating a new

ObjectMapper

yields about 230 000 reads per second and only 27 000 writes per second.

To improve performance, a singleton pattern is introduced.

<code>@Getter
public enum ObjectMapperInstance {
    INSTANCE;
    private final ObjectMapper objectMapper = new ObjectMapper();
}
</code>
<code>@Benchmark
public UserEntity singleten2ObjTest() throws JsonProcessingException {
    ObjectMapper objectMapper = ObjectMapperInstance.INSTANCE.getObjectMapper();
    return objectMapper.readValue(json, UserEntity.class);
}

@Benchmark
public String singleten2StringTest() throws JsonProcessingException {
    ObjectMapper objectMapper = ObjectMapperInstance.INSTANCE.getObjectMapper();
    return objectMapper.writeValueAsString(userEntity);
}
</code>

Benchmarking the singleton version shows roughly 4.2 million reads per second (18× faster) and 8.3 million writes per second (about 300× faster).

Further, custom serialization can be added to the singleton to handle

Long

and

BigDecimal

as strings, preventing precision loss on the front end.

<code>@Getter
public enum ObjectMapperInstance {
    INSTANCE;
    private final ObjectMapper objectMapper;
    ObjectMapperInstance() {
        objectMapper = new ObjectMapper();
        initialize();
    }
    private void initialize() {
        CustomJsonModule customJsonModule = new CustomJsonModule();
        objectMapper.registerModule(customJsonModule);
    }
}
</code>

A subsequent JMH test indicates that registering custom converters adds a modest overhead, which is negligible for most business scenarios.

Conclusion: Using a singleton

ObjectMapper

in SpringBoot dramatically improves JSON conversion performance—up to 18× faster for deserialization and up to 300× faster for serialization—while still allowing custom configuration when needed.

JavaPerformanceSpringBootsingletonJMHObjectMapper
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.