diff --git a/vertx-pg-client/pom.xml b/vertx-pg-client/pom.xml
index ea6762122..c38e2d940 100644
--- a/vertx-pg-client/pom.xml
+++ b/vertx-pg-client/pom.xml
@@ -201,4 +201,44 @@
+
+
+ benchmarks
+
+
+
+ maven-assembly-plugin
+
+
+ assemble-benchmarks
+ package
+
+ single
+
+
+
+
+ org.openjdk.jmh.Main
+
+
+
+ src/test/assembly/benchmarks.xml
+
+
+
+
+
+
+
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh.version}
+ test
+
+
+
+
+
diff --git a/vertx-pg-client/src/test/assembly/benchmarks.xml b/vertx-pg-client/src/test/assembly/benchmarks.xml
new file mode 100644
index 000000000..f647e6539
--- /dev/null
+++ b/vertx-pg-client/src/test/assembly/benchmarks.xml
@@ -0,0 +1,33 @@
+
+
+
+ benchmarks
+
+ jar
+
+ false
+
+
+ ${project.build.testOutputDirectory}
+ /
+
+
+
+
+ /
+ true
+ test
+
+
+
diff --git a/vertx-pg-client/src/test/java/io/vertx/pgclient/benchmarks/IntervalBenchmarks.java b/vertx-pg-client/src/test/java/io/vertx/pgclient/benchmarks/IntervalBenchmarks.java
new file mode 100644
index 000000000..55918ae0c
--- /dev/null
+++ b/vertx-pg-client/src/test/java/io/vertx/pgclient/benchmarks/IntervalBenchmarks.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011-2024 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+
+package io.vertx.pgclient.benchmarks;
+
+import io.vertx.pgclient.data.Interval;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.io.IOException;
+import java.time.Duration;
+import java.time.Period;
+import java.util.concurrent.TimeUnit;
+
+import static java.time.temporal.ChronoUnit.MICROS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+@Threads(1)
+@State(Scope.Thread)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Warmup(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 10, time = 2, timeUnit = TimeUnit.SECONDS)
+@Fork(value = 3, jvmArgs = {"-Xms8g", "-Xmx8g", "-Xmn7g"})
+public class IntervalBenchmarks {
+
+ private Interval interval;
+
+ @Setup
+ public void setup() throws IOException, InterruptedException {
+ interval = new Interval(-2, 3, 15, -13, 2, -57, -426994);
+ }
+
+ @Benchmark
+ public void encodeWithDurationAndPeriod(Blackhole blackhole) {
+ Duration duration = Duration
+ .ofHours(interval.getHours())
+ .plusMinutes(interval.getMinutes())
+ .plusSeconds(interval.getSeconds())
+ .plus(interval.getMicroseconds(), MICROS);
+ // days won't be changed
+ Period monthYear = Period.of(interval.getYears(), interval.getMonths(), interval.getDays()).normalized();
+
+ blackhole.consume(NANOSECONDS.toMicros(duration.toNanos()));
+ blackhole.consume(monthYear.getDays());
+ blackhole.consume((int) monthYear.toTotalMonths());
+ }
+
+ @Benchmark
+ public void encodeWithParts(Blackhole blackhole) {
+ // We decompose the interval in 3 parts: months, seconds and micros
+ int monthsPart = Math.addExact(Math.multiplyExact(interval.getYears(), 12), interval.getMonths());
+ // A long is big enough to store the maximum/minimum value of the seconds part
+ long secondsPart = interval.getDays() * 24 * 3600L
+ + interval.getHours() * 3600L
+ + interval.getMinutes() * 60L
+ + interval.getSeconds()
+ + interval.getMicroseconds() / 1000000;
+ int microsPart = interval.getMicroseconds() % 1000000;
+
+ // The actual number of months is the sum of the months part and the number of months present in the seconds part
+ int months = Math.addExact(monthsPart, Math.toIntExact(secondsPart / 2592000));
+ // The actual number of days is computed from the remainder of the previous division
+ // It's necessarily smaller than or equal to 29
+ int days = (int) secondsPart % 2592000 / 86400;
+ // The actual number of micros is the sum of the micros part and the remainder of previous divisions
+ // The remainder of previous divisions is necessarily smaller than or equal to a day less a second
+ // The microseconds part is smaller than a second
+ // Therefore, their sum is necessarily smaller than a day
+ long micros = microsPart + secondsPart % 2592000 % 86400 * 1000000;
+
+ blackhole.consume(micros);
+ blackhole.consume(days);
+ blackhole.consume(months);
+ }
+}