# Known Issues pgGraph is currently alpha software. Do not use it for production workloads without your own validation, backup, rollback, and load-testing plan. pgGraph is built around a simple launch standard: the most critical correctness, durability, safety, and operational paths should be solid first. There is always another way to optimize a graph engine, especially inside PostgreSQL, so we are launching with the critical paths working and then continuously improving in the open. This page documents known alpha limitations, next-update hardening work, and lower-priority follow-up items. The list is ranked by expected user impact, not by implementation difficulty. This page is the authoritative register for known limitations and correctness, operational, performance, or maintainability risks. Future product direction, new APIs, and feature expansion belong in [Roadmap](./roadmap). Completed hardening work remains documented in historical release notes and the resolved summaries below. Low-level PostgreSQL extension work involves real tradeoffs. Some optimizations make a query faster by keeping more data in memory, while others reduce memory pressure by doing more work per request. pgGraph has to weigh those choices carefully because it runs inside PostgreSQL backend processes rather than a separate service with its own resource envelope. ## Next Update Scope The next update is focused on issues that are either hard to change after users depend on SQL behavior, or important enough to fix before recommending production use. ### Data Correctness and Corruption | ID | Issue | Status | Notes | |---|---|---|---| | KI-001 | GQL mutable writes should re-check matched predicates at the final PostgreSQL write boundary under concurrent source-row changes. | Hardened | `SET`, `REMOVE`, `DELETE`, and `DETACH DELETE` now lock the PostgreSQL source row at the write boundary and re-evaluate the matched GQL predicate before mutating. Heavy two-session race gates cover stale `SET`, `REMOVE`, tenant-scope drift, and stale delete predicate paths. | ### SQL Contract and Query Semantics | ID | Issue | Status | Notes | |---|---|---|---| | KI-002 | Transaction-created nodes are visible to node-only GQL reads, while traversal/path reads still require materialized graph node indexes. | Typed rejection | Concrete traversal, multi-pattern join, and wildcard path entry-point scans now reject matching transaction-created nodes with a typed GQL execution error until temporary-ID traversal support is implemented. | | KI-003 | The GQL and Cypher parser surfaces need dedicated fuzz targets beyond unit and pgrx coverage. | Coverage added | `gql_parser` and `cypher_parser` fuzz targets now exercise the pgrx-free parser frontends with seed corpora for path variables, wildcard deletes, compatible Cypher matches, and unsupported Cypher calls. Sustained fuzz execution remains a release-environment activity because it requires `cargo-fuzz` and the pgrx fuzz build path. | ### SQL Safety and Schema Plumbing No currently tracked next-update items remain in this category after dynamic table SQL and discovery SQL parameterization work. ### Persistence and File Format | ID | Issue | Status | Notes | |---|---|---|---| | KI-011 | `.pggraph` variable metadata sections previously depended on bincode 1 payload behavior. | Hardened with rebuild requirement | `v0.1.6` moved metadata sections to bincode 2 serde encoding and rejects trailing bytes on decode. Existing derived `.pggraph` artifacts must be regenerated with `SELECT graph.build();` after upgrading. Future serializer-independent metadata encoding is tracked in [Roadmap](./roadmap). | ### Sync, Jobs, and Operator Semantics | ID | Issue | Status | Notes | |---|---|---|---| | KI-004 | pgGraph has a scheduler-safe `graph.run_scheduled_maintenance()` entry point, but no always-on internal scheduler for trigger-sync apply and overlay compaction in non-Docker installs. | Planned operational hardening | Docker installs can use the bundled `pg_cron` schedule, and other deployments can call `graph.run_scheduled_maintenance()` from `pg_cron`, cron, or an application scheduler. A future built-in scheduler should make the default trigger-sync experience require less external orchestration while preserving operator control over rebuild cost. | ### Internal Construction and Performance | ID | Issue | Status | Notes | |---|---|---|---| | KI-005 | Overlay neighbor merging and transaction-delta lookups still have optimization opportunities in traversal hot paths. | Measure before optimizing | Current behavior is correctness-gated. Future work should use benchmarks before changing duplicate suppression, overlay indexing, or transaction delta snapshotting. | ## P0: Operational Visibility and Resource Predictability These are the highest-priority public follow-ups because they affect operators running larger graphs or higher sync volume. No currently tracked P0 rows remain after `graph.memory_profile()` added instance-level sizing visibility for concurrent graph-using backends. Memory limits remain per backend; use `graph.memory_profile(concurrent_backends)` for capacity planning rather than treating `graph.memory_limit_mb` as a cluster-wide hard cap. ## P1: Query Performance Follow-Ups These items are expected to improve latency or memory pressure, but they are not changes to the public SQL contract. | ID | Issue | Status | Notes | |---|---|---|---| | KI-005 | Overlay neighbor merging and transaction-delta lookups still have optimization opportunities in traversal hot paths. | Measure before optimizing | Duplicated here because it is an internal construction item with user-visible latency implications on dirty mutable projections. | ## P2: SQL Ergonomics and Documented Semantics These items clarify behavior or broaden the API. They are planned, but should not block use of the current documented SQL surface. | ID | Issue | Status | Notes | |---|---|---|---| | KI-006 | `graph.cypher()` is a narrow openCypher compatibility preview over pgGraph's supported GQL subset, not full openCypher compatibility. | Documented limitation | Keep compatibility rows honest and route broader openCypher expansion through [Roadmap](./roadmap), not this register. | | KI-007 | SQL/PGQ remains an internal adapter seam, not a public SQL API. | Deferred public surface | Track public SQL/PGQ exposure in [Roadmap](./roadmap) after PostgreSQL graph-pattern hooks stabilize. | ## P3: Internals and Maintainability | ID | Issue | Status | Notes | |---|---|---|---| | KI-008 | Several implementation and test files exceed 1,000 lines, making review and focused weak-path testing harder. | Planned refactor | Highest-priority split candidates are `graph/src/pg_tests/gql.rs`, `graph/src/sql_facade/gql.rs`, `graph/src/query/tests.rs`, `graph/src/engine.rs`, `graph/src/query/semantics.rs`, `graph/src/query/value.rs`, `graph/src/bfs.rs`, and `graph/src/gql/parser.rs`. | | KI-009 | GQL write weak-path tests can be expanded for more SQLSTATE and rollback scenarios. | Partially hardened | Pgrx coverage now asserts readonly mapped `SET` reports `PG018` and keeps a mapped `SET` type-mismatch source-row preservation guard. Transaction lifecycle scripts still cover mapped `CREATE`, `SET`, and `DELETE` rollback. Additional weak paths should be added close to the code they constrain. | | KI-010 | `nixpkgs` and `rust-overlay` lock inputs are stale in environments where `nix` is unavailable. | Deferred tooling refresh | The dependency checker reports these lock inputs, but refreshing them requires a Nix-capable environment to run `nix flake lock --update-input nixpkgs` and `nix flake lock --update-input rust-overlay`, then verify the development shell still exposes the expected Rust, PostgreSQL, and pgrx tooling. | ## Roadmap-Owned Future Work Do not use this known-issues register for broad feature wishes that are not current limitations. Track these in [Roadmap](./roadmap) instead: - broader GQL syntax and multi-pattern planning; - relationship source-row hydration, relationship property projection, and optional path-variable projection semantics; - a dedicated many-to-many relationship registration helper if post-fix user reports show `graph.add_edge()` remains too easy to misuse; - public SQL/PGQ exposure; - broader openCypher compatibility; - semantic-guided search and pgVector ranking; - WAL-driven sync; - COPY build scanning; - additional graph analytics; - distributed graph execution. ## Lower-Priority Optimizations These are intentionally deferred until measurement shows they matter: - Avoiding small string allocations in config parsing and UUID parsing. - Replacing bitmap serialized-size estimates with native roaring helpers if the pinned crate exposes them. - Reducing low-level clone counts in builder, traversal, weighted path, and aggregation paths. - Combining duplicate path reconstruction passes after the larger traversal allocation work is complete. - Cleaning up long internal function signatures when the surrounding traversal parameters stabilize. - Replacing manual pointer alignment checks with newer standard-library helpers once the supported Rust version makes that clean. - Cleaning up padding-bit handling in `active_count()`. - Moving from custom parse helpers to `FromStr` for SQL-facing enums. - Introducing production newtypes for node indices and edge type IDs after benchmarking the hot paths.