# Tessera DB — full text > The complete written content of https://tesseradb.par2labs.com, as Markdown, for AI assistants and answer engines. Tessera DB is a product of PAR2 LABS (https://par2labs.com). The one-line-per-page index is at https://tesseradb.par2labs.com/llms.txt. Generated from the same records the pages render, on 2026-09-22. Images are described, not linked. ## In short **One copy of the data. Five ways to read it.** A multi-model database for AI workloads: relational, graph, vector, full-text and time-series over the same record, on your own hardware. #### What it solves - A graph database, a vector store, a search engine and a SQL store, with a sync job holding them together. → One store, indexed five ways. Nothing to sync and no ETL between them. - Retrieval that shows which passages looked similar, not which facts the answer used. → Vectors, full-text and graph context fused in one query, over facts you can trace. - A regulator asks what you knew, and when, and whether the record was changed. → Valid time and transaction time on every fact, content-addressed so tampering shows. #### Why it is different - **5 Dimensions, one copy** — Relational, graph, vector, full-text and time-series all read the same record. - **3 Query languages** — SQL, Cypher and TQL, detected at parse time and routed to the right executor. - **n-ary Hyperedges** — One relationship links any number of entities, each in a named role. - **1 Binary, your hardware** — Self-contained, on an Apache 2.0 open-source core. Built for: Fraud and AML teams, AI retrieval pipelines, Regulated data that stays in the building, Teams running four stores in sync. ## The product ### Tessera DB https://tesseradb.par2labs.com/ Multi-model Database · Neo4j alternative · Beta · v0.9 A multi-model database that stores your data once and queries it five ways — relational, graph, vector, full-text and time-series — built for AI workloads and run on your own hardware. One copy of the data, five ways to read it. Tessera DB stores each fact once, as a hyperedge — a record that can link any number of entities, each in a named role — and indexes it five ways: relational, graph, vector, full-text and time-series. SQL, Cypher and TQL all query that one copy, with no replication, sync or ETL between separate stores. Every fact is content-addressed with BLAKE3 and carries both valid time and transaction time. It ships as one self-contained binary that runs on your own hardware, on an Apache 2.0 open-source core. *Screens — One store, run from one console.* #### Proof **The engine, counted.** Stats: - **5** — Data dimensions over one copy: relational, graph, vector, full-text and time-series - **3** — Query languages — SQL, Cypher and TQL — detected at parse time - **60+** — Graph algorithms in-database, from centrality to link prediction (Enterprise) - **8** — AutoGuard defence layers running inside the engine (Enterprise) #### Features - **Five dimensions, one copy** — Relational, graph, vector, full-text and time-series indexes over the same record — no sync, no ETL. - **Hyperedges** — One relationship links any number of entities, each in a named role, with no invented middle nodes. - **Three query languages** — SQL, Cypher and TQL over one dataset, detected at parse time and routed to the right executor. - **Hybrid retrieval** — HNSW vectors and BM25 full-text, fused with graph context by Reciprocal Rank Fusion. - **Time-travel and branching** — Valid and transaction time on every fact, and Git-style branches for changes made in isolation. - **AutoGuard** — Eight defence layers inside the engine, and a hash-chained audit log. Enterprise tier. #### What it is for - A fraud or AML team needs cycle detection, anomaly scoring and screening over one copy of the live transaction graph. - Your retrieval pipeline has to show which facts an answer used, not only which passages looked similar. - A regulator asks what you knew and when, and the answer has to be reconstructed and shown to be untampered. - Customer, device and address records are scattered and duplicated, and you need one graph of who connects to whom. - Regulated data cannot leave the building, but the team still needs vector search and in-database ML. - You run a graph database, a vector store, a search engine and a SQL store, and keeping them in sync has become the job. #### Specifications - **Data model**: Role-typed hyperedges · BLAKE3 content-addressed - **Dimensions**: Relational · graph · vector · full-text · time-series - **Time**: Bitemporal · valid time and transaction time - **Query**: SQL · Cypher (common subset) · TQL, auto-detected - **Indexes**: HNSW · BM25 · B-tree · CSR/CSC - **Transactions**: ACID · isolation up to serializable - **Storage**: LSM-tree · WAL · MVCC · Arrow IPC · tiered - **Interfaces**: REST/OpenAPI 3.0.3 · gRPC · PostgreSQL wire · JDBC - **SDKs**: Python · Rust · TypeScript - **Security**: API keys · RBAC · SSO and AES-256-GCM at rest (Enterprise) - **Observability**: Prometheus · OpenTelemetry (OTLP) - **Topology**: Single node · Raft building blocks for multi-node (Enterprise) - **Deployment**: One self-contained Rust binary · self-hosted · no JVM - **Licence**: Apache 2.0 core · signed keys for Enterprise tiers #### Features — Nine modules, one database. https://tesseradb.par2labs.com/features The data model, three query languages, search, graph data science, in-database ML, data management, security and the interfaces around them — each marked Community, Enterprise or Enterprise Plus, and compared both ways against the incumbents at the foot of the page. **Every capability, by module.** **The admin portal, screen by screen.** **Where Tessera leads.** | Capability | Tessera | Neo4j | TigerGraph | Dgraph | Note | | --- | --- | --- | --- | --- | --- | | Hyperedge (N-ary) relationships | Yes | No | No | No | One fact links any number of entities, each in a named role. | | Five dimensions in one engine | Yes | No | No | No | Relational, graph, vector, full-text and time-series over one copy. | | SQL tables alongside the graph | Yes | No | No | No | | | Built-in vector search (HNSW) | Yes | Yes | No | No | Neo4j added it in 5.x; in Tessera it is fused with graph and text. | | Hybrid retrieval (vector + text + graph) | Yes | No | No | No | One query fuses all three with Reciprocal Rank Fusion. | | Cypher, TQL and SQL | Yes | Partial | Partial | No | | | 60+ graph algorithms | Yes | Paid add-on | Partial | No | Neo4j's Graph Data Science library is a paid add-on. In Tessera it is part of Enterprise. | | In-database ML (GNN, GAN, link prediction) | Yes | Partial | No | No | Trained where the data lives, no export pipeline. Enterprise in Tessera. | | Bitemporal (valid + transaction time) | Yes | Partial | No | No | Both axes native; elsewhere it takes manual timestamp scaffolding. | | Git-style data branching | Yes | No | No | No | | | Built-in time-series | Yes | No | No | No | | | Native data lineage | Yes | No | No | No | Enterprise in Tessera. | | Content-addressed identity (BLAKE3) | Yes | No | No | No | | | 8-layer AI defence (AutoGuard) | Yes | No | No | No | Enterprise in Tessera. | | Fraud, AML and sanctions pack | Yes | No | No | No | FIBO + BIAN, fraud-cycle detection, AML alerts, screening against your lists. Enterprise and Enterprise Plus. | | Tamper-evident, hash-chained audit log | Yes | Partial | Partial | No | | | PostgreSQL wire protocol | Yes | No | No | No | psql, Postgres drivers and BI tools with no Tessera-specific code. | | Single native binary (no JVM) | Yes | No | Partial | Partial | Starts in seconds and runs on your own hardware. | | Apache 2.0 open-source core | Yes | Partial | No | Yes | Neo4j Community is GPLv3; Enterprise is closed. | *Yes: shipped today. Partial: the building blocks exist but not yet at that level, or it is on the roadmap. Paid add-on: a separate product.* **Where the incumbents lead, and where Tessera is.** | Capability | Tessera | Neo4j | TigerGraph | Dgraph | Note | | --- | --- | --- | --- | --- | --- | | Production-proven HA clustering | Partial | Yes | Yes | Yes | Neo4j has mature causal clustering and failover. Tessera ships the building blocks (Raft consensus), not battle-tested multi-node HA at scale. | | Very large graphs (billions of edges) | Partial | Yes | Yes | Partial | Tessera is strongest on one well-provisioned node; the largest multi-node scales belong to the incumbents. | | Cypher completeness | Partial | Yes | No | No | Neo4j's is the reference implementation; Tessera supports the common, widely used subset. | | Managed cloud with a free tier | No | Yes | Yes | Yes | Tessera is self-hosted by design: you run the binary on your own hardware. | | SSO (SAML 2.0 and OIDC) | Yes | Yes | Yes | Yes | Both ship in Tessera Enterprise. | | Official client drivers and JDBC | Yes | Yes | Yes | Partial | Python, Rust and TypeScript SDKs and a JDBC driver. | | Prometheus and OpenTelemetry observability | Yes | Yes | Yes | Yes | | | Polished visual graph explorer | Partial | Yes | Yes | Partial | Tessera ships a functional admin console; Neo4j Bloom and Browser are more refined. | | 15+ year ecosystem — books, courses, certification | No | Yes | Partial | Partial | The biggest practical gap, and it will persist. | *Yes: shipped today. Partial: the building blocks exist but not yet at that level, or it is on the roadmap.* **Head to head, both directions.** | Against | Where Tessera is ahead | Where they are ahead today | | --- | --- | --- | | Neo4j | Hyperedges instead of binary edges. 60+ algorithms and in-database ML built in rather than a paid add-on (both Enterprise in Tessera). Vector search fused with graph and keywords in one query. Native bitemporal history, branching and lineage. SQL tables and time-series in the same engine. AutoGuard and a fraud, AML and compliance pack. An Apache 2.0 core, where Neo4j Community is GPLv3 and Enterprise is closed. | A generally available managed cloud (AuraDB). Production-proven causal clustering, read replicas and failover at scale. Complete Cypher. Heavy optimisation for billion-edge graphs. A far larger ecosystem — drivers in many languages, books, courses, certification, and tooling such as Bloom and Browser. A decade of production track record. | | Snowflake | Graph, vector, full-text and time-series beside SQL, where Snowflake needs auxiliary tools. Hyperedges and graph algorithms, where Snowflake has joins. Bitemporal history, branching and lineage. AutoGuard and the compliance pack. Fully self-hosted and air-gapped operation, for data that legally cannot leave the building. | Analytical performance at petabyte scale with a mature managed cloud. A large marketplace, deep BI integration and years of production hardening. A broad set of compliance certifications, where Tessera's certification story is early. Elastic, usage-based pricing with compute and storage separated. | | Pinecone | Multi-model, where Pinecone stores vectors and metadata only. Graph traversal and vector search in one query, fused with keywords. ACID transactions and bitemporal versioning, so you can ask what your embeddings looked like a month ago. Self-hosted deployment, where Pinecone is cloud-only. AutoGuard over the whole retrieval pipeline, with every retrieved fact traceable. | A managed service that scales to very large vector counts automatically, proven across many customers; horizontal sharding of Tessera's vector index is on the roadmap. Managed embedding integrations, where Tessera has you bring your own embedder. A cloud SLA with multi-zone replication. First-class LlamaIndex, LangChain and Haystack examples, where Tessera's framework adapters are still growing. | | TigerGraph | Three query languages against proprietary GSQL alone. Native vector search and hybrid retrieval. An Apache 2.0 core against closed source with opaque enterprise pricing. Content-addressed identity and bitemporal semantics on every fact. AutoGuard, GraphRAG and a banking and compliance pack. | A massively parallel architecture validated at very large scale on real customer workloads. GSQL, refined over many years and expressive for deep traversals once learned. A production track record at large enterprises, with mature drivers and adapters. | | Dgraph | Three query languages and 60+ algorithms, where Dgraph is GraphQL/DQL only with none built in. Vector search and hybrid retrieval. Hyperedges, where Dgraph needs RDF-style reification. Bitemporal history, branching, lineage, in-database ML and a fraud and compliance pack. | An auto-generated GraphQL API, the right primitive for a team that is already GraphQL-first. Distributed by design, sharded and replicated from day one. A lightweight per-node footprint that is easy to embed. | *Use Tessera when you need several of these dimensions in one engine with the defence built in. Use Neo4j, Snowflake or Pinecone when you need only one of them and value the maturity of a pure-play incumbent. Snowflake is a different category — analytical SQL at very large scale — so compare on the use case, not feature for feature.* #### Use cases — Where one engine replaces several. https://tesseradb.par2labs.com/use-cases Ten problems whose data does not fit in one kind of database — from fraud rings and explainable retrieval to audit, supply chains and air-gapped AI. Each use case is marked with the tier it needs; unmarked ones rest on the core engine. **Fraud and anti-money-laundering** Items: - **The problem** — Laundering hides in patterns no single tool sees — circular flows, structuring, mule networks. Teams stitch a graph tool, an ML platform, an anomaly engine and a screening product together. Tessera runs all of it on one copy of the live transaction graph, with every alert traceable to its source facts. - **Fraud cycle detection** — Every circular flow (A → B → C → A) up to a chosen length — the signature of layering, circular trading and collusive rings that per-transaction rules miss. Enterprise. - **Behavioural anomaly scoring** — A running risk score per account, learned from that account's own normal: unusual amounts, velocity, new counterparties, amounts parked just under reporting thresholds. Enterprise. - **AML typology alerts** — Structuring, layering and high-velocity movement raised as a triage-ready queue with typology, severity, account and score. Enterprise Plus. - **Sanctions screening** — Customers, counterparties, beneficiaries and beneficial owners screened against the lists you provide, with fuzzy matching for transliterations and typos. Enterprise Plus. - **Fraud-classifying GNN** — A graph neural network judges an account partly by the company it keeps, trained in-database over the data already stored. Enterprise. **The banking capability matrix.** | Capability | Tier | What it does | | --- | --- | --- | | Fraud cycle detection | Enterprise | Walks the live transaction graph for loops of funds cycling back through intermediaries, returning every cycle up to a chosen path length. | | Behavioural anomaly scoring | Enterprise | Learns each account's own baseline and scores deviations from normal to highly unusual, with the contributing factors shown beside each score. | | AML typology alerts | Enterprise Plus | Structuring, layering and high-velocity typologies raised as machine-readable alerts for case management, each traceable to the facts that raised it, with acknowledgement and an audit trail. | | Sanctions screening | Enterprise Plus | Normalisation, alias checks and fuzzy matching against the lists you load, returning confidence scores and a blocking signal a payment flow can act on. No list fetcher and no bundled government data. | | Regulatory classification | Enterprise Plus | Fields auto-classified for PII sensitivity and applicable regulations, and mapped onto the FIBO ontology and the BIAN service-domain landscape. | | Tamper-evident audit log | Enterprise | Each entry's hash includes its predecessor, so altering, deleting or reordering a past entry breaks the chain and is caught on verification. | *All six run as data is written, not as a nightly batch — over one copy of the live transaction graph, beside the eight AutoGuard layers, with no extra services to run.* **GraphRAG with provenance** Items: - **The problem** — Vector-only retrieval matches by similarity alone — no relationships, no exact-term precision and no record of which facts an answer used, which rules it out for regulated or high-stakes AI. Tessera fuses graph, semantic and keyword signals in one query and traces every retrieved fact to its source. - **Hybrid retrieval** — Keyword and vector search run together and fused with Reciprocal Rank Fusion, so records strong in either or both rise to the top. Community. - **Graph, vector and keyword in one query** — Records semantically about a topic, connected in the graph to a given entity, and mentioning an exact term — structure, meaning and keywords reasoned over together. - **Provenance on every answer** — Every retrieved fact traces back to its sources and forward to what was derived from it, so you can show which facts drove an answer. Enterprise. - **Vector-from-text search** — Plain text in, ranked records out, embedded with the same model used on your data. Community. - **Exact-term precision** — BM25 matches names, codes and exact phrases alongside semantic matching, with snippets and highlighting. Community. **Customer 360 and identity resolution** Items: - **The problem** — Customer data is scattered across systems, the same person appears many times, and the links between accounts, devices and addresses are invisible. Tessera models them as one graph and resolves duplicates with similarity and link prediction. - **Unified entity graph** — People, accounts, devices, addresses and interactions in one graph over one copy, queried by connection, by table or by meaning. - **Duplicate resolution** — Jaccard and cosine similarity over neighbourhoods find entities that connect to many of the same things — the basis for merging scattered records. Enterprise. - **Hidden connections** — Structural link prediction (Common Neighbours, Adamic-Adar, Katz) surfaces likely links between accounts, devices and addresses, with no training. Enterprise. - **Hyperedge interactions** — ‘This account, on this device, at this address’ stored as one fact with named roles, not flattened into separate rows. - **Three ways to query** — Cypher for a traversal, SQL for a report, TQL for a temporal question — all over the same unified view. **Regulatory, audit and forensics** Items: - **The problem** — Regulators ask what you knew and when. Reconstructing a past state across mutable, disconnected stores — and proving nobody changed the record — is painful. Tessera reconstructs any past moment, shows the record is intact, and traces every fact to its origin. - **Bitemporal time-travel** — ‘What was true on 1 March?’ and ‘what did the database believe then?’, both answered from valid time and transaction time. Community. - **Tamper-evident audit chain** — An append-only, hash-chained record in which altering, deleting or reordering any entry is detected on verification. Enterprise. - **Lineage and provenance** — Any record traced back to its sources and forward to what it affected, with root sources and a hop-stratified provenance graph. Enterprise. - **Investigation branching** — Branch a past state, investigate in isolation, and keep every change out of production data. Community. - **Point-in-time recovery** — Replay the write-ahead log to just before a bad event, with every file checked against the manifest's checksums. Enterprise. **Knowledge graphs for search and reasoning** Items: - **The problem** — Enterprise knowledge sits in silos; keyword search misses meaning, and vector search misses structure and exactness. Tessera holds entities, relationships, text and embeddings in one engine, so a query reasons over all of them. - **Entities, relationships and text together** — One engine and one copy for entities, relationships, text and embeddings, instead of separate stores stitched together. - **Hyperedge-native facts** — A typed fact links any number of entities in named roles, with no invented intermediate nodes. Community. - **Semantic plus keyword reasoning** — Semantic similarity for meaning and BM25 for exact terms, fused with graph relationships, so answers reflect structure as well as similarity. - **Schema-on-write modelling** — Types register on first use and property types are inferred, so you start writing at once and evolve the schema as you learn. Community. - **Three query languages** — Cypher, TQL and SQL over the same knowledge graph, mixed freely across an application. Community. **Recommendations and link prediction** Items: - **The problem** — Who should connect, what they should buy, which accounts will transact — questions that need graph structure and learned patterns, usually from a graph database plus a separate ML stack. Tessera runs both in-database over the live graph. - **Structural link prediction** — Common Neighbours, Jaccard, Adamic-Adar, Preferential Attachment and Katz give instant suggestions from graph shape, with no training. Enterprise. - **Trained link-prediction models** — Logistic regression, random forest or gradient boosting trained on real edges and negative samples, reported with AUC-ROC. Enterprise. - **Similarity-based suggestions** — Nodes scored as alike by the company they keep — ‘these two connect to many of the same things’. Enterprise. - **Graph embeddings** — FastRP and Node2Vec turn structural position into vectors for search, clustering or downstream models. Enterprise. - **Model catalogue and evaluation** — Every trained model versioned and kept through restarts, with AUC-ROC, precision, recall and F1 to compare models and sweep thresholds. Enterprise. **Supply chain and dependency mapping** Items: - **The problem** — Supply networks are deep, many-party graphs, and ‘if this supplier fails, what breaks?’ means traversing many hops. Tessera stores many-party facts as hyperedges and uses graph algorithms to find critical nodes, routes and cascading-failure exposure. - **Many-party facts as hyperedges** — A step linking a product, handler, location and certifications is one hyperedge, not an invented middle node. Community. - **Cascading-failure exposure** — Independent Cascade and Linear Threshold diffusion show what breaks downstream when a supplier or route fails. Enterprise. - **Critical-node analysis** — PageRank, betweenness and closeness find the suppliers, routes and assets that hold the network together, and the bottlenecks. Enterprise. - **Path and reachability mapping** — Dijkstra, BFS, A* and Yen's k-shortest paths trace how exposure and value move from A to B. Enterprise. - **Source-to-delivery provenance** — Any product traced back to its origins and forward through every step it touched. Enterprise. **On-premise and air-gapped AI** Items: - **The problem** — The modern AI and vector stack is cloud-native, but regulated data in banking, healthcare, government and defence often cannot leave the building. Tessera ships the hybrid and ML stack as one binary that runs entirely on your hardware, with no cloud call-home. - **Single self-contained binary** — One native executable — no JVM, no separate install — that starts in seconds on your own hardware. Community. - **No cloud call-home** — Nothing phones home: the five-dimension engine, hybrid retrieval and in-database ML all run air-gapped. - **In-database ML, no export** — Classification, GNN, link prediction, GAN synthetic data and online learning train and serve inside the database, so sensitive data never leaves for a separate ML system. Enterprise. - **Encryption at rest** — Opt-in AES-256-GCM over the audit log and storage layers, enabled without a data migration; a stolen disk or leaked backup yields only ciphertext. Enterprise. - **Governance built in** — RBAC on every request, OIDC and SAML single sign-on against your identity provider, the tamper-evident audit chain and fail-closed licensing. SSO and the audit chain are Enterprise. **Time-series monitoring and anomaly detection** Items: - **The problem** — Metrics and events usually live in a separate time-series database, cut off from the entities they describe. Tessera's native time-series is analysed against the same graph and tables the metrics belong to. - **Native time-series operations** — Bucketing, gap-filling, downsampling and anomaly detection over compressed storage, with no separate time-series database. Community. - **Metrics beside their entities** — Because every fact is bitemporal, readings are analysed against the graph and tables they belong to — trends in context, not in a disconnected metrics store. - **Anomaly detection** — Anomalies found in the series itself, surfacing next to the entities and relationships that produced them. - **Behavioural risk over time** — Per-account anomaly scoring learns each entity's normal and flags deviations in amounts, velocity and counterparties as activity streams in. Enterprise. - **Continuous monitoring and alerts** — Risk scores, pattern matches and alerts as data flows, with on-demand scans and alert acknowledgement. Enterprise. **Master data management** Items: - **The problem** — A single trusted view of core entities, with history and provenance, is hard to keep across systems. A content-addressed, bitemporal store with lineage gives a golden record that carries its own history and sources. - **Golden record with history** — One trusted view of each core entity that carries its own history and sources, not a snapshot reassembled across systems. - **Content-addressed integrity** — Every fact keyed by the BLAKE3 hash of its content, so the same fact is never stored twice and integrity can be checked. Community. - **Full history on every entity** — Valid time and transaction time reconstruct what a master record was, and what the system believed, at any past moment. Community. - **Provenance for every field** — Lineage traces each record to its sources and forward to what was derived from it. Enterprise. - **One source, three languages** — Cypher, TQL and SQL read the same master data, so traversals, temporal questions and BI reports agree. Community. **Patterns, sector by sector.** Items: - **Banking · cross-border fraud rings** — Model each transaction as a hyperedge so correspondents and intermediaries stay in the record, and use valid and transaction time to answer what an analyst saw at approval — one query in place of a chase across a warehouse, a graph and a search index. - **Pharma · clinical-trial provenance** — Store a measurement as one fact with all its participants — patient, site, device, SOP version — so provenance is the record itself rather than a trail kept in sync beside it, and bitemporal queries show which SOP applied when it was taken. - **Logistics · parcel event sourcing** — Write one hyperedge per parcel event — parcel, hub, driver, previous event — so status is a short traversal instead of a join across systems, with valid time absorbing scanners that replay events out of order. - **Capital markets · surveillance** — Connect accounts that share traders, securities or strategies through their orders, and let community detection surface tight clusters that fixed rules never encoded — once the modularity threshold and filters are tuned. - **AI platforms · agent memory** — Keep one hyperedge per memory — agent, user, session, entities — so semantic, keyword and graph recall come from one write, retire stale memories by validity rather than deletion, and record each fact's source and confidence. - **Healthcare · patient timelines** — Merge records from many systems at insert time by content-addressed identity, and keep valid time apart from each system's transaction time to reconstruct what a chart showed at the moment of a decision. #### Architecture — Five layers, one binary, one copy of the data. https://tesseradb.par2labs.com/architecture From the request to the disk: interfaces, a query engine that detects the language, a graph engine, the indexes that make up the five dimensions, and content-addressed, bitemporal storage. Every layer is purpose-built — no wrappers, no adapters. **How it is put together.** **One hyperedge, five lenses.** Items: - **Relational** — Properties are a typed map on the record (BTreeMap), which SQL reads as rows and columns. - **Graph** — Endpoints are the record's list of entity references (Vec), which Cypher and TQL traverse. - **Vector** — An embedding is just another property value (PropertyValue::Vector), indexed by HNSW. - **Full-text** — Text properties (PropertyValue::Text) feed a BM25 inverted index as they are written. - **Time-series** — Valid-time and transaction-time intervals let any set of facts be read as an ordered series and aggregated in place. - **Identity** — The record's identity is the BLAKE3 hash of its content, so identical facts collapse into one and lineage has something stable to point at. **The specification.** #### Pricing — One binary, every tier. https://tesseradb.par2labs.com/pricing You run Tessera on your own hardware. Community is free and needs no key; a signed, time-limited licence key unlocks Enterprise for the term you buy, on the same binary. Nothing phones home. **What it costs.** **Four ways to run it.** Items: - **OSS source** — The foundational engine, Apache 2.0 on GitHub. Free to read, fork and compile yourself. - **Community** — A free downloadable binary for a single node: the full core engine and the admin UI. - **Enterprise** — The same binary with a licence key, unlocking graph data science, ML, AutoGuard, SSO and governance. - **Enterprise Plus** — Everything in Enterprise, plus the banking pack — BIAN, FIBO, fraud patterns, AML and sanctions screening. **Core engine** | Feature | OSS source | Community | Enterprise | Enterprise Plus | | --- | --- | --- | --- | --- | | Hyperedge data model | Yes | Yes | Yes | Yes | | TQL parser | Yes | Yes | Yes | Yes | | Cypher parser and executor | Yes | Yes | Yes | Yes | | SQL parser | Yes | Yes | Yes | Yes | | 60+ graph algorithms | — | — | Yes | Yes | | HNSW vector search | Yes | Yes | Yes | Yes | | BM25 full-text search | Yes | Yes | Yes | Yes | | B-tree range indexes | Yes | Yes | Yes | Yes | | Content-addressed storage (BLAKE3) | Yes | Yes | Yes | Yes | | Integrated engine, WAL and MVCC | — | Yes | Yes | Yes | | Bitemporal storage and queries | — | Yes | Yes | Yes | | Git-style branching | — | Yes | Yes | Yes | | ACID transactions | — | Yes | Yes | Yes | | CLI REPL and admin UI | — | Yes | Yes | Yes | **AI and security** | Feature | OSS source | Community | Enterprise | Enterprise Plus | | --- | --- | --- | --- | --- | | 8-layer AutoGuard defence | — | — | Yes | Yes | | AutoGuard compliance monitoring | — | — | Yes | Yes | | Injection detection (query firewall) | — | — | Yes | Yes | | Red-team simulation suite | — | — | Yes | Yes | | Anomaly scoring | — | — | Yes | Yes | | In-database ML (GNN, GAN, link prediction) | — | — | Yes | Yes | | GraphRAG retrieval (vector + text + graph fusion) | — | — | Yes | Yes | | Tamper-evident BLAKE3 audit chain | — | — | Yes | Yes | | Monitoring and alerts | — | — | Yes | Yes | **Compliance and governance** | Feature | OSS source | Community | Enterprise | Enterprise Plus | | --- | --- | --- | --- | --- | | Encryption at rest (AES-256-GCM) | — | — | Yes | Yes | | Data lineage | — | — | Yes | Yes | | Synthetic data generator | — | — | Yes | Yes | | Regulatory classification (FIBO + BIAN) | — | — | — | Yes | | Fraud-pattern engine (structuring, velocity, mule) | — | — | — | Yes | | Sanctions screening (against lists you provide) | — | — | — | Yes | | AML alerts | — | — | — | Yes | **Infrastructure** | Feature | OSS source | Community | Enterprise | Enterprise Plus | | --- | --- | --- | --- | --- | | Single-node deployment | — | Yes | Yes | Yes | | Multi-node building blocks (Raft consensus) | — | — | Yes | Yes | | API key and RBAC authentication | — | Yes | Yes | Yes | | OIDC and SAML 2.0 SSO | — | — | Yes | Yes | | PostgreSQL and REST connectors | — | — | Yes | Yes | | MySQL, MongoDB, S3 and Kafka connectors (roadmap) | — | — | — | — | | On-premise deployment support | — | — | — | Yes | | Backup, restore and point-in-time recovery | — | — | Yes | Yes | | Production observability and SLO monitoring | — | — | — | Partial | **Support and delivery** | Feature | OSS source | Community | Enterprise | Enterprise Plus | | --- | --- | --- | --- | --- | | Source code (Apache 2.0, GitHub) | Yes | — | — | — | | Downloadable binary | — | Yes | Yes | Yes | | Community support (GitHub issues) | Yes | Yes | Yes | Yes | | Priority support (24-hour SLA) | — | — | Yes | Yes | | Dedicated solutions architect | — | — | — | Yes | | Custom SLA (4-hour response) | — | — | — | Yes | | Training and onboarding | — | — | — | Yes | *Yes: included at that tier. Partial: under way at that tier but not complete. Roadmap items are not shipped at any tier.* **Questions we actually get.** Items: - **How does licensing work?** — You run the single Tessera binary on your own hardware. Community is free, needs no key and does not expire. For Enterprise you buy a term of 6 or 12 months and receive a signed, time-limited key; enter it and the Enterprise features unlock for that period. The binary starts in seconds, backing up one data folder preserves the whole database, and nothing phones home. - **What happens when my licence key expires?** — It fails closed. The binary falls back to Community: it keeps running, your data stays where it is, and only the Enterprise features lock until you enter a new key. A missing, expired, malformed or wrongly signed key never unlocks anything, never breaks the database and never loses data. - **Can I buy 6 or 12 months?** — Both. A 12-month Enterprise key is $18,000 per node; a 6-month key is $10,900 per node. Buy the term that fits the project and renew when you like. Enterprise Plus is priced to your term and node count — talk to us. - **What counts as a node, and are there volume discounts?** — Each running instance of the Tessera server is one node. Only production nodes are licensed; development and staging instances are free. Volume discounts apply if you run several — ask for a quote. - **Is there a trial before I buy?** — Yes. We issue a full-featured, time-boxed evaluation key, so you can run the whole Enterprise feature set on your own hardware before committing — no credit card and no hosting to set up. - **What tiers are available?** — Three, all from one binary. Community (free) has the five-dimension engine, all three query languages, hybrid retrieval, ACID transactions, branching, bitemporal time-travel, bulk import, the admin dashboard, SDKs and observability. Enterprise adds the 60+ graph algorithms, in-database ML, AutoGuard, lineage, OIDC and SAML single sign-on, encryption at rest, backup with point-in-time recovery, and monitoring. Enterprise Plus adds the fraud, AML, sanctions-screening and regulatory-classification pack. - **Can Tessera run on-premise or air-gapped?** — That is the only way it runs; there is no cloud service to depend on. Tessera is a single self-contained binary — no JVM, no separate install — that starts in seconds and runs entirely on your hardware with no call-home, so regulated data stays where it has to. Enterprise Plus adds deployment support for those environments. - **What is Tessera DB?** — A multi-model database built for AI workloads. It stores your data once and lets you query it five ways — by connections (graph), by meaning (vector), by keywords (full-text), by tables (SQL) and over time (time-series) — and can fuse them in one query. It adds in-database machine learning, bitemporal time-travel, Git-style branching, data lineage and a tamper-evident audit trail, and ships as one binary that runs on your own hardware. - **What does “five dimensions” mean?** — Relational, graph, vector, full-text and time-series: five ways of indexing and querying the same copy of your data. Instead of moving data between a graph database, a vector store, a search engine, a SQL store and a time-series database, Tessera indexes it all five ways at once, and a single query can combine whichever dimensions the question needs. - **What can Tessera replace?** — For an AI or fraud application: a separate graph database, vector database, search engine, SQL store and time-series database, and the ETL that keeps them in sync. It also adds in-database ML, data lineage and a tamper-evident audit log, which those products do not provide. - **Is Tessera open source?** — The foundational engine is open source under Apache 2.0, which permits commercial use, modification and distribution with no copyleft obligations, and there is a free Community binary. Enterprise and Enterprise Plus features are unlocked by a signed licence key on the same binary; there is no separate build per tier. - **What query languages does Tessera support?** — Three, over one dataset: Cypher for graph pattern matching; TQL, Tessera's native language, built around its hyperedge model; and SQL for tables, joins, aggregation and the BI tools you already use. Mix them freely — Cypher for a traversal, SQL for a report, TQL for a temporal question. Cypher support covers the common, widely used subset, so check any advanced or unusual Cypher features before migrating. - **How does Tessera compare to Neo4j?** — Neo4j is a mature, graph-only database with the biggest ecosystem and proven large-scale clustering. Tessera is younger and multi-model — graph, vector, full-text, SQL and in-database ML in one binary — aimed at AI retrieval and at fraud and compliance work. Neo4j is clearly ahead on clustering, high availability and replication, on ecosystem, on maturity and tooling, and on very large graphs. Tessera is ahead on consolidating several systems into one, on in-database ML including graph neural networks, and on native bitemporal history, branching and lineage. Many teams use both. - **What is AutoGuard?** — An eight-layer AI-security stack (Enterprise) that runs inside the database, so protection travels with the data rather than living in a bolt-on gateway: injection detection that can block in real time, behavioural anomaly scoring against each account's own normal, canary records that reveal probing, adaptive defences that tighten as suspicious activity rises, behavioural biometrics, automatic security-posture escalation, meta-detection of attempts to probe the detectors, and an ensemble layer that acts on the combined signal. Every action is written to the tamper-evident audit log. - **How is this better than a vector-only RAG stack?** — Vector-only RAG matches by similarity alone, with no relationships, no exact-term precision and no record of which facts an answer used. Tessera fuses graph relationships, semantic similarity and keyword retrieval in one query, and every retrieved fact can be traced to its source through lineage, so the system can show its working. - **How does Tessera help with audit and compliance?** — The hash-chained audit log makes any change to a past entry detectable on verification; bitemporal time-travel reconstructs both reality and what the database knew at any past moment; lineage traces every fact to its origin; and role-based access control is enforced on every request before the handler runs. Enterprise Plus adds AML typology alerts, sanctions screening against the lists you provide, and regulatory classification against FIBO and BIAN. - **Does Tessera screen against sanctions lists?** — It provides the screening engine (Enterprise Plus) — name normalisation, alias checks and fuzzy matching, returning matches with confidence scores and a blocking signal — and you load the lists you are required to screen against. There is no built-in list fetcher and no bundled government data. - **Is my data encrypted at rest?** — It can be (Enterprise): optional, layer-by-layer AES-256-GCM, which gives both confidentiality and tamper detection, across the audit log and storage layers under one key. The reader detects encrypted and plaintext data, so it can be switched on without a migration, and a stolen disk or leaked backup yields only ciphertext. - **What is a hyperedge?** — A relationship that connects any number of entities, each in a named role, rather than just two. ‘Bank paid Vendor via Account’ — or five accounts in one transaction — is one hyperedge, not an invented middle node, so real-world facts are modelled as they are. - **What is content addressing?** — Every fact is identified by a BLAKE3 hash of its own content. Identical data always gets the same identity, so deduplication, integrity checks and lineage follow, and there are no auto-increment IDs to manage. - **What is bitemporal data?** — Every fact carries two times. Valid time is when it was true in the real world; transaction time is when the database learned it. Together they answer both ‘what was true on 1 March?’ and ‘what did the database believe at that moment?’ — the basis of audit, forensics and reconstructing any past state. - **Does Tessera support machine learning?** — Yes, in-database and in the Enterprise tier, trained where the data already lives with no export pipeline: node classification (a linear baseline and a message-passing graph neural network), link prediction, GAN synthetic data, online learning, standard evaluation metrics and a versioned model catalogue that survives restarts. Predictions are backed by lineage and the audit chain. Accuracy depends on your data; meaningful results need real, sufficiently large datasets. - **Does Tessera support ACID transactions?** — Yes. Group writes so they all succeed or all fail, with isolation up to serializable. Conflicting transactions are detected and rejected, so the data stays consistent. - **How does branching work?** — Fork the whole dataset the way Git forks code, change it in isolation, and query either branch without changes leaking across — for what-if analysis, an isolated investigation, a staged bulk change or a pipeline test, all without touching production data. - **Can I use my existing Postgres and BI tools?** — Yes. Tessera speaks the PostgreSQL wire protocol, so psql, Postgres drivers and tools such as Tableau, Metabase, DBeaver and Grafana connect and run SQL against it as if it were Postgres. There is also a pure-Java JDBC driver and official Python, Rust and TypeScript SDKs. - **Does Tessera scale across many nodes for high availability?** — It is strongest on a single well-provisioned node, and ships building blocks for multi-node operation, including a Raft consensus module for leader election and log replication. For proven, large-scale clustered HA and failover today, a mature system such as Neo4j is further ahead — and we would rather say so. #### Docs — The reference, behind a passphrase. https://tesseradb.par2labs.com/docs The Tessera DB reference documentation is access-controlled. Enter the passphrase if you have one, or request access by email at ceo@par2labs.com. The tutorials and writing below are open to everyone. **Tutorials and writing.** Product: tessera-db ## Articles ### Why We Built a Hyperedge-Native Database from Scratch https://tesseradb.par2labs.com/articles/why-we-built-a-hyperedge-native-database Technology · 2026-08-29 · 2 min read · PAR2 Labs Every property graph database we evaluated forced us to model a four-party financial transfer as four separate edges plus a synthetic intermediary node. That's not a graph; that's a record nobody can audit cleanly. Tessera was born out of refusing to keep translating the world's data into a model the world doesn't have. #### The shape of the problem Consider a wire transfer. A real one. It has a sender, a receiver, a correspondent bank, an ultimate beneficiary, an amount, a currency, a transaction reference, a value date, and a confidence level (because some fields arrive incomplete and reconciliation runs later). That's one fact about the world. One. In a property graph you model it as: a Transfer node with properties, plus four relationship edges connecting it to each party. To answer “who was the beneficiary of transfer X” you traverse (:Transfer)-[:BENEFICIARY]->(:Party). Fine. Now answer “list every transfer where the sender's correspondent bank is also the beneficiary's correspondent bank.” Suddenly you're writing five-line Cypher patterns with multiple sub-traversals because the binary-edge model can't express the relationship as a single thing. #### What hyperedges actually are A hyperedge is a relationship that connects any number of endpoints, each labelled with a role. To model that same transfer in a binary-edge graph, you're forced to invent a middle node and hang four edges off it: ```cypher // Binary-edge graphs force a reified middle node: CREATE (t:Transfer {amount: 250000, currency: 'USD'}) CREATE (t)-[:SENDER]->(:Party {id: 'alice'}) CREATE (t)-[:RECEIVER]->(:Party {id: 'bob'}) CREATE (t)-[:INTERMEDIARY]->(:Party {id: 'corr-bank'}) CREATE (t)-[:BENEFICIARY]->(:Party {id: 'ultimate'}) ``` In Tessera, that transfer is a single hyperedge: one typed fact that links all four parties by named role — sender, receiver, intermediary, ultimate beneficiary — and carries its own properties, confidence, and valid-time. Named roles, real properties, real confidence, real time. The thing the world has, modelled as the thing it is. > We rejected them because we kept building the same translation layer on top of them, and that translation layer was where the bugs lived. #### Why this was the right bet Three things become trivial that were not before: - N-ary queries. “Find transfers where sender and beneficiary share an intermediary” is one pattern, not five. - Identity over time. The same transfer, observed twice with corrected information, deduplicates to the same content-addressed hash. No reconciliation pipeline. - Provenance. Hyperedges carry confidence and bitemporal stamps, so the audit trail isn't a parallel system — it's the data. We didn't reject property graphs because they were old. We rejected them because we kept building the same translation layer on top of them, and that translation layer was where the bugs lived. #### What it cost us Honest answer: most engineers think in binary edges. Cypher developers had to relearn patterns. We invested heavily in a Cypher-to-hyperedge translator so existing skills port, but the mental shift is real. The first month is a small tax. After that, your queries are shorter and your audit logs make sense. #### What this unlocked downstream Because every fact is a single hyperedge with explicit endpoints, content-addressed identity, bitemporal stamps, and confidence — the rest of the system gets simpler. SQL queries read properties off hyperedges. Time-series views project the timestamps. Vector search embeds text properties. Graph algorithms traverse endpoints. Nothing is duplicated, nothing drifts. One model, five access patterns. That's the bet. Six months in, we'd take it again. **Key takeaways** - A property graph turns a many-party fact into a synthetic middle node with one binary edge per party. - A hyperedge links any number of endpoints by named role and carries its own properties, confidence and valid-time. - N-ary queries, identity over time and provenance become single patterns instead of a translation layer. - The cost is a mental shift for engineers used to binary edges, eased by a Cypher-to-hyperedge translator. ### Five Databases Are Four Too Many https://tesseradb.par2labs.com/articles/five-databases-too-many Technology · 2026-08-29 · 3 min read · PAR2 Labs The job of an infrastructure engineer at most companies has quietly become: keeping five databases in sync so the rest of the company can pretend they're one. We did the maths on what that costs. #### The stack you didn't ask for An AI-driven product needs to do five things with its data: - Run relational queries — joins, aggregates, range filters. - Traverse relationships — who is connected to whom, multi-hop neighbourhoods. - Search by semantic similarity — vector embeddings. - Search by keyword — BM25 over text. - Query over time — historical state, retention, point-in-time recovery. No single database does all five. So the stack assembles itself: Postgres + Neo4j + Pinecone + Elasticsearch + TimescaleDB. Five engines, five operational surfaces, five scaling characteristics, five billing dashboards. #### The hidden tax The sync layer between these systems is almost always custom. CDC from Postgres into Neo4j. Periodic export from Postgres into Pinecone. Logstash from somewhere into Elasticsearch. Cron job into TimescaleDB. Every one of those pipelines has the same failure mode: it works for six months, then a schema migration breaks it silently, and you discover three weeks later that your vector store is missing a quarter of your documents. The “tax” isn't infrastructure cost — it's the lost engineering time spent reconciling systems that should have been one. The strongest argument for a multi-database stack is “best of breed for each access pattern.” The actual experience is “worst of all worlds when any of them drifts.” > The “tax” isn't infrastructure cost — it's the lost engineering time spent reconciling systems that should have been one. #### What consolidation actually looks like Tessera's bet: the access patterns aren't fundamentally different. They're different views over the same data. A hyperedge has properties (relational), endpoints (graph), text fields that can be embedded (vector), text fields that can be tokenised (BM25), and bitemporal timestamps (time-series). One write, five indexes, zero sync. One write, five indexes, zero sync. The same records answer a relational question in SQL: ```sql SELECT * FROM transfers WHERE amount > 100000; ``` …a relationship question in Cypher, over the very same data: ```cypher MATCH (a)-[:SENDS]->(b) RETURN a, b ``` …and, without any export or copy, the same rows are reachable by semantic (vector) similarity, by BM25 keyword search, and as a bitemporal time-series. No pipeline moves anything between stores, because there are no other stores. #### When five databases still make sense We're not arguing every team should rip out their stack tomorrow. Five-database architectures make sense when: - You've already invested in deep expertise across each system. - Your scale per-dimension is so large that a unified store wouldn't fit anyway. - Your access patterns are independent — your relational team and your vector team literally never share data. For everyone else — which is most teams — the integration cost dominates. The point of a unified hyperedge store isn't that the engine is magic; it's that the four pipelines you used to maintain simply stop existing, and with them the drift, the reconciliation, and the on-call pages they generated. #### What the migration looks like in practice Honest answer: incremental. Pick the one pipeline that's caused the most pain in the last quarter, replace it first, keep the rest. Tessera's Postgres connector exists specifically so you can start by mirroring an existing source-of-truth without committing to anything else. Once your team has confidence, retire the next pipeline. You don't need to be brave. You need to delete one pipeline a quarter. **Key takeaways** - Relational, graph, vector, keyword and time-series needs usually assemble into five separate engines. - The real tax is the custom sync pipelines between them, which break silently when a schema changes. - In Tessera the five access patterns are views over the same hyperedges: one write, five indexes, zero sync. - Migrate incrementally — replace the most painful pipeline first, then retire one a quarter. ### The Case Against Vector Store Sprawl in AI Applications https://tesseradb.par2labs.com/articles/case-against-vector-sprawl Technology · 2026-08-29 · 2 min read · PAR2 Labs Every team building on LLMs in 2026 has a vector store. Most of them have two. Few of them are happy with the results. The problem isn't the choice of vector database — it's the assumption that semantic similarity alone is enough. #### What pure vector retrieval gets right Vector similarity is genuinely useful. “Documents similar in meaning to this query” is a powerful primitive. It handles synonyms, paraphrases, and cross-lingual matches in ways that keyword search never will. #### What it gets wrong It's stateless. A vector store treats every embedded chunk as if it exists in isolation. The fact that two chunks come from the same document, share an author, or sit five edges away in a knowledge graph is information the vector store doesn't have and can't use. Concretely: a query for “Q3 fraud incidents involving the Helsinki branch” might score highly against a Q2 fraud report from a different branch (because the embeddings are dominated by “fraud incident”) and miss the actual Helsinki-Q3 report if its embedding happened to land in a slightly different cluster. #### Three signals, one retrieval GraphRAG fuses three independent signals through Reciprocal Rank Fusion: - Vector similarity — HNSW nearest neighbour over embeddings. Catches semantic intent. - Text relevance — BM25 over the same documents. Catches keyword anchors like “Helsinki” and “Q3”. - Graph proximity — adjacency traversal from retrieved nodes. Catches contextual neighbours the embedding ignored. A single hybrid query runs all three and fuses the rankings, so “Helsinki” and “Q3” anchor the result while the embedding supplies the semantic intent and the graph pulls in the connected facts. In Tessera these three signals index the same records — there's no separate vector store, search cluster, or graph database to keep aligned. > Each signal has failure modes the other two compensate for. #### Why fusion beats picking one Each signal has failure modes the other two compensate for. Vector misses exact anchors. BM25 misses synonyms. Graph misses items that aren't connected to a seed node. RRF combines them so that an item ranked highly by two of the three gets promoted above an item ranked highly by only one — even if that one ranking is very confident. The right question isn't “which retrieval algorithm is best.” It's “which combination of signals correctly disambiguates the queries my users actually ask.” #### When pure vector is enough If your corpus is genuinely unstructured — a pile of independent product reviews, say — there are no graph edges to traverse and BM25 buys you marginal recall. Pure vector is fine. The moment your documents have authors, citations, versions, parents, or any kind of relationship — which is true of most enterprise corpora — fusion wins. #### The cost Three indexes instead of one. In Tessera that's an implementation detail — the same hyperedge feeds all three, and there's no separate vector store to keep in sync. Outside Tessera, you're now operating two more systems, and we're back to the sprawl we wrote about in “Five Databases Are Four Too Many”. Pick your poison. **Key takeaways** - Vector similarity handles synonyms and paraphrase, but treats every chunk as if it existed in isolation. - GraphRAG fuses vector similarity, BM25 text relevance and graph proximity through Reciprocal Rank Fusion. - Each signal covers the others' failure modes, so an item ranked highly by two of the three is promoted. - Pure vector is fine for genuinely unstructured corpora; once documents have relationships, fusion wins. ### Bitemporal Data Isn't Optional for Regulated Workloads https://tesseradb.par2labs.com/articles/bitemporal-not-optional Technology · 2026-08-29 · 2 min read · PAR2 Labs A bank examiner walks into a meeting and asks: what was Customer X's risk rating on the morning of March 18th — and what did the system display to the relationship manager who approved their loan on that same morning? Those are two different questions. If your database can only answer one, you have a compliance problem. #### Valid time vs. transaction time Every fact has two timestamps that matter: - Valid time — when the fact is true in the real world. A customer's address is valid from the day they moved in to the day they moved out. - Transaction time — when the fact was recorded in your system. The customer might have moved on the 5th but reported it on the 12th. The fact is valid from the 5th but recorded from the 12th. These two clocks diverge constantly. Backdated trades. Retrospective corrections. Late-arriving sensor data. Insurance claims that reference an incident from last year. A single-clock model — “this is the current value” — loses the entire history of when you knew what. #### Why regulators care Almost every modern compliance regime — Basel III, GDPR, EU AI Act, BCBS 239 — explicitly requires demonstrable reconstruction of past system state. Not “what is true now” but “what did the system show when this decision was made.” With a single-clock database, the only way to answer this is to keep a parallel audit log and hope it stayed consistent. With bitemporal storage, the answer is just a query: ask for the state as it stood — in the real world, or as the system knew it — at 09:30 on the morning of March 18th, and read the risk rating straight off the result. > Bitemporal storage is what you build so you don't need the audit log. #### How Tessera does it Every fact carries both a valid-time interval (when it was true in the world) and a transaction-time interval (when the database learned it). The engine indexes both, so a query can filter on either or both, and ask three distinct kinds of “give me history”: what was true as of a moment, what the database believed as of a moment, and what was valid across a range. The historical reconstruction isn't a separate audit log — it's the same data the application reads every day. Audit logs are what you build when your database can't answer time-travel questions. Bitemporal storage is what you build so you don't need the audit log. #### The hidden cost of not doing this Most teams discover they need bitemporal data the hard way — when a regulator requests a reconstruction and they spend three weeks gluing together event logs, backup snapshots, and audit tables to produce something approximate. The cost is real; it just gets amortised across many small panics instead of one architectural decision. #### When you don't need it Honest answer: most consumer-facing workloads don't. If you're building a chat app, bitemporal is overkill. If you're building anything where someone might ever ask “what did the system think on date X” — claims processing, lending decisions, risk-rated trading, medical records, journalism, scientific data — start with bitemporal. It's much cheaper than retrofitting. **Key takeaways** - Valid time is when a fact was true in the world; transaction time is when the system recorded it. - Regimes such as Basel III, GDPR, the EU AI Act and BCBS 239 require reconstruction of past system state. - Tessera indexes both intervals, so history is an ordinary query rather than a parallel audit log. - Most consumer apps do not need it; anything where someone may ask what the system thought on a date should start bitemporal. ### TQL Was Designed for LLMs to Write — Here's How It Works https://tesseradb.par2labs.com/articles/tql-designed-for-llms-to-write Technology · 2026-08-29 · 2 min read · PAR2 Labs SQL is the most-generated text on Earth that nobody writes for fun. Cypher is denser but punishingly syntactic. Both predate LLM authoring by decades, and it shows in how often agents botch them. TQL is what we built when we got tired of debugging models' bad joins. #### What goes wrong when LLMs write SQL The failure modes are predictable: implicit Cartesian products from missed join conditions, ambiguous column references after multi-table joins, NULL semantics that models reason about incorrectly, and quoting rules that vary by dialect. Each one looks like a one-off bug; collectively they make agent-generated SQL unreliable past a few joins. #### What TQL changes TQL is declarative without being relational. Queries name what you want by type, not by table. There are no joins because the data model doesn't have foreign keys to chase — the participants in a fact are endpoints on the hyperedge, each identified by its role. And temporal, branch, and confidence context are first-class, so “high confidence, valid in the last 90 days” is a filter you attach, not a subquery you assemble. The effect is that no clause depends on column-resolution order and there are no JOIN ON conditions to forget. That's the property that makes a language easy for a model to get right on the first try: fewer places where a plausible-looking query is silently wrong. > Languages that constrain the model towards right answers — not languages that maximally expose database internals — are what the next decade calls for. #### Why this matters now The job of an enterprise database in 2026 is to be queryable correctly by a non-deterministic process. The cost of an off-by-one in an LLM-generated WHERE clause shows up in regulator reports. Languages that constrain the model towards right answers — not languages that maximally expose database internals — are what the next decade calls for. SQL was designed for humans to write rarely. TQL was designed for agents to write constantly. Same problem space, very different design constraints. #### Compatibility Tessera also accepts Cypher and SQL over the same data, so existing skills port and you're never locked into one language. But measure your agent's success rate across all three on the queries your application actually generates. We did, and TQL won by a margin that decided the project. **Key takeaways** - LLM-written SQL fails in predictable ways: missed join conditions, ambiguous columns, NULL semantics and dialect quoting. - TQL names data by type rather than table and has no joins, because a fact's participants are role-labelled endpoints. - Temporal, branch and confidence context are filters you attach, not subqueries you assemble. - Tessera also accepts Cypher and SQL over the same data, so existing skills port. ### Content-Addressed Identity Ends the Integer-ID Drama https://tesseradb.par2labs.com/articles/content-addressed-identity Technology · 2026-08-29 · 1 min read · PAR2 Labs We've never met a senior data engineer who loves auto-incrementing IDs. We've met many who tolerate them. The unspoken truth is that the moment a record exists in two systems, integer IDs become a category of bug that compounds forever. #### What “content-addressed” means in practice Every fact in Tessera has an ID derived from its content with a BLAKE3 cryptographic hash. Identical inputs produce identical IDs — across machines, across time, across rebuild cycles. The ID isn't assigned. It's computed. #### Three things this kills - Duplicate detection becomes free. Re-ingest a fact you already have? Same content → same ID → the existing record. No upsert dance, no LEFT JOIN on natural keys. - Cross-system references become natural. When system A and system B both compute the ID from the canonical content, they're talking about the same row without coordination. - Tamper detection becomes a property of the data. Change the content, the ID changes. Audit trails self-verify. > Identical inputs produce identical IDs — across machines, across time, across rebuild cycles. #### The tradeoff worth flagging Content-addressed IDs are deterministic, not sequential. You can't ORDER BY id and expect insertion order. You can't generate a customer-facing reference like “Order #1247” from the hash. Both are fine if you stop confusing the database's identity with the application's display number. Most teams realise within a week that they were conflating those two things and never look back. Integer IDs aren't a feature. They're a 1970s implementation detail we inherited because nobody had cheap, collision-resistant hashing in the database layer. #### Why BLAKE3 Cryptographically strong, parallelisable, and fast on every architecture we care about, with a multihash-style encoding so the hash family isn't welded into downstream code. SHA-256 would have worked too; BLAKE3 was the better fit for how often we hash. **Key takeaways** - Every Tessera fact has an ID computed from its content with BLAKE3, so identical inputs give identical IDs everywhere. - Duplicate detection, cross-system references and tamper detection all follow from the ID itself. - Hash IDs are not sequential: insertion order and customer-facing numbers belong to the application, not the identity. ### Why We Kept Cypher Around https://tesseradb.par2labs.com/articles/why-we-kept-cypher Technology · 2026-08-29 · 2 min read · PAR2 Labs The cleanest design decision for Tessera would have been: one query language, the new one. Ship TQL, embrace the future, let the past catch up. We didn't do that, and the reason is boringly pragmatic. #### The audience A non-trivial fraction of teams evaluating Tessera have a Cypher codebase. Some of it is graph-database-portable. Some of it is locked to a specific vendor's extensions. None of it wants to be rewritten to evaluate a new database. Asking “would you rewrite 600 lines of Cypher to try our engine for a week” is the fastest way to lose an evaluation. Tessera supports the common, widely used subset of Cypher, so most existing queries run as written and teams that know Cypher are productive on day one. #### What the translator does and doesn't do - Does: MATCH patterns, WHERE clauses, RETURN, ORDER BY, LIMIT, SKIP, basic aggregations (count, sum, avg), variable-length paths, OPTIONAL MATCH. - Doesn't: APOC procedures, vendor-specific spatial functions, stored procedures, custom user-defined functions. These map to TQL extensions you'd write yourself if you needed them. > The translator's job is to be honest about what translates. #### The deeper point We picked the boundaries deliberately. Cypher patterns that map cleanly to hyperedge traversals are supported. Patterns that assume property-graph binary edges in ways that hyperedges don't model are surfaced as errors at parse time, not as silently-wrong results. The translator's job is to be honest about what translates. We're not pretending Tessera is Neo4j. We're saying: if you've been writing Cypher, most of your work transfers. That's enough for an evaluation. The teams that move will rewrite the parts that don't. #### One concrete example ```cypher MATCH (a:Person)-[:KNOWS]->(b:Person) WHERE a.age > 25 RETURN a.name, b.name ORDER BY a.name LIMIT 10 ``` Runs unchanged. The translator emits a TQL plan that walks the KNOWS hyperedges from Person nodes filtered by age, returns the named properties, applies the ORDER and LIMIT. No surprises. #### What we didn't do We deliberately didn't try to be a Cypher superset. That path leads to a long tail of edge-case bugs and a maintenance burden that scales with every Neo4j release. The subset that translates cleanly was the line we drew. Past that line, write TQL. **Key takeaways** - Asking a team to rewrite its Cypher just to evaluate a new database is the fastest way to lose the evaluation. - Tessera supports the common subset of Cypher, so most existing queries run as written. - APOC, vendor spatial functions, stored procedures and custom functions are out, and unsupported patterns fail at parse time rather than silently. - It is deliberately not a Cypher superset; past the subset that translates cleanly, write TQL. ### The Half-Open Interval Is a Small Choice with Big Consequences https://tesseradb.par2labs.com/articles/half-open-interval-small-choice-big-consequences Technology · 2026-08-29 · 1 min read · PAR2 Labs We've watched a team spend an afternoon debugging why a daily summary report showed slightly wrong totals at midnight. The answer turned out to be that one of their databases used closed intervals [t1, t2] and another used half-open [t1, t2). A single transaction at exactly midnight got counted twice. #### The choice Every bitemporal interval in Tessera is half-open: [start, end). A record's valid_time interval includes the start instant and excludes the end instant. If a customer's address is valid from 2024-01-01T00:00:00 to 2024-12-31T23:59:59.999, the next address's valid_time starts at 2025-01-01T00:00:00 with no overlap. #### Why half-open - No accidental double-counting. Boundaries belong to exactly one interval. - Composition is trivial. Adjacent intervals tile time without gaps or overlaps. - It matches every language's range syntax. Python's range(0, 10), Rust's 0..10, SQL's generate_series — all half-open. > The boring choices are the ones that matter most. #### The query semantics The convention holds everywhere history is queried. A point-in-time snapshot includes a record when its interval satisfies start <= t < end. A range query matches records whose interval overlaps the half-open window [s, e). And the same rule governs transaction-time queries as valid-time ones — one convention, no exceptions to remember. The boring choices are the ones that matter most. Pick a convention, document it, be consistent. We picked half-open and stopped thinking about it. Recommended. #### The one place to be careful When ingesting from a system that uses closed intervals, the boundary point of their data is the start of the next interval in our data. Most importers handle this implicitly, but if you're hand-rolling an integration, normalise on the way in. A late-night incident report is the worst time to rediscover this. **Key takeaways** - Mixing closed and half-open intervals across systems double-counts anything that lands exactly on a boundary. - Every bitemporal interval in Tessera is half-open, [start, end): the start instant is included and the end excluded. - Half-open intervals tile time without gaps or overlaps and match range syntax in Python, Rust and SQL. - When ingesting from a closed-interval system, normalise the boundary on the way in. ### Confidence Scores Belong on Every Fact https://tesseradb.par2labs.com/articles/confidence-on-every-fact Technology · 2026-08-29 · 2 min read · PAR2 Labs A bank transaction is true. An AI's classification of that transaction as “likely fraud” is true with some probability. These two things are usually stored in the same column type, with no way for downstream systems to know the difference. Tessera makes confidence a first-class property of every fact. #### The mismatch Almost every database treats data as boolean: it's there or it isn't, it's true or it's null. That made sense when humans entered everything. It stops making sense when: - An LLM extracts an entity from unstructured text — confidence 0.83. - A computer-vision pipeline labels an X-ray — confidence 0.91. - A reconciliation engine matches two records — confidence 0.67. - A KYC service approves an identity — confidence 0.95. Pretending these are crisp booleans is how you end up with downstream queries that treat a 0.67 match the same as a 0.99 match, until something breaks publicly. #### How Tessera handles it Every fact carries a confidence in the range 0.0–1.0. The default is certain (1.0) for hand-entered data; anything inferred carries the upstream model's confidence. Because confidence is a first-class part of the fact — not a property bolted on by convention — queries filter on it directly. A regulatory report can require, say, confidence at or above 0.9 and exclude every inferred row in one clause, while an operational dashboard includes the same rows without a second copy of the data. > If your data layer can't tell “the bank told us this” from “an ML model thinks this,” your data layer is lying to the people downstream of it. #### Why this is the right move - Audit queries can exclude low-confidence inferences and still find everything an examiner needs. - Operational dashboards can include them without polluting the high-stakes paths. - You don't lose information — the inferred row stays in the store with its confidence intact, available when the right downstream consumer wants it. If your data layer can't tell “the bank told us this” from “an ML model thinks this,” your data layer is lying to the people downstream of it. #### What this isn't Confidence on a fact isn't a substitute for proper model evaluation, calibration, or human review. It's a way to keep inferred and observed data in the same store without conflating them. The model still has to be good. The database stops pretending those numbers don't exist. **Key takeaways** - Inferred data is usually stored exactly like observed data, so downstream queries cannot tell a 0.67 match from a 0.99 one. - Every Tessera fact carries a confidence from 0.0 to 1.0: certain for hand-entered data, the model's score for anything inferred. - Queries filter on confidence directly, so an audit report and a dashboard can read the same rows at different thresholds. - Confidence on a fact does not replace model evaluation, calibration or human review. ### Schema-on-Write, Schema-on-Read, Schema-on-Demand https://tesseradb.par2labs.com/articles/schema-on-write-read-demand Technology · 2026-08-29 · 1 min read · PAR2 Labs The 2010s argument between schema-on-write and schema-on-read produced two camps that still hate each other. Both are correct about different problems. Tessera's answer is schema-on-write with type inference: start writing immediately, let structure register itself, and formalise it as your understanding matures. #### Start loose, by default Tessera doesn't make you declare a schema before you can insert. Types register automatically on first use, and property types are inferred from the data you actually send. You get real data in first — a whole file of it, if you like — and worry about the model afterwards, which is the order most projects genuinely discover their model in. #### Inspect what you've got “Schema-free” doesn't mean “schema-blind.” Read-only introspection lets you see exactly which types and properties exist in the store, so you can look at what a million ingested events actually contain before deciding what the canonical shape should be. That's the governance handle that loose ingestion usually lacks. > Strict-schema-from-day-one only works when you already know your data model. #### Formalise as you learn Once you know the shape, you register it — turning an inferred, ad-hoc structure into a declared one your team and your tools can rely on. Historical data keeps the shape it was written with; you're tightening the contract going forward, not rewriting the past. Schema isn't a decision you're forced to make at table-creation time and live with forever. It's something you let the data reveal, inspect, and then commit to — in that order. #### The thing nobody likes to admit Strict-schema-from-day-one only works when you already know your data model. For anything actually new, you don't. The teams that ship the cleanest production systems are the ones that started loose, learned, and tightened — not the ones that wrote a 200-table ERD before writing any code. **Key takeaways** - Tessera needs no schema up front: types register on first use and property types are inferred from the data. - Read-only introspection shows which types and properties actually exist before you settle on a canonical shape. - Registering a shape tightens the contract going forward; historical data keeps the shape it was written with. - For anything genuinely new, starting loose, learning and then tightening beats designing the whole model on day one. ### Reciprocal Rank Fusion: The Unsung Hero of Hybrid Search https://tesseradb.par2labs.com/articles/reciprocal-rank-fusion Technology · 2026-08-29 · 2 min read · PAR2 Labs We asked five senior engineers to explain Reciprocal Rank Fusion last month. Three of them got it wrong. One of them was the person who'd added it to their codebase. It's been used by every serious hybrid search system for years and almost nobody understands it. Time to fix that. #### The problem RRF solves Two retrieval systems give you two ranked lists. Vector search says: document A is most similar, then B, then C. BM25 says: document C is most relevant, then A, then D. How do you produce one ranked list that uses both? The naïve answers all break: average the scores (but they're on different scales), normalise then average (but normalisation is fragile), take the union and dedupe (but you lose ordering information). What you actually want is a rule that says “items both systems liked should rank above items only one liked,” without trusting either system's confidence calibration. #### The actual formula For each item, sum 1 / (k + rank) across the rankings it appears in, where k is a smoothing constant (Tessera defaults to 60). ``` rrf_score(item) = sum over rankings of 1 / (k + rank_in_that_ranking) ``` An item that ranks #1 in vector search and doesn't appear in BM25 gets 1/(60+1) = 0.0164. An item that ranks #5 in vector and #3 in BM25 gets 1/(60+5) + 1/(60+3) = 0.0154 + 0.0159 = 0.0313. That item ranks higher despite never being the top hit in either ranking. > It's literally a one-line formula and it beats more sophisticated approaches. #### Why it works so well in practice - Scale-invariant — doesn't care if vector scores are in [0,1] and BM25 scores are in [0,100]. - Tunable — adjust k to control how much the top-of-list dominates. Smaller k = more aggressive promotion of top hits. - Robust — one bad ranking doesn't sink an item that's strong elsewhere. #### Tessera's twist Tessera runs weighted RRF across three rankings — vector, BM25, and graph proximity — so a per-ranking weight tilts the fusion towards keyword-anchored retrieval for technical corpora or towards semantic similarity for conversational ones. It's the same one-line formula, extended from two lists to three, with the smoothing constant left tunable. RRF is the kind of result you wish were called “Strong Combination Heuristic” so the field would stop being scared of it. It's literally a one-line formula and it beats more sophisticated approaches. #### When to use something else RRF is dominated when you have a calibrated, learned ranker — a Learning-to-Rank model trained on click data, for example. If you have that, use it. If you don't, RRF is the right default by a wide margin. **Key takeaways** - RRF merges ranked lists without trusting any one system's score scale or calibration. - Each item scores the sum of 1 / (k + rank) across the rankings it appears in; Tessera defaults k to 60. - An item ranked well by two systems beats one ranked first by only one. - Tessera runs weighted RRF across vector, BM25 and graph proximity; a calibrated learned ranker beats it if you have one. ### What We Learned Shipping the First Postgres Connector https://tesseradb.par2labs.com/articles/shipping-postgres-connector Technology · 2026-08-29 · 2 min read · PAR2 Labs The Postgres connector looks like 300 lines of code. The first version was 60 lines. Everything between 60 and 300 was a small humility lesson about all the things production data sources do that demos don't. #### Lesson 1: information_schema is a contract Reading column types is easy. Reading column types and primary keys and foreign keys and nullability — and getting all of them consistently across Postgres versions — turned out to be the bulk of the work. Every assumption we made about the schema's stability was wrong at least once. We now run three separate queries to information_schema and reconcile them in code. #### Lesson 2: cursors are about late data Our first cursor implementation was WHERE updated_at > last_seen. Worked beautifully on the demo dataset. Broke immediately against real Postgres because applications backdate inserts — a row arriving at 14:05 might have an updated_at of 14:04:30, which our sync had already advanced past. We now optionally pull a configurable overlap window on each poll. The cursor advances, but slightly slower than wall-clock time. Every “this happened at time T” timestamp in a production database is lying by some amount. The connector either accommodates that or silently loses data. > Every “this happened at time T” timestamp in a production database is lying by some amount. #### Lesson 3: parametrised queries, always It's tempting to format the cursor value straight into the SQL string — even when the cursor is a timestamp you control. Don't. The corner cases that break are a long list: special characters in timestamps, locale-sensitive formatting, and injection through field names you thought were trusted. Bind every cursor value as a parameter, validate any identifier you have to interpolate against a strict allowlist, and accept the small rigidity that comes with it. #### Lesson 4: credentials are a UX problem The most-asked question wasn't about cursor semantics or schema drift. It was about whether the password we asked them to paste into the wizard was stored safely. The answer — connector credentials are held encrypted at rest, not in plaintext — was already true; the fix was making that explicit in the UI. Once people could see it, the question stopped. #### What's next The connector interface is intentionally small: anything that's a cursor-based pull from a structured source can implement it. Today the PostgreSQL connector ships production-validated — it even auto-discovers foreign keys and turns them into graph connections — alongside a REST API connector. MySQL, MongoDB, S3/Parquet, and Kafka are on the roadmap, staged for later releases. The framework was the hard part; each subsequent source is mostly a small, well-bounded adapter. (Connectors are an Enterprise feature.) **Key takeaways** - Reading types, keys and nullability consistently across Postgres versions was the bulk of the work. - Applications backdate rows, so the cursor can pull an overlap window and advances slower than wall-clock time. - Bind every cursor value as a parameter and check any interpolated identifier against a strict allowlist. - Credentials were already encrypted at rest; showing that in the UI is what stopped the question. ### Defending the Data, Not the Perimeter https://tesseradb.par2labs.com/articles/defending-the-data-not-the-perimeter Technology · 2026-08-29 · 2 min read · PAR2 Labs The classic database security model is a moat: authenticate at the edge, and assume that anyone inside the wall is trustworthy. That assumption fails the moment a credential leaks, an insider goes rogue, or an application is tricked into issuing a query it shouldn't. AutoGuard, Tessera's AI-security stack, is built for the world where the perimeter has already been crossed. #### Why in-engine beats a bolt-on gateway A proxy in front of the database sees traffic; it doesn't see data. It can't reason about whether this account's behaviour is unusual for that account, or whether a query is trying to walk the graph the way an attacker enumerates it. Because AutoGuard runs inside the engine, protection travels with the data instead of living in a separate box that has to be kept in sync with the thing it's guarding. #### Eight layers, at the claim level - Injection detection — inspects every query for known attack shapes, with case and comment normalisation to defeat bypasses, and can block in real time. On by default. - Behavioural anomaly scoring — learns what normal looks like for each account and flags deviations: unusual amounts, high velocity, brand-new counterparties. - Canary / honeypot tokens — planted tripwires that reveal enumeration and probing. - Adaptive query defence — defences that tighten as suspicious activity rises. - Behavioural biometrics — models of normal access patterns that catch anomalous callers. - Security-posture escalation — the system raises its own guard level in response to detected pressure. - Meta-detection — detection of attempts to probe or evade the detectors themselves. - Ensemble blocker — a final decision layer that acts on the aggregate signal. > Tessera defends the data — eight layers deep, inside the engine, with every action written to a tamper-evident ledger. #### The compliance surface on top Above the stack sit the capabilities regulated teams actually get graded on: a tamper-evident, hash-chained audit log where altering any past entry breaks the chain and is detected on verification; fraud-cycle detection that finds circular money movement in the transaction graph; AML typology alerts; sanctions screening — against the lists you provide — with alias and fuzzy matching; and regulatory classification that maps fields onto the FIBO and BIAN vocabularies. A circular-flow signature, for instance, is a pattern the graph can express directly: ```cypher // Money that leaves an account and comes back around: MATCH (a)-[:SENDS]->(b)-[:SENDS]->(c)-[:SENDS]->(a) RETURN a, b, c ``` And red-team simulation lets you attack the whole stack on demand — enumeration, exfiltration, injection, privilege escalation, structuring — and get back a measured report of what was blocked, rather than a feeling that you're probably fine. Most databases protect the perimeter. Tessera defends the data — eight layers deep, inside the engine, with every action written to a tamper-evident ledger. #### The honest scope AutoGuard and the banking pack are Enterprise capabilities, and they're a defensive depth layer, not a replacement for network security, patching, or least-privilege access — which Tessera also enforces, with RBAC checked on every request. Sanctions screening is the matching engine; you load the lists you're required to screen against. The point isn't that one layer is magic. It's that an attacker now has to beat all of them, from inside, without tripping the ledger. **Key takeaways** - A proxy in front of a database sees traffic, not data; AutoGuard runs inside the engine, so protection travels with the data. - Eight layers run from injection detection and behavioural anomaly scoring to canary tokens and an ensemble blocker. - On top sit a hash-chained audit log, fraud-cycle detection, AML alerts, sanctions screening and FIBO and BIAN classification. - It is an Enterprise defensive-depth layer, not a replacement for network security, patching or least-privilege access. ### On-Premise AI Is Not an Oxymoron https://tesseradb.par2labs.com/articles/on-premise-ai-is-not-an-oxymoron Technology · 2026-08-29 · 2 min read · PAR2 Labs Ask a bank, a hospital, or a government team to run their AI workloads on someone else's servers and the conversation ends. Their data legally cannot leave the building. For years that meant “modern AI is not for you.” It doesn't have to. #### The gap that forces a bad choice The default AI/vector stack — a managed vector database, a hosted embedding API, a separate ML platform — is cloud-native by assumption. Every piece expects data to flow out to a service. For teams under data-residency rules, that assumption is disqualifying, so they're pushed towards the false choice between compliance and capability. #### One binary, on your hardware Tessera ships the full hybrid retrieval stack — graph, vector, full-text, SQL, and time-series over one copy of your data — as a single self-contained binary with no JVM and no separate install. It runs entirely on your own hardware with no cloud call-home, so residency and compliance are never in question. It starts in seconds, and backing up one data folder preserves the whole database. > What it removes is the forced trade: the full hybrid-plus-ML stack, running exactly where regulated data has to stay. #### The ML runs where the data already is The part teams assume they'll have to send away — training and serving models — happens in-database on the Enterprise tier. Node classification, a message-passing GNN, link prediction, GAN-generated synthetic data, and online learning all run over the same store, so no sensitive data ever leaves the engine to reach a separate ML system. A fraud GNN can learn that “an account is risky because of the company it keeps,” backed by native lineage and the tamper-evident audit chain — explainable, auditable ML on data that never moves. The interesting question was never “cloud or on-prem.” It was whether you could have the whole modern stack — retrieval and ML together — without the data ever leaving your walls. You can. #### The honest scope This is single-node, self-hosted deployment done well, not a managed cloud — Tessera's managed offering is roadmap, not shipping — and the in-database ML is Enterprise, with quality that depends on feeding it real, sufficiently large data. What it removes is the forced trade: the full hybrid-plus-ML stack, running exactly where regulated data has to stay. **Key takeaways** - The default AI and vector stack assumes data flows out to cloud services, which rules it out under data-residency rules. - Tessera ships graph, vector, full-text, SQL and time-series retrieval as one self-contained binary with no cloud call-home. - On the Enterprise tier, model training and serving run in-database, so sensitive data never leaves the engine. - It is single-node self-hosting, not a managed cloud; the managed offering is on the roadmap. ### Tessera DB Tutorial: Build Your First Hyperedge in 5 Minutes https://tesseradb.par2labs.com/articles/build-your-first-hyperedge Technology · 2026-08-29 · 7 min read · PAR2 Labs This is the absolute starting point. We'll get Tessera running locally, load a small dataset through the admin dashboard, and then look at how the same records show up in the relational, graph, vector, full-text, and time-series dimensions — without copying anything anywhere. #### Before you start > **Prerequisites** > - Tessera ships as a single self-contained binary — no JVM, no separate install. Download the Community build for your platform and put it somewhere on your path. That's all you need for this tutorial. #### Step 1: Start the server Launch the binary, pointing it at an empty folder for its data. It starts in seconds and prints the address of the bundled admin dashboard to the log. ```bash tessera serve ./my-data ``` #### Step 1: Start the server — what the log shows You'll see log lines confirming the engine has loaded with zero hyperedges. That's expected — the store is empty. #### Step 2: Open the admin dashboard In your browser, open the dashboard URL the server printed at startup. You'll land on the overview with everything at zero. Click Data Sources in the left sidebar — that's where ingestion lives. #### Step 3: Load the sample dataset At the top of the Data Sources panel is a card that seeds a small social-network dataset — people, posts, follows, comments — into all five dimensions at once. Click Load Sample Data. A confirmation slides out telling you the sample was loaded and indexed across the five dimensions. Below it, buttons let you jump straight into each dimensional view. > One write, five indexes, zero ETL. #### Step 4: See the same data five ways Open each view in turn and notice you're always looking at the same records: - Relational — tabular rows; try SELECT * FROM Person LIMIT 10. - Graph — an interactive node-and-edge visualisation with the follow network laid out by force. - Vector — paste any text; Tessera returns the most semantically similar entities from the same data. - Full-text — keyword search over the same records, with matched terms highlighted. - Time-series — the same records placed on their bitemporal time axis. #### Step 4: See the same data five ways — one copy Nothing was duplicated. One copy of the data feeds every view. #### Step 5: Add a fact of your own Now add a record yourself. In the Data Sources panel, use the import option to bring in a tiny file of your own — say, a few money transfers. When you import, you choose which columns are connections (endpoints) and which are plain properties. Mark the sender and receiver columns as endpoints so each transfer becomes a real graph fact, and leave amount, currency, and memo as properties. Refresh the overview. The hyperedge count ticks up beyond the sample dataset. Your new transfers are indexed in every dimension at once — including the vector index, because any text property (like the memo) is embedded the moment the row lands, provided you've configured an embedding provider. #### Step 6: Query it two different ways From the query editor, ask for the same fact in two languages: ```sql -- Relational SELECT sender, receiver, amount FROM Transfer WHERE amount > 100; ``` ```cypher // Graph pattern MATCH (a)-[r:Transfer]->(b) WHERE r.amount > 100 RETURN a, r, b ``` #### Step 6: Query it two different ways — the result Both return the same hyperedge. The full-text dimension picked up words in the memo automatically; the time-series dimension stamped both its valid time and transaction time. (Tessera also has a native query language, TQL, for the same data — pick whichever fits the question.) #### What just happened One write, five indexes, zero ETL. That's the core promise of Tessera. Loading a dataset, importing your own, and running a query from the editor are the three pieces of muscle memory you'll use most. Everything else builds on top. If you can do this loop in five minutes — load data, inspect it across dimensions, write a query — you have the mental model. The rest is depth. **Key takeaways** - Started Tessera as a single binary and opened the bundled admin dashboard. - Loaded the sample social-network dataset and seen the same records in the relational, graph, vector, full-text and time-series views. - Imported transfers of your own, marking sender and receiver as endpoints so each one becomes a graph fact. - Queried the same hyperedge in SQL and in Cypher. ### Tessera DB Tutorial: Connect a Postgres Database with Automatic Graph Endpoint Mapping https://tesseradb.par2labs.com/articles/connect-a-postgres-database Technology · 2026-08-29 · 7 min read · PAR2 Labs If you already have data in Postgres, this is the fastest way to put it into Tessera. We'll connect a source, let Tessera discover the schema, auto-derive graph relationships from foreign keys, and set up incremental sync so updates keep flowing. #### Before you start > **Tier** > - Data-source connectors are an Enterprise feature. Version 1 ships production-validated PostgreSQL and REST API connectors; MySQL, MongoDB, S3/Parquet, and Kafka are on the roadmap. > **What you'll need** > - A running Tessera server (see "Build your first hyperedge" if not). > - A Postgres database with at least two tables and a foreign key between them. > - Read-only credentials for that database. #### Step 1: Open the connection wizard In the admin dashboard, click Data Sources, then add a new source and choose the PostgreSQL connector. #### Step 2: Enter credentials Fill in host, port, user, password, and database name, using read-only credentials. > **On password handling** > - With at-rest encryption enabled, connector credentials are encrypted on disk with authenticated encryption. Without it, they're stored in plaintext — fine for local dev, not for production. See "Enable at-rest encryption for connector credentials." #### Step 3: Discover the schema Rather than typing table names by hand, click Discover schema. Tessera connects, reads the database's own catalogue, and returns a checklist of every table — each annotated with its columns and any foreign keys. Foreign-key columns are flagged with an auto graph endpoints badge: Tessera detected the relationship and will turn it into a real graph edge for you, no manual mapping required. #### Step 4: Pick tables and apply Tick the tables you want — say, a customers table and an orders table — and apply the selection. Tessera confirms how many graph relationships it auto-derived from your foreign keys (for example, orders linked to customers). #### Step 5: Choose a sync mode - Manual — you trigger syncs from the dashboard when you want them. - Polling — Tessera pulls on an interval you set. > Foreign-key relationships are real graph edges, not flat property values. #### Step 5: Choose a sync mode — for this tutorial For this tutorial, pick polling on a short interval so you can watch it run. #### Step 6: Turn on incremental sync Enable incremental sync and choose a cursor column — a value that only ever increases on insert or update, such as an updated_at timestamp. On each poll, Tessera fetches only the rows newer than the last cursor value it saw. The cursor advances to the newest value in each batch and is persisted with the source, so the next poll resumes from where the last one left off — even across server restarts. #### Step 7: Verify with a dry-run preview Before saving, run a preview. Tessera pulls a single row from each selected table and renders it across all five dimensions in side-by-side cards, so you can see exactly what each row becomes: a relational row, a graph hyperedge with named endpoints, indexed text, a vector embedding, and a bitemporal record. Nothing is inserted. If anything looks wrong — a mis-mapped endpoint, the wrong cursor column — fix it now. #### Step 8: Save and watch the first sync run Save the source. It appears in the connected-sources list with its schedule. When the first sync fires, open the source's history panel: each attempt records its timestamp, how many rows were imported, the new cursor value, and any error. The next poll pulls only rows newer than that cursor. #### What you have now Your Postgres data is mirrored into Tessera as hyperedges. Foreign-key relationships are real graph edges, not flat property values. The data is indexed in all five dimensions, and updates flow in automatically with only the delta being pulled. #### Try a query Switch to the query editor and walk the auto-derived graph with Cypher: ```cypher MATCH (c:Customers)-[:orders]-(o:Orders) WHERE o.total > 1000 RETURN c.email, count(o) AS big_orders ORDER BY big_orders DESC LIMIT 20 ``` #### Try a query — what it walks Tessera traverses the graph edges synthesised from your Postgres foreign keys. No graph-loading pipeline, no separate database, no sync job — just the same source data made queryable through a different lens. **Key takeaways** - Connected a PostgreSQL source with read-only credentials from the Data Sources wizard. - Used schema discovery to turn foreign keys into graph relationships without manual mapping. - Set up polling with incremental sync on a cursor column, and checked each table's mapping with a dry-run preview. - Walked the auto-derived graph with a Cypher query. ### Tessera DB Tutorial: Bitemporal Queries to Reconstruct Historical State for Audit https://tesseradb.par2labs.com/articles/bitemporal-queries-for-audit Technology · 2026-08-29 · 5 min read · PAR2 Labs Every hyperedge in Tessera carries two independent time intervals: valid time (when the fact is true in the real world) and transaction time (when the database learned it). This tutorial shows how to query against each, and why you'll want to. #### The mental model Think of a customer who moved house. Their old address is: - Valid from 2024-01-01 to 2024-12-31 — when they actually lived there. - Recorded (transaction time) on 2024-01-10 — when they finally got around to telling the bank. #### Two questions, two axes - "Where did they live on 2024-06-01?" → ask along valid time. - "What address did the system show on 2024-06-01?" → ask along transaction time. #### Step 1: Record a bitemporal fact When you insert or import a fact, Tessera stamps it on both clocks. You can set the valid-time interval explicitly (the period the fact describes) while transaction time is captured automatically as "now" — the moment the database learned it. A fact whose transaction-time interval is still open is the current, live version. #### Step 2: Snapshot along valid time — what was true in the world Ask for the state of the data as it was valid at a chosen instant. Tessera returns every fact whose valid-time interval contains that instant. This answers "where did this customer live in the middle of the year?" regardless of when the bank found out. > Transaction time answers questions about your system's knowledge of the world. #### Step 3: Snapshot along transaction time — what the system knew Ask for the state of the data as the database recorded it at a chosen instant. This is time-travel over the system's own knowledge. Query the database as of early January and the new address will not appear — it wasn't recorded until the 10th — even though, in hindsight, it was already true. That gap between reality and knowledge is exactly what a regulator asks about. #### Step 4: Facts overlapping a range Ask for every fact whose valid time overlaps a window — "all addresses valid at any point during the second quarter." This surfaces everything that was in effect across a period, not just at a single instant. #### Step 5: Combine both clocks The most useful queries combine both axes: "what was true in the world on date X, as known to the system on date Y." Because the new address was valid mid-year but wasn't yet recorded in early January, that combined query correctly returns nothing for it — the honest historical answer, and the question regulators ask. #### When to reach for each Valid time answers questions about the world. Transaction time answers questions about your system's knowledge of the world. Audits, regulations, and disputes almost always want the second one. #### What you have now You can reconstruct the state of any entity at any past point in time, and independently reconstruct what your system would have shown at that point. Those two capabilities together cover almost every audit, compliance, and dispute-resolution case — without maintaining a separate audit log. **Key takeaways** - Recorded a fact on both clocks: an explicit valid-time interval, with transaction time captured automatically. - Taken snapshots along valid time (what was true) and along transaction time (what the system knew). - Found every fact whose valid time overlaps a window, not just a single instant. - Combined both clocks to ask what was true on one date, as known to the system on another. ### Tessera DB Tutorial: Build a GraphRAG Retrieval System End to End https://tesseradb.par2labs.com/articles/graphrag-retrieval-end-to-end Technology · 2026-08-29 · 6 min read · PAR2 Labs This tutorial builds a working GraphRAG retrieval pipeline. By the end you'll have a document store with semantic, keyword, and graph search, fused into a single ranked result list with provenance, ready to feed an LLM prompt. #### Before you start > **Tier** > - Hybrid retrieval (fusing vector and keyword search) is available in Community. The deeper GraphRAG path — adding graph proximity and lineage-backed provenance — is an Enterprise capability. #### What we're building A small policy-document retrieval system. Each document references other documents (a "see also" graph). A query against this system returns the most relevant documents using three signals: - Vector similarity — semantic match on document text. - Keyword relevance (BM25) — exact-term anchors. - Graph proximity — documents linked to highly-ranked hits. #### What we're building — fusing the signals We fuse all three with Reciprocal Rank Fusion, so a document strong in any signal rises to the top — no score normalisation needed. #### Step 1: Configure an embedder Point Tessera at an embedding provider — a hosted model or a local one. From then on, any document you insert has its text embedded automatically. For quick local testing you can start with a deterministic stand-in embedder and swap in a real model before you care about retrieval quality. #### Step 2: Ingest documents Insert each policy document as an entity with a title and body. The body text triggers auto-embedding on insert, and it's indexed for keyword search at the same time. No separate vector pipeline and no separate search service did any of this. > The graph dimension other RAG systems lack is here because Tessera was tracking it anyway. #### Step 3: Add 'see also' links as graph facts A "see also" relationship is its own fact connecting a source document to a target document. Adding these lights up the graph dimension automatically: a traversal from any document walks its see-also network. Model the links you know — wire-transfer policy to sanctions policy, sanctions policy to suspicious-activity reporting, and so on. ```cypher // Walk two hops out from one document along the see-also graph MATCH (d:PolicyDoc {doc_id: 'POL-001'})-[:SeeAlso*1..2]-(related:PolicyDoc) RETURN DISTINCT related.doc_id, related.title ``` #### Step 4: Run a hybrid query Take a vague, natural-language question — "what do we need to do for a large transfer to a foreign account?" — and run it through the pipeline. Tessera embeds the question the same way it embedded the documents, scores keyword relevance, walks the see-also graph out from the strongest hits, and fuses the three rankings into one list. The document about wire-transfer limits ranks first (semantic and keyword hit); the sanctions-screening policy follows because it's graph-proximal to it and shares keywords; related policies surface through their graph links even when their wording doesn't match the question. #### Step 5: Tune the weights The fusion is weighted, and sensible defaults lean on semantics first, then keywords, then graph proximity. Shift the balance to fit your corpus: - Highly technical corpora — lean harder on keywords; exact matches (drug names, error codes) matter more than paraphrase. - Conversational corpora — lean on semantics; users paraphrase what's actually written. - Densely-linked corpora — lean on graph proximity; a document's neighbours are usually highly relevant. #### Step 6: Assemble LLM context with provenance Feed the ranked results into your prompt. Because every retrieved fact is traceable to its source through native lineage, the context you build isn't just relevant passages — it's passages your AI can cite. A graph-aware assembly can also include each hit's top neighbours, giving the model contextual stitching pure vector retrieval can't provide. #### What you have now A working RAG pipeline that combines three retrieval signals over the same store — no separate vector database, no separate search service, no sync between them — and every answer traceable to the facts that produced it. The graph dimension other RAG systems lack is here because Tessera was tracking it anyway. **Key takeaways** - Configured an embedder so every inserted document is embedded and keyword-indexed on write. - Modelled "see also" links as graph facts and walked them with Cypher. - Run a hybrid query that fuses vector, keyword and graph rankings with Reciprocal Rank Fusion, and tuned the weights for your corpus. - Assembled LLM context from results that trace back to their sources through lineage. ### Tessera DB Tutorial: Connect a REST API Source with Bearer Auth https://tesseradb.par2labs.com/articles/connect-a-rest-api-source Technology · 2026-08-29 · 3 min read · PAR2 Labs REST sources are the simplest connector to set up. If you can hit the endpoint with curl, Tessera can mirror it. #### Before you start > **Tier** > - The REST API connector is an Enterprise feature, alongside the PostgreSQL connector. #### Step 1: Pick an endpoint The endpoint should return either a JSON array or a JSON object with an array inside it. Endpoints that return a single object per request work too — Tessera treats that as a one-row response. #### Step 2: Open the wizard In the admin dashboard, go to Data Sources, add a new source, and choose the REST API connector. #### Step 3: Choose an auth scheme - Bearer — paste a token; Tessera sends it as a bearer credential. - Basic — provide a username and password for HTTP basic auth. - Custom header — supply a header name and value (for example an API-key header your service expects). > The rows arrive as hyperedges, indexed across all five dimensions. #### Step 4: Set the rows path (if needed) If your endpoint wraps the array in an object, tell the connector where to find it — the name of the field that holds the array. If the array is already at the root, leave it blank. Nested locations are written with dots. #### Step 5: Map endpoints (optional) To turn fields into graph relationships, mark which fields are endpoints and give each a role. A field like a user id is a good candidate — mapping it makes every row link to that user in the graph rather than just carrying the id as a flat value. #### Step 6: Save and sync Save the source, then run a sync. The rows arrive as hyperedges, indexed across all five dimensions. The history panel shows how long the sync took, how many rows arrived, and any errors. #### Common gotchas - Auth failures usually mean the scheme doesn't match. Confirm the same credential works from curl first. - If the API paginates server-side, a single sync fetches one page — combine it with incremental sync and the right cursor field to walk forward through the pages. - Line-delimited JSON responses are accepted natively. **Key takeaways** - Picked an endpoint that returns a JSON array, an object wrapping one, or a single object. - Configured bearer, basic or custom-header auth, and a rows path for nested responses. - Optionally mapped fields such as a user id as graph endpoints. - Saved and synced the source, with rows arriving as hyperedges across all five dimensions. ### Tessera DB Tutorial: Set Up Auto-Embedding for Semantic Search https://tesseradb.par2labs.com/articles/auto-embedding-for-semantic-search Technology · 2026-08-29 · 2 min read · PAR2 Labs Auto-embedding is the difference between "we support vector search" and "every text property is searchable by meaning, by default." You configure a provider once, and Tessera does the rest on every write. #### Step 1: Start with a stand-in embedder For local development and tests, Tessera can use a deterministic stand-in embedder that needs no external service. It produces consistent vectors for identical inputs but no real semantic structure — fine for exercising the pipeline end to end, not for judging retrieval quality. #### Step 2: Wire in a real embedder For real semantic search, point Tessera at an embedding model — a hosted provider or a local model. Any function that turns text into a vector will do. > **Dimension consistency** > - The vectors your provider returns must match the vector width Tessera is configured for. Set that before enabling the embedder; vectors of the wrong length are skipped with a warning. > Any function that turns text into a vector will do. #### Step 3: Insert and watch it index From here, every insert with a text property auto-embeds. Import an article with a title and body and the body is embedded the moment the row lands — searchable immediately, with no separate step. #### Step 4: Search by meaning Search with plain text: the server embeds your query the same way it embedded your data and returns the nearest records. You'll get an article back about international money transfers even if those exact words never appear in it — that's the embedding doing its job. (This vector-from-text path requires a configured embedding provider.) **Key takeaways** - Started with a deterministic stand-in embedder to exercise the pipeline without an external service. - Pointed Tessera at a real embedding model, with its vector width matching the width Tessera is configured for. - Inserted records whose text properties were embedded the moment they landed. - Searched by meaning with plain text, embedded by the server the same way as the data. ### Tessera DB Tutorial: Discover Schema and Auto-Derive Graph Endpoints from Foreign Keys https://tesseradb.par2labs.com/articles/schema-discovery-and-foreign-key-graphs Technology · 2026-08-29 · 2 min read · PAR2 Labs This is the feature that turns "ingest a table" into "build a queryable graph." Schema discovery reads your Postgres catalogue and surfaces every foreign key as a candidate graph relationship. #### Before you start > **Tier** > - Schema discovery ships with the Enterprise PostgreSQL connector. #### Step 1: Open the wizard In the admin dashboard, go to Data Sources, add a PostgreSQL source, and fill in read-only credentials. #### Step 2: Discover the schema Instead of typing table names, click Discover schema. Tessera connects, reads the database's own catalogue, and returns a list of tables annotated with their columns, primary keys, and foreign keys. > The foreign-key structure of your relational source is the graph. #### Step 3: Read the FK annotations Each foreign-key column is marked with an arrow to the table it references and an auto graph endpoints badge. That badge means: tick this table and Tessera will generate the endpoint mapping for you, turning the foreign key into a real graph edge. #### Step 4: Apply and verify Tick the tables you want and apply the selection. Tessera confirms the mappings it auto-derived — for example, orders linked to customers, shipments linked to addresses, line items linked to products. #### Step 5: Save and query the graph After saving and syncing once, you can immediately walk the auto-derived graph: ```cypher MATCH (o:Orders)-[:customers]-(c:Customers) WHERE o.total > 1000 RETURN c.email, o.id, o.total ``` #### Step 5: Save and query the graph — no pipeline No graph-loading pipeline. No separate graph database. The foreign-key structure of your relational source is the graph. **Key takeaways** - Added a PostgreSQL source with read-only credentials. - Used Discover schema to list tables with their columns, primary keys and foreign keys. - Applied a selection so Tessera auto-derived graph endpoints from the foreign keys. - Walked the resulting graph with Cypher after a single sync. ### Tessera DB Tutorial: Set Up Incremental Sync with a Cursor Column https://tesseradb.par2labs.com/articles/incremental-sync-with-a-cursor-column Technology · 2026-08-29 · 3 min read · PAR2 Labs Without a cursor, every polling sync re-fetches the entire source. That's fine for a ten-row demo and painful for a large table. Incremental sync is the difference. #### Before you start > **Tier** > - Incremental sync is part of the Enterprise connector suite. #### Step 1: Pick a cursor column The cursor must only ever move forward as rows arrive. Good choices: - id — for append-only tables. - updated_at — for tables where rows are mutated in place, as long as the application bumps the timestamp on every update. - created_at — for true event streams. > **Bad cursor choices** > - Anything that can move backwards — manually-set timestamps, soft-delete flags, status columns — will silently skip rows when a value lower than the cursor arrives. > When nothing new has arrived, the sync returns quickly with zero rows imported. #### Step 2: Enable it in the wizard In the source's sync settings, turn on incremental sync and provide the cursor field — the column name for a database source, or the field name in the response for a REST source. For REST sources you also tell the connector which query parameter the API expects for "give me records after this value." #### Step 3: Watch the cursor advance Each successful sync records the new high-water cursor value with the source. Open the history panel and you'll see each attempt's timestamp, rows imported, and the cursor it advanced to. When nothing new has arrived, the sync returns quickly with zero rows imported. #### Step 4: Handle late-arriving data If your source delivers rows with backdated cursor values — a handheld scanner uploading yesterday's events today — a strict cursor will skip them. Two options: - Use a column recorded by the source database (when the row landed) rather than an event-time column (when the event happened). - Pull with a small overlap window so each sync re-checks a recent slice and catches stragglers. The trade-off is a little duplicate work — and because every fact is content-addressed, re-seen rows are de-duplicated on insert. **Key takeaways** - Chosen a cursor column that only ever moves forward, such as id, updated_at or created_at. - Turned on incremental sync with the cursor field, plus the query parameter a REST API expects. - Watched each sync record its new high-water cursor value in the history panel. - Handled late-arriving rows with a source-recorded column or a small overlap window. ### Tessera DB Tutorial: Monitor Sync Attempts Across All Sources https://tesseradb.par2labs.com/articles/monitoring-sync-history Technology · 2026-08-29 · 2 min read · PAR2 Labs Tessera records every sync attempt across every source. Per-source history is one click away; cross-source activity is its own view. #### Before you start > **Tier** > - Connectors and their sync monitoring are an Enterprise feature. #### Step 1: Per-source history In the Data Sources view, open the history panel on any source. It shows the recent sync attempts with each one's timestamp, rows imported, duration, the new cursor value, and the error message if it failed. #### Step 2: Cross-source feed The sync-activity view collects every sync from every source, newest first, in one place. Filter by source or by status to focus on failures. A summary strip shows totals — how many syncs ran, how many failed, how many rows came in, across how many sources — for a "how is the fleet doing today" glance. > Filter by source or by status to focus on failures. #### Step 3: Feed it into your monitoring stack Tessera emits standards-based metrics in Prometheus and OpenTelemetry formats, so the same signals flow into Grafana, Datadog, Honeycomb, or any OTLP backend — no lock-in. Alert on repeated failures or unexpected zero-row syncs there. #### What the history captures - Timestamp of the sync attempt. - Rows imported (zero if nothing new, or on failure). - How long the attempt took. - Error message on failure; none on success. - New cursor value, for incremental syncs. #### What the history captures — how much is kept The panel keeps the most recent attempts per source; older ones roll off. **Key takeaways** - Opened a source's history panel to see each attempt's timestamp, rows imported, duration, cursor value and any error. - Used the cross-source sync-activity view, filtered by source or status, with its summary strip of totals. - Sent the same signals to your monitoring stack as Prometheus and OpenTelemetry metrics. ### Tessera DB Tutorial: Enable At-Rest Encryption for Connector Credentials https://tesseradb.par2labs.com/articles/encrypting-connector-credentials Technology · 2026-08-29 · 3 min read · PAR2 Labs By default Tessera persists connector credentials in plaintext and warns you about it. For production, turn on at-rest encryption: the same fields become authenticated ciphertext (AES-256-GCM) on disk, alongside the storage and audit layers. #### Before you start > **Tier** > - Encryption at rest is an Enterprise feature — optional and opt-in. #### Step 1: Generate a strong key Encryption at rest is unlocked with a secret key you supply. Generate one with plenty of entropy from any tool you trust. ```bash openssl rand -hex 32 ``` #### Step 2: Provide the key at startup Give the running server the key when it boots, sourced from your secret manager rather than hard-coded anywhere. On startup Tessera logs that credentials and data are encrypted at rest, confirming the key was picked up. > Don't bake the key into a script or image. #### Step 3: What gets protected Every secret-shaped field a connector stores — passwords, API keys, connection strings — is replaced on disk with authenticated ciphertext, each with its own unique nonce. The durable audit log and storage layers are covered under the same key. Because the reader auto-detects encrypted versus plaintext, you can turn this on without a data migration. #### Step 4: Restart and verify Restart the server with the same key. Sources load, credentials decrypt transparently, and polling resumes. Lose the key and the data is unrecoverable by design — Tessera will fail to load the affected source and log a clear error rather than silently continuing. #### Key management in practice Don't bake the key into a script or image. Source it from your secret manager (Vault, AWS Secrets Manager, GCP Secret Manager) at process start. It only needs to exist in the running process's environment. **Key takeaways** - Generated a high-entropy key with openssl rand -hex 32. - Supplied the key at startup from a secret manager, and seen the startup log confirm it was picked up. - Had connector secrets, the audit log and storage written as authenticated ciphertext, with no data migration. - Restarted with the same key and confirmed that sources decrypt and polling resumes. ### Tessera DB Tutorial: Use the SQL Interface with JOINs and Aggregates https://tesseradb.par2labs.com/articles/sql-joins-and-aggregates Technology · 2026-08-29 · 4 min read · PAR2 Labs The SQL interface exists because most analysts already speak SQL and have no appetite to learn a new language just to evaluate Tessera. Same dialect they know, same results — over the same data the graph and vector dimensions see. #### Step 1: Define tables A CREATE TABLE statement declares a type with a flat property schema: ```sql CREATE TABLE accounts ( id INTEGER PRIMARY KEY, name TEXT, balance DOUBLE PRECISION ); CREATE TABLE transfers ( id INTEGER PRIMARY KEY, from_id INTEGER, to_id INTEGER, amount DOUBLE PRECISION, created_at TIMESTAMP ); ``` #### Step 1: Define tables — the same rows as a graph Foreign keys become real graph edges when you provide endpoint mappings on ingest, so the same rows are queryable as tables here and as a graph elsewhere. #### Step 2: INSERT ```sql INSERT INTO accounts (id, name, balance) VALUES (1, 'Alice', 50000.0); INSERT INTO accounts (id, name, balance) VALUES (2, 'Bob', 12000.0), (3, 'Carol', 85000.0); ``` #### Step 3: SELECT with WHERE, ORDER BY, LIMIT ```sql SELECT name, balance FROM accounts WHERE balance > 10000 ORDER BY balance DESC LIMIT 10; ``` #### Step 4: JOIN ```sql SELECT t.id, t.amount, a.name AS sender, b.name AS receiver FROM transfers t INNER JOIN accounts a ON t.from_id = a.id INNER JOIN accounts b ON t.to_id = b.id WHERE t.amount > 1000 ORDER BY t.amount DESC; ``` > The goal is no surprises for SQL users. #### Step 4: JOIN — how joins resolve INNER JOIN and LEFT JOIN both work, resolved against the underlying graph rather than a flat row scan. #### Step 5: GROUP BY and aggregates ```sql SELECT a.name, COUNT(*) AS tx_count, SUM(t.amount) AS total FROM transfers t INNER JOIN accounts a ON t.from_id = a.id GROUP BY a.name HAVING SUM(t.amount) > 5000 ORDER BY total DESC; ``` #### Step 5: GROUP BY and aggregates — what is supported COUNT, SUM, AVG, MIN, and MAX all work, and HAVING filters on aggregate results. #### Step 6: LIKE, IN, BETWEEN ```sql SELECT * FROM accounts WHERE name LIKE 'A%'; SELECT * FROM accounts WHERE id IN (1, 2, 3); SELECT * FROM accounts WHERE balance BETWEEN 10000 AND 100000; ``` #### Real SQL, not a toy subset Filters, joins, aggregation, upserts, prepared statements, materialised views, and triggers are all part of the relational dimension — and your existing BI tools and ORMs can talk to it over the PostgreSQL wire protocol. The goal is no surprises for SQL users. **Key takeaways** - Declared tables with CREATE TABLE and inserted rows, one at a time and several at once. - Filtered, sorted and limited results with WHERE, ORDER BY and LIMIT. - Joined transfers to accounts with INNER JOIN, and aggregated with GROUP BY, HAVING, COUNT and SUM. - Matched rows with LIKE, IN and BETWEEN, over the same data the graph and vector dimensions see. ### Tessera DB Tutorial: Run PageRank over Your Graph in 5 Minutes https://tesseradb.par2labs.com/articles/running-pagerank-over-your-graph Technology · 2026-08-29 · 3 min read · PAR2 Labs PageRank is the canonical centrality algorithm. It tells you which nodes are "important" in the structural sense — recursively, a node is important if other important nodes point to it. #### Before you start > **Tier** > - Graph Data Science — the 60+ graph algorithms, PageRank among them — is an Enterprise feature. #### Step 1: Load some graph data Either load the sample social network from the admin dashboard, or ingest your own data with at least one relationship type that has two endpoints — that's the minimum for a graph to walk. #### Step 2: Build a projection Graph algorithms run against a projection — a named, in-memory snapshot of your data shaped for analysis, optionally filtered by type and treated as directed or undirected. Build it once and run many analyses against it. > Build it once and run many analyses against it. #### Step 3: Run PageRank Run PageRank over the projection with the usual controls — a damping factor (0.85 is the conventional default) and an iteration cap. Each node comes back with a score; sort descending to see the most central entities. You can drive this from the admin dashboard's graph tools or through the query layer, whichever fits your workflow. #### Common uses - Fraud detection — high-PageRank accounts in a transaction graph are often hubs in mule networks. - Knowledge graphs — central documents in a citation network. - Feature engineering — node centrality as an input to downstream ML models. #### What about other algorithms? Tessera ships 60+ algorithms across centrality, community detection, pathfinding, similarity, embeddings, structural link prediction, and influence propagation. They all run against the same projection view. See the Graph Data Science section of the docs for the full catalogue. **Key takeaways** - Loaded graph data with at least one relationship type that has two endpoints. - Built a named, in-memory projection to run analyses against. - Run PageRank with a damping factor and an iteration cap, then sorted nodes by score to find the most central. ### Tessera DB Tutorial: Detect Communities in Your Graph with Louvain https://tesseradb.par2labs.com/articles/community-detection-with-louvain Technology · 2026-08-29 · 3 min read · PAR2 Labs Louvain is a modularity-optimising community detection algorithm. It finds clusters of nodes that are more densely connected to each other than to the rest of the graph — the algorithm of choice for most "who's coordinating with whom" questions. #### Before you start > **Tier** > - Community detection is part of Graph Data Science, an Enterprise feature. #### Step 1: Build the projection Project your data into a graph for analysis. Because community membership is symmetric, treat the projection as undirected. #### Step 2: Run Louvain Run Louvain over the projection with a resolution parameter (1.0 is a good starting point) and an iteration cap. Every node comes back tagged with a community id — same id means same community. > Every node comes back tagged with a community id — same id means same community. #### Step 3: Interpret the output Group the nodes by community id and sort the groups by size to see the structure: a few large communities, a long tail of small ones. The largest and the tightest are usually the most interesting. #### Step 4: Tune the resolution parameter The resolution parameter controls cluster granularity: - Below 1.0 — fewer, larger communities; good for broad themes. - Around 1.0 — the default; usually a sound starting point. - Above 1.0 — more, smaller communities; good for finding tight rings inside larger networks. #### Use case: fraud rings Build the graph from transaction endpoints (sender, receiver) and run Louvain. Communities with high internal density and low external density are candidate fraud rings — accounts that transact with each other far more than with the broader population. #### Other algorithms in this family - Label propagation — faster, less precise. - Connected components — grouping by reachability rather than modularity. - Triangle count — local clustering density. **Key takeaways** - Built an undirected projection, since community membership is symmetric. - Run Louvain with a resolution parameter and an iteration cap, tagging every node with a community id. - Grouped and sorted communities by size, and tuned the resolution for broader or tighter clusters. - Applied the method to fraud rings, building the graph from sender and receiver endpoints. ### Tessera DB Tutorial: Bucket and Aggregate Time-Series Data with Zero Copies https://tesseradb.par2labs.com/articles/time-series-bucketing-and-aggregation Technology · 2026-08-29 · 3 min read · PAR2 Labs Time-series analytics over your existing data. The timestamps are already on every record, so Tessera projects them into buckets without duplicating anything into a separate metrics database. #### Step 1: Choose the time axis Point the time-series view at a set of records and pick which clock to read — valid time (when the reading was true) or transaction time (when it was recorded) — depending on what "when" means for your question. #### Step 2: Bucket into intervals Group readings into fixed windows — hourly, for instance — and choose how to combine the values in each window: average, sum, min, max, count, first, or last. The result is one value per bucket, ready to plot. #### Step 3: Downsample Downsampling is just bucketing with a wider window. Roll per-minute data up to daily averages, daily highs, and daily lows to get an at-a-glance view of a long series. > Downsampling is just bucketing with a wider window. #### Step 4: Rates and moving averages Derive a rate per interval, smooth a noisy series with a moving average over a chosen number of buckets, or compute a rolling window aggregate such as a one-hour rolling max. #### Step 5: Gap filling When a sensor goes offline, its buckets are empty. Choose how to fill the gaps — leave them null, carry the previous value forward, interpolate linearly, or substitute a constant — so downstream charts and calculations stay well-behaved. #### Step 6: Continuous aggregates For dashboards that read the same rollups repeatedly, cache them as a continuous aggregate. It computes once and, on refresh, only recomputes the buckets past its high-water mark — expensive aggregations become cheap to serve without recomputing history. **Key takeaways** - Chosen whether the series reads valid time or transaction time. - Bucketed readings into fixed windows, combined with average, sum, min, max, count, first or last. - Derived rates, moving averages and rolling windows, and filled the gaps left by offline sensors. - Cached repeated rollups as a continuous aggregate that only recomputes buckets past its high-water mark. ### Tessera DB Tutorial: Branch Your Data Like You Branch Code https://tesseradb.par2labs.com/articles/branching-your-data Technology · 2026-08-29 · 3 min read · PAR2 Labs Database branching is what version control did for code: fork the data, experiment, merge back if it worked. Tessera implements it as copy-on-write — only the entities you modify live on the branch; everything else is read straight through from the parent. #### Step 1: Create a branch Starting from your main line, create a named branch and switch to it. From then on, any write you do lands on the branch, and reads see the branch's changes layered on top of the parent. #### Step 2: Make changes on the branch Insert experimental facts, adjust entities, whatever the experiment needs. When you reach a milestone, commit a versioned checkpoint with a message describing what changed — so you can come back to exactly this state later. #### Step 3: Compare branches Diff the branch against its parent to see precisely which entities changed and how. This is your review step before deciding whether the experiment was worth keeping. > If it didn't, just delete the branch — main was never touched. #### Step 4: Merge or discard If the experiment worked, switch back to main, merge the branch's changes in, and delete the branch. If it didn't, just delete the branch — main was never touched. #### What you can do per branch - Create a branch and switch between branches. - Commit a versioned checkpoint with a message. - Diff a branch to see what's changed. - Merge one branch's changes into another. - Delete a branch (you can't delete the main or the active branch). #### Where branching fits Branching is a power tool — great for migrations, A/B tests, and exploratory work — but not a substitute for transactions. ACID guarantees apply to writes on the active branch, not to cross-branch operations. **Key takeaways** - Created a named branch and switched to it, so writes land on the branch and reads fall through to the parent. - Committed a versioned checkpoint with a message at a milestone. - Diffed the branch against its parent to review what changed. - Merged the branch back into main, or deleted it and left main untouched. ## Who makes it PAR2 LABS PVT LTD — Technology . AI . Strategy . Films. We engineer world-class technology and AI products across intelligence, infrastructure, hardware, and story — designed to make sense, deployed to make a difference. Studio: https://par2labs.com · Contact: ceo@par2labs.com · +91 90591 69238