Skip to content
CAI
Software that uses CAICheck a score

SwissBorg/akka-persistence-postgres

55.6

Adequate · 21 September 2026

3.5k

lines of production code

Scala

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a PostgreSQL-specific implementation of the Akka Persistence plugin, designed to store and retrieve persistent state for distributed actors. It manages write and read operations through configurable journal partitioning, metadata tracking, and tag-based querying, while also handling snapshot storage. The system includes migration tools to upgrade existing JDBC-based schemas to the new PostgreSQL structure.

How it got here

2014–2016 — Project restructuring and build standardization

9 changes.

The period focused on refactoring the project into a multi-module structure and standardizing the build configuration. Hardcoded database configurations and obsolete test suites were removed to support a more flexible, multi-backend approach, while new scripts and build plugins were added to streamline development and release workflows.

2019–2023 — PostgreSQL persistence implementation

26 changes.

This period focused on replacing the generic JDBC persistence layer with a dedicated PostgreSQL implementation using Slick. The work introduced support for partitioned journal tables, metadata tracking, and asynchronous serialization to improve performance and scalability. Comprehensive test coverage and migration scripts were added to support the new architecture.

Features

Added migration scripts for archiving and migrating journal data

Added SQL and shell scripts to support archiving detached partitions and migrating journal data to flat, nested-partitioned, and range-partitioned table structures. The archivation scripts handle the full lifecycle of partition detachment, export, drop, re-import, and reattachment. The migration scripts provide step-by-step procedures to copy data, fill tag tables, move sequences, and create indexes for three target schemas: flat tables, nested partitions, and range partitions.

scripts/migration · high confidence

Added scripts for local PostgreSQL development and release management

New shell scripts and configuration files have been added to the scripts directory to streamline local development and release workflows. The \create-release-issue.sh\ script automates the creation of release tracking issues using a provided version number. Additionally, \docker-compose.yml\ and \launch-postgres.sh\ provide a standardized way to spin up a local PostgreSQL instance for development, while \psql-cli.sh\ offers a quick reference for common psql commands and database interactions.

scripts · high confidence

Initial project setup and documentation

The repository was initialized with essential project configuration files, including \.sbtopts\ for SBT memory settings, \.scala-steward.conf\ to manage automated dependency updates, and \.scalafmt.conf\ for code formatting. A \CONTRIBUTING.md\ guide was added to outline the development workflow and pull request requirements. The \README.md\ was updated to provide comprehensive usage instructions, feature highlights, and installation steps for the Akka Persistence Postgres plugin.

(repo-wide) · high confidence

Introduce journal metadata tracking with partitioned table and trigger

A new \journal\_metadata\ table is created to track per-persistence metadata, including \min\_ordering\ and \max\_ordering\ values. The table is partitioned by \persistence\_id\ into 10 hash partitions. A corresponding trigger and function (\update\_journal\_metadata\) are added to the \journal\ table to automatically upsert metadata on insert, initializing \min\_ordering\ to -1 for new records. A migration script also backfills existing data into the metadata table.

scripts/migration-0.6.0 · medium confidence

PostgreSQL persistence plugin introduces configurable journal partitioning and metadata tables

The PostgreSQL persistence plugin now supports configurable journal partitioning via the \NestedPartitionsJournalDao\ and \FlatJournalDao\ implementations, allowing users to split journal data into partitions for improved performance. Additionally, a new \journal\_metadata\ table and associated configuration options are introduced to store and query metadata (such as max sequence numbers and ordering) separately from the main journal table, enabling faster queries and optional usage based on configuration. Users can now tune partition sizes, prefixes, and metadata table settings to optimize their Akka Persistence setup.

core/src/main/resources · medium confidence

Behavioural changes

Add new migration module for journal and snapshot store schema updates

A new \migration\ module has been introduced to handle the migration of the \journal\_persistence\_ids\ table and related schema changes. This includes creating temporary tables for journal and snapshot data, defining schemas for partitioned and flat journal tables, and implementing triggers to update metadata (such as \max-sequence-number\ and \min-ordering\) during the migration process. The migration logic supports both partitioned and nested partitioned DAOs, ensuring that the \journal\_persistence\_ids\ table is properly updated to support the \allPersistenceIds\ query. Additionally, the migration process handles the deserialization of old journal and snapshot data, serializing it into the new format, and swapping the old tables with the new ones.

migration/src/main/scala · medium confidence

Added database index creation scripts for partitioned journal tables

New SQL migration scripts have been added to the 0.5.0 release to create unique indexes on partitioned journal tables. The first script manually creates the indexes using the CONCURRENTLY option to avoid locking, while the second script ensures the indexes exist for Flyway migrations and drops a global non-unique index. This improves query performance for persistence and sequence number lookups in partitioned tables.

scripts/migration-0.5.0 · medium confidence

Asynchronous serialization interfaces for persistence and snapshots

The persistence and snapshot serializers now operate asynchronously. The new PersistentReprSerializer and SnapshotSerializer traits define interfaces where serialization methods return Scala Futures, enabling non-blocking, concurrent processing of persistent and snapshot data. This change improves throughput by allowing the serialization layer to leverage the underlying async execution context rather than blocking threads.

core/src/main/scala/akka/persistence/postgres/serialization · high confidence

Configurable batch size for PostgreSQL migration

The migration module now includes a configuration file that allows users to set the batch size for the PostgreSQL migration process, with a default value of 500 records per batch.

migration/src/main/resources · high confidence

Fix eventsByTag returning events with incorrect ordering offsets

The \eventsByTag\ query was returning events with ordering values less than the expected offset, causing incorrect stream behavior. This fix ensures that the offset returned by \eventsByTag\ correctly reflects the ordering of events, aligning with the expected sequence numbers. Additionally, the implementation now uses \Source.futureSource\ instead of \Source.future.flatMapConcat\ for improved efficiency, and the plugin configuration is properly passed when looking up event adapters.

core/src/main/scala/akka/persistence/postgres/query/scaladsl · medium confidence

Introduces caching for tag ID resolution in Postgres persistence

The Postgres persistence plugin now caches tag name-to-ID lookups using an asynchronous Scaffeine-based cache. This change, implemented in the new \CachedTagIdResolver\ and supporting classes (\TagDao\, \EventTag\, \EventTagQueries\), reduces database queries for tag lookups, improving performance for applications using tag-based persistence.

core/src/main/scala/akka/persistence/postgres/tag · medium confidence

Migrate Akka Persistence from JDBC to Postgres

The persistence layer has been refactored to use PostgreSQL directly via Slick, replacing the previous JDBC-based implementation. This introduces new components including PostgresAsyncWriteJournal for write operations, JournalSequenceActor for tracking ordering IDs, and PostgresReadJournal with its Java/Scala DSLs for queries. The package structure has been renamed from akka.persistence.jdbc to akka.persistence.postgres, and all related classes (such as JournalDao and configuration classes) have been renamed to reflect the Postgres focus.

core/src/main/scala/akka/persistence/postgres/query · high confidence

New Postgres snapshot store implementation

The Postgres snapshot store has been refactored into a new \PostgresSnapshotStore\ class that delegates to a \SnapshotDao\ interface, with a default \ByteArraySnapshotDao\ implementation that serializes snapshots using Akka's \Serialization\ and stores metadata as JSON in a dedicated \metadata\ column. This change introduces a cleaner separation between the actor-level store and the data-access layer, allowing for alternative DAO implementations and more compact JSONB storage of snapshot metadata.

core/src/main/scala/akka/persistence/postgres/snapshot · high confidence

PostgreSQL persistence config and data models for journal, metadata, and tags

The Akka Persistence JDBC plugin now provides explicit configuration classes and data models for PostgreSQL, including support for partitioned journal tables, a separate journal metadata table, and a tags table. Users can configure table names, column names, partition sizes, and whether to use journal metadata. The default DAO implementations have been renamed (e.g., ByteArrayJournalDao to FlatJournalDao) and the package structure updated to akka.persistence.postgres, with the main config file AkkaPersistenceConfig.scala introducing new configuration options for journal partitions, metadata, and tags.

core/src/main/scala/akka/persistence/postgres/config · high confidence

Refactor Postgres read journal DAOs to support partitioned and flat strategies with optional metadata usage

The Postgres read journal implementation has been refactored to separate concerns between flat and partitioned journal strategies. A new \BaseByteArrayReadJournalDao\ trait and \ReadJournalDao\ interface define the query logic, while \FlatReadJournalDao\ and \PartitionedReadJournalDao\ implement specific table mappings. The \PartitionedReadJournalDao\ now optionally uses a \journal\_metadata\ table to optimize message queries by pruning partitions based on minimum ordering, controlled by the \useJournalMetadata\ configuration option. This change improves query efficiency for events by tag and other read operations.

core/src/main/scala/akka/persistence/postgres/query/dao · high confidence

Refactored Postgres journal DAO with metadata table and partitioning support

The Postgres journal implementation has been refactored to support optional event metadata storage in a separate 'journal\_metadata' table, which can be used to optimize queries for the highest sequence number and partition pruning. The codebase has been reorganized into a new package structure (akka.persistence.postgres.journal.dao) with distinct DAO implementations: FlatJournalDao for standard tables, and PartitionedJournalDao/NestedPartitionsJournalDao for partitioned schemas. The serialization layer now stores event metadata (serializer ID, manifest, writer UUID, timestamp) as a compact JSON object in the 'metadata' column. Additionally, logical deletion is deprecated with a warning, and the 'pg-' prefixed configuration keys have been renamed to 'postgres-' prefixes.

core/src/main/scala/akka/persistence/postgres/journal/dao · high confidence

Refactored database initialization and error handling for Postgres persistence

The database layer has been restructured to improve how database connections are managed and how errors are handled. A new \SlickExtension\ and \SlickDatabase\ abstraction replaces the previous direct Slick usage, introducing a provider pattern that supports both eager and lazy database initialization, as well as shared database connections. Additionally, a new \DbErrors\ object provides uniform handling for partitioning and unique index creation errors, ensuring that duplicate table or index errors are treated as successful operations rather than failures.

core/src/main/scala/akka/persistence/postgres/db · high confidence

Removal of hardcoded database configuration and JDBC implementation classes

The hardcoded configuration classes for H2 and PostgreSQL (H2Config, PostgresqlConfig) and the generic JDBC connection and actor configuration traits (ActorConfig, Config, JdbcConnection) have been removed. This eliminates the previous mechanism where database credentials, connection pool settings, and SQL execution logic were embedded directly in the Scala source code, indicating a shift away from these specific internal implementation details.

src/main/scala · high confidence

Removed default JDBC journal and H2 schema from resources

The default JDBC journal configuration and the H2 in-memory database schema have been removed from the project's resources. Users relying on the default H2 setup or the pre-defined table structure will need to provide their own configuration and schema, as these defaults are no longer bundled with the library.

src/main/resources · high confidence

Standardize build configuration and centralize dependencies

The project's build structure has been refactored to centralize dependency management and standardize build settings. Dependencies for Akka, Slick, Flyway, and others are now defined in a dedicated \Dependencies.scala\ file, which also specifies Scala 2.13.12 as the default version. The \ProjectAutoPlugin\ consolidates project metadata, compiler options, and documentation settings, while \AutomaticModuleName.scala\ provides a helper for setting the Java Module System name. Additionally, the build properties have been updated to use SBT 1.9.8, and the plugin configuration now includes sbt-scalafmt, sbt-mima-plugin, sbt-ci-release, and sbt-unidoc.

project · high confidence

Test coverage

Added PostgreSQL schema test resources for journal, tags, and snapshot tables; Added comprehensive test suites for Postgres journal partitioning and performance; Added configuration tests for Postgres persistence components; Added integration tests for Postgres migration scripts; Added test configuration files for Postgres persistence; Added test configuration files for the migration module; Added test coverage for Postgres persistence queries; Added test infrastructure for Akka Persistence Postgres; Added tests for PostgreSQL tag resolution and DAO; Added tests for Postgres read journal DAOs; Added tests for Postgres snapshot store and DAO components; Removed hardcoded test configuration file; Removed obsolete JDBC journal tests; Removed test utility for JDBC table initialization.

Dependencies

Restructure project into core and migration subprojects

The build configuration was refactored from a single-project layout into a multi-project structure containing 'core' and 'migration' subprojects. This change introduces separate build definitions for the main library and its data migration tools, while also adding a code formatting verification task to enforce style consistency across the codebase.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 52 → 56 (+3.8)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 97 (-2.6)
  • Architecture 100 → 64 (-36.4)
  • Maturity 40 → 45 (+5.1)
  • Readiness 43 → 55 (+11.6)
  • Security 67 → 86 (+19.3)

Resolved (13)

  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Further orphaned files (smaller)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • LLM evaluation failed
  • No exposed public API
  • Test reliability not included
  • complexity unreadable for .scala — churn × complexity hotspots could not be measured
  • dormant codebase — no living knowledge left to concentrate

New (22)

  • Dormant codebase
  • Duplicated block (14–16 lines × 2) (core/src/main/scala/akka/persistence/postgres/journal/dao/PartitionedJournalDao.scala)
  • Duplicated block (9 lines × 2) (core/src/main/scala/akka/persistence/postgres/db/DbErrors.scala)
  • High IaC: WD-COMPOSE-0002 (scripts/docker-compose.yml)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • Jdbc4JournalMigration.migrateJournal (cognitive 30) (migration/src/main/scala/akka/persistence/postgres/migration/journal/Jdbc4JournalMigration.scala)
  • Jdbc4SnapshotStoreMigration.migrateSnapshots (cognitive 20) (migration/src/main/scala/akka/persistence/postgres/migration/snapshot/Jdbc4SnapshotStoreMigration.scala)
  • JournalSchema.swapJournals (cognitive 45) (migration/src/main/scala/akka/persistence/postgres/migration/journal/JournalSchema.scala)
  • Low cohesion: PartitionedJournal (LCOM4 4) (migration/src/main/scala/akka/persistence/postgres/migration/journal/JournalSchema.scala)
  • Medium: security finding (details withheld)
  • No dependency advisory monitoring
  • Outdated: github-pages
  • Outdated: just-the-docs
  • Outdated: minima
  • Outdated: tzinfo-data
  • PartitionedJournal.swapJournals (cognitive 45) (migration/src/main/scala/akka/persistence/postgres/migration/journal/JournalSchema.scala)
  • …and 2 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

SwissBorg/akka-persistence-postgres was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 45b809cb3e5194f4084863d68c81617a985e1864 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-fa71c66cabd8.