Subpartitioning is a core Decaton concept that enables concurrent processing within a single partition by using a fixed count of queues, each with an associated processing thread. This improves throughput but can lead to idle CPUs if the workload is I/O intensive and the thread count is fixed.
Decaton provides two runtime options to manage this:
THREAD_POOL (Default): Processes one partition using a fixed number of platform (OS) threads. The number of threads is determined by the decaton.partition.concurrency configuration.VIRTUAL_THREAD: Processes each unique record key on a different Java Virtual Thread. This is highly efficient for I/O-intensive workloads as it avoids the overhead of OS threads. Requires JDK 21 or higher. When using this mode, the decaton.partition.concurrency setting is ignored.
Warning for VIRTUAL_THREAD users: Avoid using the synchronized primitive in your code (or libraries used within DecatonProcessor#process()). Using synchronized can cause "pinning" of the virtual thread, which prevents the scheduler from unmounting it and can negate the performance benefits of virtual threads.
// Concept: Subpartition Runtime selection
// THREAD_POOL: Uses fixed platform threads (controlled by decaton.partition.concurrency)
// VIRTUAL_THREAD: Uses one virtual thread per record key (Requires JDK 21+)