# 11. Production checklist [← Previous](10-scaling-sensitivity-to-data-size.md) | [README](../README.md) Everything below is a consequence of an earlier chapter, not a new claim — this is the condensed version to check a real job against. - **Confirm your `Partitioner` actually reads `gridSize` before sizing anything by it.** `MultiResourcePartitioner` does not ([chapter 3](03-what-gridsize-actually-controls.md)). The number of partitions that run is whatever your partitioner's `partition()` map returns, full stop — check that, not the `gridSize` property, when something needs exactly N partitions. - **Size the thread pool to at least gridSize, with a queue, not a bare `AbortPolicy` at zero capacity.** An undersized pool with `AbortPolicy` does not fail loudly — it leaves rejected partitions' `StepExecution`s parked at `STARTING` forever and makes every future restart throw `JobExecutionAlreadyRunningException` ([chapter 7](07-the-rejectedexecutionexception.md), [chapter 9](09-jobexecutionalreadyrunning-and-recover.md)). If you must use `AbortPolicy` for fail-fast behavior, have an operational runbook that calls `JobOperator#recover` before anyone tries to restart. - **Benchmark gridSize against your actual data volume, not just your core count.** More partitions than cores got *worse*, not flat, at both scales this module measured; at the smaller of the two, over-partitioning lost to not partitioning at all ([chapter 10](10-scaling-sensitivity-to-data-size.md)). A gridSize tuned for a large nightly batch is not automatically safe for a smaller one. - **Check what your worker steps write to.** A single-writer embedded database (this module's H2 file) caps the speedup partitioning can deliver regardless of thread count or core count ([chapter 6](06-why-cpu-bound-not-io-bound.md), [chapter 10](10-scaling-sensitivity-to-data-size.md)). A database built for concurrent writers changes this ceiling; measure again against the real target rather than assuming. - **Make the writer idempotent if partitions can retry.** `MERGE ... KEY(order_id)` here, not `INSERT` ([chapter 4](04-the-writer-and-the-beanmapped-trap.md)) — a partition that fails after partially writing and then restarts writes some rows twice on a plain `INSERT`. - **Delete the diagnostic endpoint** ([chapter 5](05-the-diagnostic-endpoint.md)) or put it behind real authentication before this leaves a sandbox. - **Don't reach for `BeanPropertySqlParameterSource`/`beanMapped()` with Java records** without checking it actually populated your columns ([chapter 4](04-the-writer-and-the-beanmapped-trap.md)) — it fails by silently writing `NULL`, not by throwing. - **If migrating a 5.x partitioned job to 6.0**, budget time for the `org.springframework.batch.item.*` → `org.springframework.batch.infrastructure.item.*` import rewrite across every reader, writer, and `ExecutionContext` reference before anything else compiles ([`docs/output/03-package-repackaging-javap.txt`](output/03-package-repackaging-javap.txt)), and rename any `@Bean` methods that were only distinguished by `@Profile` ([`docs/output/04-enforceuniquemethods-error.txt`](output/04-enforceuniquemethods-error.txt)). [← Previous](10-scaling-sensitivity-to-data-size.md) | [README](../README.md)