Spring Batch Metadata Tables Diagram
Spring Batch persists every job run in six metadata tables. BATCH_JOB_INSTANCE is the top of the hierarchy - one row per logical job identified by name plus key. Each run adds a BATCH_JOB_EXECUTION row with status, exit code, and timestamps; parameters land in BATCH_JOB_EXECUTION_PARAMS; each step adds a BATCH_STEP_EXECUTION row with read/write/skip counters; and restart state is serialized into the two _CONTEXT tables. The design detail that surprises people: the _ID primary keys are not database-generated - they come from separate sequences, because the key must be set on the Java object right after insert.
Last updated: 2026-09-27
Source: Official schema-postgresql.sql (spring-projects/spring-batch) · License: Apache-2.0
Tables in the Spring Batch schema
| Column | Type | Nullable | Key |
|---|---|---|---|
| BATCH_JOB_INSTANCE | |||
| JOB_INSTANCE_ID | BIGINT | No | PK |
| VERSION | BIGINT | Yes | - |
| JOB_NAME | VARCHAR(100) | No | - |
| JOB_KEY | VARCHAR(32) | No | - |
| BATCH_JOB_EXECUTION | |||
| JOB_EXECUTION_ID | BIGINT | No | PK |
| VERSION | BIGINT | Yes | - |
| JOB_INSTANCE_ID | BIGINT | No | - |
| CREATE_TIME | TIMESTAMP | No | - |
| START_TIME | TIMESTAMP | Yes | - |
| END_TIME | TIMESTAMP | Yes | - |
| STATUS | VARCHAR(10) | Yes | - |
| EXIT_CODE | VARCHAR(2500) | Yes | - |
| EXIT_MESSAGE | VARCHAR(2500) | Yes | - |
| LAST_UPDATED | TIMESTAMP | Yes | - |
| BATCH_JOB_EXECUTION_PARAMS | |||
| JOB_EXECUTION_ID | BIGINT | No | - |
| PARAMETER_NAME | VARCHAR(100) | No | - |
| PARAMETER_TYPE | VARCHAR(100) | No | - |
| PARAMETER_VALUE | VARCHAR(2500) | Yes | - |
| IDENTIFYING | CHAR(1) | No | - |
| BATCH_STEP_EXECUTION | |||
| STEP_EXECUTION_ID | BIGINT | No | PK |
| VERSION | BIGINT | No | - |
| STEP_NAME | VARCHAR(100) | No | - |
| JOB_EXECUTION_ID | BIGINT | No | - |
| CREATE_TIME | TIMESTAMP | No | - |
| START_TIME | TIMESTAMP | Yes | - |
| END_TIME | TIMESTAMP | Yes | - |
| STATUS | VARCHAR(10) | Yes | - |
| COMMIT_COUNT | BIGINT | Yes | - |
| READ_COUNT | BIGINT | Yes | - |
| FILTER_COUNT | BIGINT | Yes | - |
| WRITE_COUNT | BIGINT | Yes | - |
| READ_SKIP_COUNT | BIGINT | Yes | - |
| WRITE_SKIP_COUNT | BIGINT | Yes | - |
| PROCESS_SKIP_COUNT | BIGINT | Yes | - |
| ROLLBACK_COUNT | BIGINT | Yes | - |
| EXIT_CODE | VARCHAR(2500) | Yes | - |
| EXIT_MESSAGE | VARCHAR(2500) | Yes | - |
| LAST_UPDATED | TIMESTAMP | Yes | - |
| BATCH_STEP_EXECUTION_CONTEXT | |||
| STEP_EXECUTION_ID | BIGINT | No | PK |
| SHORT_CONTEXT | VARCHAR(2500) | No | - |
| SERIALIZED_CONTEXT | TEXT | Yes | - |
| BATCH_JOB_EXECUTION_CONTEXT | |||
| JOB_EXECUTION_ID | BIGINT | No | PK |
| SHORT_CONTEXT | VARCHAR(2500) | No | - |
| SERIALIZED_CONTEXT | TEXT | Yes | - |
Frequently asked questions
What are the Spring Batch metadata tables?
Six tables: BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION, BATCH_JOB_EXECUTION_PARAMS, BATCH_STEP_EXECUTION, BATCH_STEP_EXECUTION_CONTEXT, and BATCH_JOB_EXECUTION_CONTEXT. Together they record every job instance, execution, step, parameter, and restart checkpoint.
What is the difference between BATCH_JOB_INSTANCE and BATCH_JOB_EXECUTION?
A job instance is the logical job (name + identifying key) - one row no matter how many times it runs. Each run creates a new job execution row pointing back at the instance, so restarts and retries share one instance with many executions.
Why do Spring Batch IDs use sequences instead of generated keys?
Because the generated key must be assigned to the Java domain object immediately after insert. Sequences let Spring Batch fetch the ID first, set it on the object, then insert - a pattern that works uniformly across all supported databases.
Explore more schemas
Visualize your own database
Paste your PostgreSQL connection string and get an interactive ER diagram of your own schema in under 10 seconds. No signup required.
Try it free →