Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ HotData. Wrap an expensive function with `@materialize`: on a **miss**, the
function runs in the host application's environment and the result is captured
and loaded into HotData as parquet; on a **hit**, the host app's database is
never touched — the caller gets a `MaterializedFrame` backed by a HotData
managed database that supports dataframes, SQL, and vector/BM25 search.
instant database that supports dataframes, SQL, and vector/BM25 search.

This is not a fast key-value cache. It is a **capability cache**: a hit does
not save microseconds, it saves the host database from running a
Expand Down Expand Up @@ -73,7 +73,7 @@ Registry schema (one table, `main.entries`, in the registry database):
CREATE TABLE entries (
fingerprint TEXT PRIMARY KEY, -- content-address of the entry
key TEXT, -- human-readable label from the decorator
database_id TEXT, -- the entry's managed database (db_...)
database_id TEXT, -- the entry's instant database (db_...)
status TEXT, -- building | ready | failed
created_at TIMESTAMP,
expires_at TIMESTAMP,
Expand Down Expand Up @@ -115,7 +115,7 @@ results without round-tripping data through the client.

### 3. Database-per-entry

Every materialized entry is **its own managed database**, named
Every materialized entry is **its own instant database**, named
`mz_<fingerprint32>` (a display label — identity is the server-issued
database id, mapped from the full fingerprint by the registry). The captured result lands in a fixed
location inside it: `main.data`.
Expand Down Expand Up @@ -366,7 +366,7 @@ synchronous — fine for WSGI; async views get `sync_to_async` wrappers

## Open questions

1. **Workspace limits on managed database count** — database-per-entry needs
1. **Workspace limits on instant database count** — database-per-entry needs
a sanity check against quotas and any per-database cost/overhead on the
HotData side.
2. **Registry write throughput** — every persist costs an upload session +
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ SQL server-side.

Think materialized views, not Redis: entries are snapshots of expensive
analytical results, with a TTL lifecycle, each living in its own Hotdata
managed database. The host application needs **no migrations and no Redis** —
entry metadata lives in a small Hotdata managed database (the registry),
instant database. The host application needs **no migrations and no Redis** —
entry metadata lives in a small Hotdata instant database (the registry),
created on first use.

Measured against TPC-H on a Neon Postgres (see [demo/](demo/)):
Expand Down Expand Up @@ -154,10 +154,10 @@ deletes them proactively is on the roadmap below.

## How it works

One managed database (the **registry**) holds one row per entry: fingerprint,
One instant database (the **registry**) holds one row per entry: fingerprint,
status, TTL, the entry's database id, and — for small results — the data
itself as an inline Arrow payload, so a chart-sized hit is served in a single
API round trip. Larger results live in a per-entry managed database and are
API round trip. Larger results live in a per-entry instant database and are
fetched as an Arrow IPC stream via a result id minted at persist time (no
re-query on hits). Failures are loud and fail toward "no cache": a failed
persist leaves no registry row, and the next request simply misses again.
Expand Down
2 changes: 1 addition & 1 deletion hotdata_materialized/registry.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""The remote registry: one managed database holding one row per entry.
"""The remote registry: one instant database holding one row per entry.

The hit/miss check is a SELECT against this database — the host application
keeps no local state. POST /v1/queries is read-only (DML and DDL are
Expand Down
2 changes: 1 addition & 1 deletion hotdata_materialized/store.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""The entry store: one managed database per materialized entry.
"""The entry store: one instant database per materialized entry.

Persist path: create database -> upload parquet (presigned, direct to object
storage) -> load into main.data -> mark the registry row ready. Everything
Expand Down
Loading