Scalable spring batch job on kubernetes
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Spring Batch can scale on Kubernetes, but only if you align the batch model with Kubernetes job semantics. The common mistake is to deploy a batch application like a long-running web service and then call extra replicas "scaling." Real scalability comes from partitioning work and coordinating it through a shared job repository.
Use a Kubernetes Job, Not a Deployment
Batch workloads are finite by nature:
- start
- process data
- finish
That maps naturally to a Kubernetes Job, not a Deployment.
Minimal example:
Using a Deployment for one-off batch work usually creates awkward behavior around retries, completion, and replica management. A Job gives Kubernetes the correct lifecycle model from the beginning.
The Job Repository Must Be Shared
Spring Batch tracks execution state, step progress, failures, and restart metadata through its job repository. If you want multiple Pods or workers to cooperate, they need a shared durable repository, typically backed by an external database.
Without that, scaling is unreliable because each container loses sight of what the others already did.
So the architecture usually includes:
- containerized Spring Batch app
- shared job repository database
- Kubernetes Job or CronJob launcher
- partitioning or remote chunking strategy
That repository is part of correctness, not just observability.
Horizontal Scaling Requires Work Partitioning
Running four identical Pods against the same batch step does not magically parallelize Spring Batch safely. You need a deliberate split of work:
- partitioned steps
- remote chunking
- or separate job parameters that assign non-overlapping data slices
A partitioned step in Spring Batch might look like this:
The important idea is that each worker receives a defined slice of the total workload. Without that, extra Pods only create duplicate processing or lock contention.
Kubernetes Adds Elastic Compute, Not Batch Semantics
Kubernetes is excellent at:
- launching workers
- isolating resources
- retrying failed Pods
- scaling compute pools
Spring Batch is excellent at:
- step control
- restartability
- chunk processing
- execution state
Treat them as complementary. Kubernetes should not replace the job repository, and Spring Batch should not pretend to be an orchestrator by itself.
Think About Restartability and Idempotency
A scalable batch system must assume retries happen:
- Pods can be evicted
- nodes can fail
- jobs can be re-run
That means workers should be restartable and, where possible, idempotent. If a Pod dies halfway through a partition, the system should be able to retry that slice without corrupting the data or duplicating irreversible side effects.
This is where many "scaled" batch systems fail. They increase throughput but lose operational safety.
Tune at the Step Level, Not Just the Pod Count
Performance depends on more than replica count. Spring Batch throughput still depends on:
- chunk size
- reader and writer efficiency
- transaction boundaries
- partition size
- database throughput
- memory per worker
A sensible tuning process is:
- make one worker correct
- measure bottlenecks
- add partitioning
- increase worker count gradually
Blindly scaling Pods before step design is stable usually just multiplies database or I/O contention.
CronJobs for Scheduled Batch Runs
If the batch run is periodic, wrap the same container in a Kubernetes CronJob:
This gives you Kubernetes-native scheduling while still keeping Spring Batch responsible for execution semantics inside the container.
Observability Matters Once You Scale
After the workload spans multiple Pods, you need visibility into:
- job and step duration
- partition success and retry counts
- Pod failures
- queue or backlog size
- database pressure from the job repository
Without these signals, a "scalable" design can degrade quietly and be harder to operate than a single-node job.
Common Pitfalls
- Deploying Spring Batch as a
Deploymentand treating replica count as true batch scaling. - Running multiple Pods without partitioning or another clear split of work.
- Forgetting that all workers need a shared durable job repository.
- Increasing Pod count before understanding database and I/O bottlenecks.
- Ignoring restart and idempotency requirements while focusing only on throughput.
Summary
- Scalable Spring Batch on Kubernetes starts with the right primitive:
JoborCronJob, notDeployment. - Real horizontal scale requires partitioning, remote chunking, or another deliberate work-splitting strategy.
- A shared job repository is essential for correctness and restartability.
- Kubernetes provides elastic execution, while Spring Batch provides batch semantics.
- Throughput only matters if the system stays restartable, observable, and partition-safe.
Related reading
- Scale down Kubernetes Pods
- Scheduler is not scheduling Pod for DaemonSet in Master node
- script backup namespace,deployment etc.. from kubernetes
- Script to continuously follow kubectl get pods
- seccompunconfined for a container in a kubernetes pod? Or changing default in docker 1.10?
- See full command of running/stopped container in Docker
- Scaling services in Distributed system SOA
- Scaling TerminusDB to multiple servers

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.