ADR-004: Use H2 as In-Memory Database for Persistence¶
| Field | Value |
|---|---|
| Date | 2026-03-21 |
| Status | Accepted |
| Deciders | Project owner |
| Supersedes | — |
| Superseded by | — |
Context and Problem Statement¶
The Task Manager backend needs a persistence layer to store Task records across API calls
within a single application runtime. The goal of the project is a working prototype that can
be demonstrated without requiring external infrastructure (e.g., a running database server).
A database must be chosen that satisfies development simplicity while keeping the option open to migrate to a production-grade RDBMS in the future.
Decision Drivers¶
- Zero-infrastructure setup: no external database process should be required to run or test the application.
- Developer experience: the app must start with a single command (
make run) with no additional setup steps. - Spring Boot compatibility: the solution must integrate with Spring Data JPA and JDBC out of the box.
- Prototype scope: persistence across application restarts is not required for this phase.
Considered Options¶
- H2 (in-memory, embedded)
- PostgreSQL (external, via Docker Compose)
- SQLite (file-based, embedded)
Decision Outcome¶
Chosen option: H2 (in-memory, embedded), because it requires zero external infrastructure, integrates natively with Spring Boot auto-configuration, and is sufficient for the prototype scope where data persistence across restarts is not required.
Positive Consequences¶
- The application starts with no setup beyond a JVM — no database installation, no Docker Compose.
- Spring Boot auto-configures the H2 data source and schema on startup.
- The H2 console (
/h2-console) provides a built-in UI for inspecting data during development. - Switching to PostgreSQL later requires only a dependency swap and
application.ymlchanges; the JPA layer is unchanged.
Negative Consequences / Risks¶
- All task data is lost on every application restart — not suitable for production use.
- H2 SQL dialect differences can mask compatibility issues with production databases; integration tests against PostgreSQL would be required before a production migration.
Pros and Cons of the Options¶
Option 1 — H2 (in-memory, embedded)¶
- Pro: No external dependencies; runs entirely within the JVM process.
- Pro: Native Spring Boot auto-configuration; minimal
application.ymlsetup. - Pro: Built-in web console for development inspection.
- Con: Data lost on restart; not suitable for production.
- Con: Dialect differences may mask SQL compatibility issues.
Option 2 — PostgreSQL (external, via Docker Compose)¶
- Pro: Production-equivalent SQL dialect; no migration surprises.
- Con: Requires Docker and a running container; adds setup friction for developers.
- Con: Overkill for a prototype scope with no real persistence requirement.
Option 3 — SQLite (file-based, embedded)¶
- Pro: Embedded, no external process required; data survives restarts.
- Con: Poor Spring Data JPA / Hibernate support; requires additional configuration.
- Con: Not a common choice in the Spring ecosystem; limited community guidance.