PostgreSQL 18 with koldstore preinstalled for trying KoldStore quickly.
5.9K
PostgreSQL with the KoldStore extension preinstalled. Use this image to try tiered storage without building from source.
Keep hot data in PostgreSQL. Move historical rows to Parquet. Query one table.
KoldStore is an open-source PostgreSQL extension for tables that grow forever (messages, audit logs, AI history, notifications, events, IoT). The active working set stays in PostgreSQL; older rows flush to compressed Parquet on storage you control; reads still go through the original table.
A built-in database worker auto-flushes managed tables when hot rows exceed hot_row_limit (auto_flush defaults to true). Manual flush_table remains available if you want to control flush yourself (for example with pg_cron).
Early development — not production-ready. Manage, flush, auto-flush scheduling, and hot/cold query work. Recovery, backup/restore, compaction, and schema evolution are still being hardened.
docker pull jamals86/pg-koldstore:latest # PostgreSQL 18
docker run --rm -e POSTGRES_PASSWORD=postgres -p 5432:5432 jamals86/pg-koldstore:latest
psql postgres://postgres:[email protected]:5432/koldstoredb
PostgreSQL 16 remains available as jamals86/pg-koldstore:pg16 (or :<version>-pg16).
Windows / Docker Desktop bind mounts: if you map a host folder to
/koldstore-data, the image entrypoint creates /koldstore-data/cold and makes
it writable for the postgres user (bind mounts often arrive as root-owned).
Prefer base_path => '/koldstore-data/cold/' only after that path is writable;
/tmp/koldstore-demo always works inside the container. Watch
docker logs <container> for WARNING: koldstore flush: FAILED ... (permission
errors used to be easy to miss at LOG level).
Multi-arch (linux/amd64, linux/arm64). Default database is koldstoredb. Extension koldstore is created on first init, shared-preloaded (required for KoldMergeScan on every connection), and started with wal_level=logical (required for manage_table / async mirror).
SHOW shared_preload_libraries; -- includes koldstore
SHOW wal_level; -- logical
SELECT koldstore.preload_status();
SELECT jsonb_pretty(koldstore.async_mirror_status()); -- wal.current_lsn vs wal.applied_lsn
SELECT koldstore.register_storage(
name => 'local-dev',
storage_type => 'filesystem',
base_path => '/tmp/koldstore-demo', -- or '/koldstore-data/cold/' on a writable mount
credentials => '{}'::jsonb,
config => '{}'::jsonb
);
CREATE TABLE messages (
id bigint PRIMARY KEY,
body text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
ALTER TABLE messages SET (
koldstore_enabled = true,
koldstore_storage = 'local-dev',
koldstore_hot_row_limit = 1000,
koldstore_min_flush_rows = 1,
koldstore_max_rows_per_file = 1000
);
INSERT INTO messages (id, body)
SELECT gs, 'row ' || gs FROM generate_series(1, 1012) AS gs;
-- Returns jsonb: job_id / status / error (not a bare uuid)
SELECT jsonb_pretty(koldstore.flush_table(table_name => 'messages'::regclass));
SELECT count(*) FROM messages; -- still 1012 via KoldMergeScan
| Component | Notes |
|---|---|
| PostgreSQL | 18 by default (latest / pg18, amd64+arm64); 16 via pg16 (amd64); optional 17 via pg17 (amd64) |
koldstore | Preinstalled + in shared_preload_libraries (required for KoldMergeScan + auto-flush worker); wal_level=logical by default |
pg_cron | Packaged only; not preloaded. Enable yourself if you want cron-based flush |
| Entrypoint | Compatible with official POSTGRES_* env vars |
| Tag | Meaning |
|---|---|
latest | Latest published release on PostgreSQL 18 (amd64 + arm64) |
pg18 | Floating tag for the latest PostgreSQL 18 image (amd64 + arm64) |
pg16 | Floating tag for the latest PostgreSQL 16 image (amd64 only) |
pg17 | Floating tag for the latest PostgreSQL 17 image (amd64 only, published when enabled in Release) |
<version>-pg18 | Specific KoldStore version on PostgreSQL 18 |
<version>-pg16 | Specific KoldStore version on PostgreSQL 16 |
<version>-pg17 | Specific KoldStore version on PostgreSQL 17 |
Example: jamals86/pg-koldstore:0.1.12-preview.0-pg18
PGDATA is major-version specific. Do not point a PG18 container at a PG16 volume (or the reverse) without
pg_upgrade.
Same as the official Postgres image, including:
POSTGRES_PASSWORD (required)POSTGRES_USER (default postgres)POSTGRES_DB (default koldstoredb)Content type
Image
Digest
sha256:ef8ba99c7…
Size
96.9 MB
Last updated
about 1 month ago
docker pull jamals86/pg-koldstore