# Known Issues

<Callout type="warning">
pgGraph is currently alpha software. Do not use it for production workloads
without your own validation, backup, rollback, and load-testing plan.
</Callout>

<Callout type="info">
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.
</Callout>

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 must participate in later reads without becoming durable graph-only state. | Hardened | GQL node `CREATE`/`MERGE` now assigns backend-local temporary graph node indexes. Node-only reads, concrete traversal, multi-pattern joins, wildcard paths, and relationship `CREATE` can use those nodes within the same top-level PostgreSQL transaction. |
| 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

<Callout type="info">
No currently tracked next-update items remain in this category after dynamic
table SQL and discovery SQL parameterization work.
</Callout>

### 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.

<Callout type="info">
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.
</Callout>

## 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.
