demo/

directory
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: MIT

README

PredictiveCache Demo

This directory contains a working PostgreSQL example and an integration guide for an existing Go service.

Run the Demo

Prerequisites:

  • Go 1.22 or newer;
  • PostgreSQL command-line tools initdb and pg_ctl on PATH;
  • a C compiler for the default pg_query_go PostgreSQL parser build.

Docker is not required. From the repository root:

./scripts/run-demo.sh

The script uses /tmp by default. Set PCACHE_TMPDIR to another existing short-path directory if needed.

The script creates a disposable PostgreSQL cluster under the system temporary directory, runs postgres/main.go, and removes the cluster. The program:

  1. creates user and order tables;
  2. trains a repeated user-to-orders query transition;
  3. shows the predicted template and argument binding;
  4. triggers a real background PostgreSQL prefetch;
  5. proves the next orders query was served from the in-memory cache.

The final line should be:

DEMO PASS: a learned transition executed on PostgreSQL in the background and served the next query from cache

Add It to an Existing Project

Install the module:

go get github.com/Hetul3/PredictiveCache@latest
go get github.com/jackc/pgx/v5

Register pgx with database/sql, open the existing database handle, and wrap it once at application startup:

import (
	"database/sql"
	"time"

	"github.com/Hetul3/PredictiveCache"
	_ "github.com/jackc/pgx/v5/stdlib"
)

db, err := sql.Open("pgx", dsn)
if err != nil {
	return err
}

pc, err := predictivecache.Wrap(
	db,
	predictivecache.DialectPostgres,
	predictivecache.WithCacheTTL(5*time.Second),
	predictivecache.WithMaxCacheBytes(64<<20),
	predictivecache.WithPrefetchEnabled(true),
)
if err != nil {
	return err
}
defer pc.Close()

Replace read calls with pc.QueryContext. The return type is *predictivecache.Rows, which supports Next, Scan, Columns, ColumnTypes, Err, Close, and FromCache:

ctx := predictivecache.WithSessionID(r.Context(), requestID)
ctx = predictivecache.WithRoute(ctx, "GET /users/:id")

rows, err := pc.QueryContext(
	ctx,
	"select id, name from users where id = $1",
	userID,
)
if err != nil {
	return err
}
defer rows.Close()

for rows.Next() {
	var id int64
	var name string
	if err := rows.Scan(&id, &name); err != nil {
		return err
	}
}
if err := rows.Err(); err != nil {
	return err
}

Run writes through pc.ExecContext so table-version invalidation occurs:

_, err = pc.ExecContext(
	ctx,
	"update users set name = $1 where id = $2",
	name,
	userID,
)

If another connection, process, or service writes to the database, notify this client before relying on cached reads:

err := pc.InvalidateTables("users", "orders")
// Use pc.InvalidateAll() when the affected tables are unknown.

Give the Predictor Useful Context

Use one session ID for the related queries in a request or workflow. A route helps distinguish code paths that begin with the same query:

ctx = predictivecache.WithSessionID(ctx, traceID)
ctx = predictivecache.WithRoute(ctx, "GET /users/:id")
ctx = predictivecache.WithTenant(ctx, tenantID)

When a later query needs a value that is not available from the previous query's arguments, supply it explicitly:

ctx = predictivecache.WithBindValue(ctx, "user_id", userID)

The library never executes a predicted query unless every argument has a high-confidence binding.

Tune It Safely

Prefetching is off by default. Start with exact caching, collect metrics, and enable prefetch only for repeated, bindable query flows with enough delay for a background query to finish.

Useful controls:

predictivecache.WithMinEventsBeforePrefetch(500)
predictivecache.WithPredictionConfidenceThreshold(0.70)
predictivecache.WithBindingMinTrials(5)
predictivecache.WithBindingConfidenceThreshold(0.85)
predictivecache.WithPrefetchConcurrency(2)
predictivecache.WithPrefetchMaxQPS(20)
predictivecache.WithPrefetchTimeout(500 * time.Millisecond)

Inspect behavior rather than assuming prefetch is helping:

stats := pc.Stats()
explain, err := pc.Explain(ctx, query, args...)

Pay particular attention to cache hit-rate lift, PrefetchHits, PrefetchWasted, PrefetchErrors, and rejection counters. Disable prefetch when it raises database load without improving application latency.

Persistence and Privacy

Learned metadata persistence is opt-in:

predictivecache.WithLogDir("./.predictivecache")

Persistence excludes sessions, argument values, result rows, and cache entries. Original executable SQL is also excluded unless WithPersistRawSQL(true) is set. Review SQL text for sensitive literals before enabling that option.

Current Boundaries

  • PostgreSQL is the only supported dialect.
  • Explicit transaction caching and prefetching are not supported in v1.
  • The API is a DB-like wrapper, not a transparent database/sql/driver.
  • External writes require explicit invalidation.
  • The no-cgo parser fallback has intentionally narrower SQL coverage and disables structural cold-start fallback.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL