A lightweight Java 21 library for micro-batching requests to any backend. Built with virtual threads, smart batching, and comprehensive Micrometer metrics. Released under Apache License 2.0.
Backend backend = batch -> {
// Your backend logic
return new BatchResult<>(
successes, failures
);
};
BatcherConfig config = BatcherConfig
.builder()
.batchSize(10)
.lingerTime(Duration.ofMillis(100))
.build();
try (MicroBatcher batcher =
new MicroBatcher<>(backend, config)) {
CompletableFuture>
future = batcher.submit("data");
}
Everything you need for efficient micro-batching
Leverage Java 21's Project Loom for high concurrency. Backend code can be blocking - virtual threads make it efficient.
Triggers on batch size OR linger time (whichever comes first). Ensures optimal throughput and low latency.
Optional atomic commit mode where entire batch fails if any request fails. Perfect for transactional operations.
Works with any backend via the simple Backend<T> interface. HTTP, database, queues - anything.
Micrometer metrics for queue depth, success/failure rates, latencies. Ready for Prometheus, Grafana, and more.
Intelligent replay of successful items when batches contain mixed results. Backend-driven or config-based decisions.
See how easy it is to get started
import com.vajrapulse.vortex.*;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
// 1. Create a backend implementation
Backend backend = batch -> {
List> successes = new ArrayList<>();
List> failures = new ArrayList<>();
for (String item : batch) {
// Process item (e.g., HTTP call, database query)
successes.add(new SuccessEvent<>(item));
}
return new BatchResult<>(successes, failures);
};
// 2. Configure the batcher
BatcherConfig config = BatcherConfig.builder()
.batchSize(10) // Batch size trigger
.lingerTime(Duration.ofMillis(100)) // Time-based trigger
.atomicCommit(false) // Optional: all-or-nothing
.maxConcurrency(10) // Max concurrent batches
.build();
// 3. Create and use the batcher
try (MicroBatcher batcher = new MicroBatcher<>(backend, config)) {
CompletableFuture> future = batcher.submit("request-data");
BatchResult result = future.get();
// Handle result...
}
// Enable atomic commits - entire batch fails if any item fails
BatcherConfig config = BatcherConfig.builder()
.batchSize(10)
.lingerTime(Duration.ofMillis(100))
.atomicCommit(true) // All-or-nothing
.build();
try (MicroBatcher batcher = new MicroBatcher<>(backend, config)) {
// If any item in the batch fails, all items receive failure
CompletableFuture> future = batcher.submit("data");
BatchResult result = future.get();
if (result.hasFailures()) {
// All items in this batch failed
}
}
// Backend that decides when to replay
Backend backend = new Backend() {
@Override
public BatchResult dispatch(List batch) throws Exception {
// Your dispatch logic
return new BatchResult<>(successes, failures);
}
@Override
public boolean shouldReplaySuccesses(BatchResult result) {
// Replay when there are both successes and failures
return !result.getFailures().isEmpty()
&& !result.getSuccesses().isEmpty();
}
};
// Or use config-based replay
BatcherConfig config = BatcherConfig.builder()
.batchSize(10)
.autoReplaySuccesses(true) // Global replay policy
.build();
try (MicroBatcher batcher = new MicroBatcher<>(backend, config)) {
// Access Micrometer registry
MeterRegistry registry = batcher.getMeterRegistry();
// Metrics are automatically exposed:
// - vortex.requests.submitted
// - vortex.batches.dispatched
// - vortex.requests.succeeded
// - vortex.requests.failed
// - vortex.queue.depth (gauge)
// - vortex.batch.dispatch.latency
// - vortex.request.wait.latency
// Export to Prometheus, Grafana, etc.
// registry.getMeters().forEach(...);
}
Add Vortex to your project in minutes
dependencies {
implementation("com.vajrapulse:vortex:0.0.1")
}
dependencies {
implementation 'com.vajrapulse:vortex:0.0.1'
}
<dependency>
<groupId>com.vajrapulse</groupId>
<artifactId>vortex</artifactId>
<version>0.0.1</version>
</dependency>
Built for the modern Java ecosystem
Write synchronous, blocking code. Virtual threads handle the efficiency. No need to manage CompletableFuture in your backend.
Clients get async results via CompletableFuture. Compose, chain, and handle results asynchronously.
Comprehensive test coverage, Micrometer integration, and battle-tested patterns. Ready for production workloads.
Minimal dependencies. Clean, simple API. Easy to understand and integrate into any project.
Vortex is completely open source and free to use. Released under the Apache License 2.0, you can use it in commercial and personal projects without restrictions.
Permissive open source license that allows you to:
Vortex is built by the community, for the community. Contributions are welcome!