diff --git a/benchmark/pom.xml b/benchmark/pom.xml
new file mode 100644
index 0000000..80a6778
--- /dev/null
+++ b/benchmark/pom.xml
@@ -0,0 +1,186 @@
+
+
+ 4.0.0
+
+ flink-connector-gcp-parent
+ com.google.flink.connector.gcp
+ 0.0.0
+
+
+ flink.contector.gcp
+ benchmark
+ 1.0
+ jar
+
+ JMH benchmark sample: Java
+
+
+
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${jmh.version}
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh.version}
+ provided
+
+
+ com.google.flink.connector.gcp
+ flink-examples-gcp
+ 0.0.0
+
+
+ com.google.cloud.flink
+ flink-1.17-connector-bigquery
+
+ 0.1.0-preview
+
+
+
+
+ UTF-8
+
+
+ 1.37
+
+
+ 1.8
+
+
+ benchmarks
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+ ${javac.target}
+ ${javac.target}
+ ${javac.target}
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.1
+
+
+ package
+
+ shade
+
+
+ ${uberjar.name}
+
+
+ org.openjdk.jmh.Main
+
+
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+
+
+
+
+
+ maven-clean-plugin
+ 2.5
+
+
+ maven-deploy-plugin
+ 2.8.1
+
+
+ maven-install-plugin
+ 2.5.1
+
+
+ maven-jar-plugin
+ 2.4
+
+
+ maven-javadoc-plugin
+ 2.9.1
+
+
+ maven-resources-plugin
+ 2.6
+
+
+ maven-site-plugin
+ 3.3
+
+
+ maven-source-plugin
+ 2.2.1
+
+
+ maven-surefire-plugin
+ 2.17
+
+
+
+
+
+
diff --git a/benchmark/src/main/java/flink/contector/gcp/AvroRandomRecordGenerator.java b/benchmark/src/main/java/flink/contector/gcp/AvroRandomRecordGenerator.java
new file mode 100644
index 0000000..9b32180
--- /dev/null
+++ b/benchmark/src/main/java/flink/contector/gcp/AvroRandomRecordGenerator.java
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flink.contector.gcp;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.avro.Schema;
+import org.apache.avro.generic.GenericData;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.RandomUtils;
+
+public class AvroRandomRecordGenerator {
+
+ public static String getRandomString() {
+ return RandomStringUtils.randomAlphabetic(RandomUtils.nextInt(2, 40));
+ }
+
+ public static Integer getRandomInteger() {
+ return RandomUtils.nextInt(0, Integer.MAX_VALUE);
+ }
+
+ public static Long getRandomLong() {
+ return RandomUtils.nextLong(0L, Long.MAX_VALUE);
+ }
+
+ public static Double getRandomDouble() {
+ return RandomUtils.nextDouble(0, Double.MAX_VALUE);
+ }
+
+ public static Float getRandomFloat() {
+ return RandomUtils.nextFloat(0f, Float.MAX_VALUE);
+ }
+
+ public static Boolean getRandomBoolean() {
+ return RandomUtils.nextInt(0, 10) % 2 == 0 ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public static ByteBuffer getRandomBytes() {
+ return ByteBuffer.wrap(RandomUtils.nextBytes(RandomUtils.nextInt(1, 25)));
+ }
+
+ /**
+ * Generates Generic Record with random values to given avro Schema.
+ *
+ * @param schema Avro Schema
+ * @return
+ */
+ public static GenericData.Record generateRandomRecordData(Schema schema) {
+ if (!Schema.Type.RECORD.equals(schema.getType())) {
+ throw new IllegalArgumentException("input schema must be a record schema");
+ }
+
+ final GenericData.Record record = new GenericData.Record(schema);
+
+ for (Schema.Field field : schema.getFields()) {
+ switch (field.schema().getType()) {
+ case BOOLEAN:
+ record.put(field.pos(), getRandomBoolean());
+ break;
+ case INT:
+ record.put(field.pos(), getRandomInteger());
+ break;
+ case LONG:
+ record.put(field.pos(), getRandomLong());
+ break;
+ case DOUBLE:
+ record.put(field.pos(), getRandomDouble());
+ break;
+ case FLOAT:
+ record.put(field.pos(), getRandomFloat());
+ break;
+ case BYTES:
+ record.put(field.pos(), getRandomBytes());
+ break;
+ case STRING:
+ record.put(field.pos(), getRandomString());
+ break;
+ case RECORD:
+ record.put(field.pos(), generateRandomRecordData(field.schema()));
+ break;
+ case ENUM:
+ record.put(field.pos(), generateRandomEnumSymbol(field.schema()));
+ break;
+ case FIXED:
+ record.put(field.pos(), generateRandomFixed(field.schema()));
+ break;
+ case UNION:
+ record.put(field.pos(), generateRandomUnion(field.schema()));
+ break;
+ case ARRAY:
+ record.put(field.pos(), generateRandomArray(field.schema()));
+ break;
+ case MAP:
+ record.put(field.pos(), generateRandomMap(field.schema()));
+ break;
+ default:
+ throw new IllegalArgumentException("Not Support type " + schema.getValueType().getType());
+ }
+ }
+
+ return record;
+ }
+
+ /**
+ * Generates Enum Field with random values to given avro Schema.
+ *
+ * @param schema Avro Schema
+ * @return
+ */
+ public static GenericData.EnumSymbol generateRandomEnumSymbol(Schema schema) {
+ if (!Schema.Type.ENUM.equals(schema.getType())) {
+ throw new IllegalArgumentException("input schema must be an enum schema");
+ }
+
+ return new GenericData.EnumSymbol(schema,
+ schema.getEnumSymbols().get(RandomUtils.nextInt(0, schema.getEnumSymbols().size())));
+ }
+
+ /**
+ * Generates Fixed Field with random values to given avro Schema.
+ *
+ * @param schema Avro Schema
+ * @return
+ */
+ public static GenericData.Fixed generateRandomFixed(Schema schema) {
+ if (!Schema.Type.FIXED.equals(schema.getType())) {
+ throw new IllegalArgumentException("input schema must be an fixed schema");
+ }
+
+ return new GenericData.Fixed(schema,
+ RandomUtils.nextBytes(schema.getFixedSize()));
+ }
+
+ /**
+ * Generates Union Field with random values to given avro Schema.
+ *
+ * @param schema Avro Schema
+ * @return
+ */
+ public static Object generateRandomUnion(Schema schema) {
+ if (!Schema.Type.UNION.equals(schema.getType())) {
+ throw new IllegalArgumentException("input schema must be an union schema");
+ }
+ Object unionData = null;
+ switch (schema.getTypes().get(1).getType()) {
+ case BOOLEAN:
+ unionData = getRandomBoolean();
+ break;
+ case INT:
+ unionData = getRandomInteger();
+ break;
+ case LONG:
+ unionData = getRandomLong();
+ break;
+ case DOUBLE:
+ unionData = getRandomDouble();
+ break;
+ case FLOAT:
+ unionData = getRandomFloat();
+ break;
+ case BYTES:
+ unionData = getRandomBytes();
+ break;
+ case STRING:
+ unionData = getRandomString();
+ break;
+ case RECORD:
+ unionData = generateRandomRecordData(schema.getTypes().get(1));
+ break;
+ case ENUM:
+ unionData = generateRandomEnumSymbol(schema.getTypes().get(1));
+ break;
+ case FIXED:
+ unionData = generateRandomFixed(schema.getTypes().get(1));
+ break;
+ case UNION:
+ unionData = generateRandomUnion(schema.getTypes().get(1));
+ break;
+ default:
+ unionData = null;
+ }
+
+ return unionData;
+ }
+
+ /**
+ * Generates Array Field with random values to given avro Schema.
+ *
+ * @param schema Avro Schema
+ * @return
+ */
+ public static GenericData.Array> generateRandomArray(Schema schema) {
+ if (!Schema.Type.ARRAY.equals(schema.getType())) {
+ throw new IllegalArgumentException("input schema must be an array schema");
+ }
+
+ int elements = RandomUtils.nextInt(1, 11);
+ GenericData.Array