Documentation Index
Fetch the complete documentation index at: https://mintlify.com/gatling/gatling.io-doc/llms.txt
Use this file to discover all available pages before exploring further.
Apache Kafka is built for high-throughput, fault-tolerant message streaming — which means it needs to be load tested in a way that reflects the actual volume and variety of messages your producers will send in production. Gatling supports Kafka load testing through a community plugin that integrates the standard Kafka producer client into Gatling’s virtual-user engine, allowing you to send messages with custom keys, values, headers, and serialization formats while Gatling’s reporting tracks throughput and error rates across every run.
Prerequisites
- Gatling version 3.13.x
- Java 17
- Maven or Gradle
- A Kafka broker (running locally or in your test environment)
- A Gatling Enterprise Edition trial account (for distributed testing and advanced reporting)
Add the Kafka Plugin Dependency
The Kafka plugin for Gatling is published by the org.galaxio group. You also need the Confluent Maven repository because some serializers depend on it.
Add the Confluent repository to your pom.xml:<repositories>
<repository>
<id>confluent</id>
<url>https://packages.confluent.io/maven/</url>
</repository>
</repositories>
Add the Kafka plugin dependency:<dependency>
<groupId>org.galaxio</groupId>
<artifactId>gatling-kafka-plugin_2.13</artifactId>
<version>1.0.0-RC1</version>
<scope>test</scope>
</dependency>
Add the Confluent repository to build.gradle:repositories {
mavenCentral()
maven {
url "https://packages.confluent.io/maven/"
}
}
Add the dependency:dependencies {
gatling "org.galaxio:gatling-kafka-plugin_2.13:1.0.0-RC1"
}
Add the Import Statements
import org.galaxio.gatling.kafka.javaapi.protocol.*;
import org.apache.kafka.clients.producer.ProducerConfig;
import static io.gatling.javaapi.core.CoreDsl.*;
import static org.galaxio.gatling.kafka.javaapi.KafkaDsl.*;
Define the cluster connection, topic, and producer settings:
private final KafkaProtocolBuilder kafkaProtocol = kafka()
.topic("test")
.properties(
Map.of(
ProducerConfig.ACKS_CONFIG, "1",
ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092",
ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
"org.apache.kafka.common.serialization.StringSerializer",
ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
"org.apache.kafka.common.serialization.StringSerializer"
)
);
SASL Authentication
If your Kafka cluster requires SASL, use environment variables to keep credentials out of source code:
public static final String IP_SERVER = System.getProperty("IP_SERVER", "");
public static final String URL_REGISTRY= System.getProperty("URL_REGISTRY","");
public static final String USER_AUTH = System.getProperty("USER_AUTH", "");
private final KafkaProtocolBuilder kafkaProtocol = kafka()
.topic("test")
.properties(
Map.of(
ProducerConfig.ACKS_CONFIG, "1",
ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, IP_SERVER,
ProducerConfig.MAX_REQUEST_SIZE_CONFIG, "2097152",
"security.protocol", "SASL_SSL",
"sasl.mechanism", "PLAIN",
"client.dns.lookup", "use_all_dns_ips",
"sasl.jaas.config",
"org.apache.kafka.common.security.plain.PlainLoginModule " +
"required username=\"$USERNAME_BROKER\" password=\"$PASSWORD_BROKER\";",
"schema.registry.url", URL_REGISTRY,
"basic.auth.credentials.source", "USER_INFO",
"basic.auth.user.info", USER_AUTH
)
);
Write the Scenario
Send a message with a custom header to the configured topic:
private final Headers headers = new RecordHeaders(
new Header[]{ new RecordHeader("test-header", "value".getBytes()) }
);
private final ScenarioBuilder kafkaProducer = scenario("Kafka Producer")
.exec(kafka("Simple Message")
.send("key", "value", headers)
);
Kafka operates asynchronously — messages are sent and received independently. The plugin also supports request-reply patterns (send a message and wait for a correlated response on a reply topic) for verifying end-to-end delivery.
Define the Injection Profile
Choose an injection profile that matches your testing objective. For a Kafka cluster that is not yet in production, a capacity test that increments users per second across multiple levels is a good starting point:
{
setUp(
kafkaProducer.injectOpen(
incrementUsersPerSec(1000)
.times(4)
.eachLevelLasting(60)
.separatedByRampsLasting(10)
.startingFrom(100.0)
)
).protocols(kafkaProtocol);
}
This profile starts at 100 virtual users per second and increases by 1,000 every 60 seconds (with 10-second ramps between levels), reaching 4,100 users per second at the top.
Complete Simulation Example
package kafka;
import io.gatling.javaapi.core.*;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.header.*;
import org.apache.kafka.common.header.internals.*;
import org.galaxio.gatling.kafka.javaapi.protocol.*;
import java.util.Map;
import static io.gatling.javaapi.core.CoreDsl.*;
import static org.galaxio.gatling.kafka.javaapi.KafkaDsl.*;
public class KafkaSimulation extends Simulation {
private final KafkaProtocolBuilder kafkaProtocol = kafka()
.topic("test")
.properties(Map.of(
ProducerConfig.ACKS_CONFIG, "1",
ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092",
ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
"org.apache.kafka.common.serialization.StringSerializer",
ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
"org.apache.kafka.common.serialization.StringSerializer"
));
private final Headers headers = new RecordHeaders(
new Header[]{ new RecordHeader("test-header", "value".getBytes()) }
);
private final ScenarioBuilder kafkaProducer = scenario("Kafka Producer")
.exec(kafka("Simple Message").send("key", "value", headers));
{
setUp(
kafkaProducer.injectOpen(
incrementUsersPerSec(1000)
.times(4).eachLevelLasting(60)
.separatedByRampsLasting(10)
.startingFrom(100.0)
)
).protocols(kafkaProtocol);
}
}
Running a Local Kafka Cluster with Docker
If you don’t have a Kafka broker available, spin one up with Docker Compose:
# docker-compose.yml
version: "3"
services:
kafka:
container_name: kafka
image: "bitnami/kafka:latest"
ports:
- 9092:9092
environment:
- KAFKA_ENABLE_KRAFT=yes
- KAFKA_CFG_NODE_ID=1
- KAFKA_CFG_PROCESS_ROLES=broker,controller
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092
- KAFKA_BROKER_ID=1
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@127.0.0.1:9093
- ALLOW_PLAINTEXT_LISTENER=yes
# Start the broker
docker compose up -d
# Create a test topic
docker exec -it kafka /opt/bitnami/kafka/bin/kafka-topics.sh \
--create --bootstrap-server localhost:9092 \
--replication-factor 1 --partitions 1 --topic test
# Tail incoming messages
docker exec -it kafka /opt/bitnami/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server localhost:9092 --from-beginning --topic test
Running on Gatling Enterprise Edition
For high-throughput distributed Kafka load tests, use Gatling Enterprise Edition to inject load from multiple regions simultaneously.
If your Kafka broker is not accessible from the public internet, use Private Locations to deploy load generators inside your private network. If the broker is public but firewall-protected, use Dedicated IP Addresses to whitelist Gatling’s load generator IPs.