# Apache AGE Feature Request Prioritization

**Date:** 2026-02-27
**Source:** `apache/age` GitHub issue tracker
**Purpose:** Identify highest-impact feature contributions alongside bug fixes

---

## Methodology

Searched all open issues on `apache/age` for enhancements, feature requests, and
community-demanded improvements. Ranked by: community signal (thumbs-up reactions,
comment count), openCypher spec compliance impact, Piggie SDK alignment, and
estimated contributor feasibility.

---

## Tier 1: High Impact, High Feasibility — Work on These Next

### 1. MERGE ON CREATE SET / ON MATCH SET (Issue #1619)

- **Reactions:** 7 thumbs-up | **Comments:** 1
- **Status:** WE ARE ALREADY WORKING ON THIS (paused due to branch issue)
- **openCypher spec:** Yes, standard clause. Documented gap in #2323.
- **Complexity:** Medium-high. Touches grammar (Cypher.y), transform layer,
  executor. Grammar and keyword changes done; 8 more files remain.
- **Piggie SDK relevance:** Critical. MERGE ON CREATE/MATCH SET is bread-and-butter
  for any graph ETL pipeline. Every SDK user will hit this gap.
- **Competition:** Neo4j has it. Kuzu has it. AGE is the outlier.
- **Linked PRs:** None (we are the only contributor working on this).

### 2. Predicate Functions: all(), any(), none(), single() (Issues #552, #553, #555, #556)

- **Reactions:** 0 | **Comments:** 1 each
- **Status:** Open since 2022. No PRs submitted. Tagged `feature request`.
- **openCypher spec:** Yes, standard predicate functions.
- **Complexity:** Medium. Each is a new function in `cypher_funcs.c` plus grammar
  additions for the `WHERE` clause inside the predicate. Similar pattern for all four
  -- implement one and the others follow the same template.
- **Piggie SDK relevance:** High. List predicate operations are essential for graph
  traversal filtering. Any data science workflow over paths or collections needs these.
- **Implementation note:** These share a parent tracking issue (#551). Pattern:
  `all(x IN list WHERE predicate)`. Requires grammar support for the
  `variable IN expression WHERE expression` sub-clause.

### 3. Pattern Matching in WHERE Clause (Issue #1577)

- **Reactions:** 1 thumbs-up | **Comments:** 1
- **Status:** Open since 2024. No PR. Linked to #1607 (pattern matching in RETURN).
- **openCypher spec:** Yes, standard feature. Documented gap in #2323 (the
  `NOT (pattern)` form specifically).
- **Complexity:** Medium. Requires grammar changes to allow pattern expressions in
  WHERE position. The transform layer needs to compile patterns into subquery-style
  existence checks.
- **Piggie SDK relevance:** High. `WHERE (a)-[:KNOWS]->(b)` and
  `WHERE NOT (a)-[:OWNS]->(:Asset)` are standard filtering patterns in every Cypher
  tutorial. Users migrating from Neo4j will hit this immediately.

### 4. CALL Subquery (Issue #1690)

- **Reactions:** 1 thumbs-up | **Comments:** 5
- **Status:** Open since 2024. No PR.
- **openCypher spec:** Yes, standard clause (CIP2021-01-18).
- **Complexity:** High. Requires new clause type in grammar, new executor node, scoping
  rules for variables flowing in/out of the subquery. This is a significant
  architectural addition but well-defined by the spec.
- **Piggie SDK relevance:** Very high. CALL {} is the standard mechanism for
  post-UNION processing, batched updates, and complex multi-step operations. Critical
  for any production ETL pipeline. Enables patterns like
  `CALL { MATCH ... RETURN ... UNION MATCH ... RETURN ... }`.

### 5. Unique Properties / Constraints / Indexing (Issue #45)

- **Reactions:** 7 thumbs-up, 1 heart, 1 rocket | **Comments:** 25
- **Status:** Open since 2021. Oldest open enhancement. Some early PRs attempted
  (#227) but nothing landed. Latest comments (2023) discuss property-specific indexes
  still not working properly beyond GIN indexes.
- **openCypher spec:** Standard feature (CREATE CONSTRAINT).
- **Complexity:** High. Touches catalog system, DDL processing, constraint enforcement
  during CREATE/MERGE. Would need to bridge Cypher DDL to PostgreSQL constraint
  mechanisms on the underlying label tables.
- **Piggie SDK relevance:** Critical. Without unique constraints, MERGE operations
  cannot guarantee idempotency at the database level. Every production graph needs
  this. This is one of the top reasons people avoid AGE for serious workloads.

---

## Tier 2: Strategic — Serves the Piggie Graph+Vector Vision

### 6. pgvector Integration (Issue #1121)

- **Reactions:** 29 thumbs-up, 6 rockets | **Comments:** 36
- **Status:** Most-upvoted feature request after RDS support. Active discussion through
  Jan 2026. User `webcoderz` published `age_search` pip package with working
  AGE+pgvector+pg_search bridge. Maintainer `jrgemignani` is engaged.
- **Complexity:** Very high for native integration (new agtype operators, vector
  functions in Cypher, index planner hints). Medium for SQL-bridge approach
  (wrapper functions that convert agtype properties to vector type).
- **Piggie SDK relevance:** THIS IS THE CORE DIFFERENTIATOR. The entire Piggie value
  proposition is graph+vector in one PostgreSQL instance. Even if native Cypher-level
  vector ops take time, contributing SQL bridge functions and documenting patterns
  advances the SDK story immediately.
- **Approach:** Start with utility functions (agtype property to vector cast,
  vector similarity as a Cypher-callable function), then propose deeper integration.
  The `age_search` package shows the SQL-level patterns work today.

### 7. LlamaIndex / LangChain Graph Store Integration (Issue #1783)

- **Reactions:** 8 thumbs-up | **Comments:** 14 (with +1s through July 2025)
- **Status:** Open since 2024. Community keeps bumping it. LlamaIndex has a graph
  store interface template. Nobody has implemented it for AGE.
- **Complexity:** Medium. This is a Python library contribution (to LlamaIndex), not
  an AGE core change. Requires implementing the `GraphStore` interface using AGE's
  Python driver.
- **Piggie SDK relevance:** Very high. A LlamaIndex graph store adapter for AGE
  would be the single most impactful thing for AI/RAG adoption. This is exactly the
  kind of integration the Piggie Python SDK should provide. We could contribute this
  upstream to LlamaIndex AND include it in the Piggie SDK.
- **Note:** This doesn't require any AGE core changes, just Python SDK work.

### 8. Multiple Labels (PR #2082)

- **Status:** Open PR by `rafsun42` with 8 comments. Single review comment: "Looks
  good to me otherwise." From MuhammadTahaNaveed (AGE maintainer).
- **openCypher spec:** Yes, standard feature. `CREATE (n:Person:Employee)`.
- **Complexity:** High. PR already exists and touches CREATE, MERGE, MATCH. Changes
  how vertex/edge objects are output. Needs rebase.
- **Piggie SDK relevance:** High. Multi-label is fundamental to real-world graph
  modeling. Every domain model (legal entities, org structures, compliance mappings)
  uses multiple labels.
- **Opportunity:** This PR needs a champion to push it through review. Could offer to
  help rebase and address review feedback rather than starting from scratch.

---

## Tier 3: Important Infrastructure — Enables Scale Adoption

### 9. Performance: Edge Creation at Scale (Issue #2198)

- **Reactions:** 0 | **Comments:** 23
- **Status:** Very active discussion (Jan 2026). Users hitting severe performance
  degradation after 200K edges. Maintainer `jrgemignani` engaged, pointing to
  `agefreighter` tool. Core issue is that Cypher-based batch inserts don't use
  efficient bulk loading paths.
- **Complexity:** Medium-high. Could involve optimizing the MERGE/CREATE executor
  for batch operations, or improving the load_from_file functions.
- **Piggie SDK relevance:** Critical for production use. The SDK needs to provide
  efficient bulk loading. If AGE core doesn't handle it, the SDK needs to provide
  optimized loading utilities (like agefreighter does).
- **Related:** #2177 (MERGE upsert performance at 10K+ edges), #2194 (SQL vs Cypher
  aggregation performance — 3s vs 50s for same query).

### 10. SQL vs Cypher Performance Gap (Issue #2194)

- **Reactions:** 1 thumbs-up | **Comments:** 20
- **Status:** Active investigation by `jrgemignani`. Root cause identified: hash
  joins in AGE don't use indexes well. The query planner doesn't optimize Cypher
  queries the same way it optimizes equivalent SQL.
- **Complexity:** Very high. Touches the query planner/optimizer interface between
  Cypher and PostgreSQL. This is deep PostgreSQL internals work.
- **Piggie SDK relevance:** High. If Cypher queries are 15-50x slower than equivalent
  SQL, users will bypass Cypher. The SDK needs both fast Cypher and fast SQL paths.
- **Note:** PRs #2287 (GROUP BY/ORDER BY optimization) and #2295 (id()/start_id()
  optimization) and #2303 (composite types) from `jrgemignani` and
  `MuhammadTahaNaveed` are actively addressing this. These are being worked by
  maintainers, but reviewing/testing them accelerates the merge.

### 11. Bulk Data Loading via Client Connection (Issue #432)

- **Reactions:** 4 thumbs-up | **Comments:** 4
- **Status:** Open since 2022. No PR. The load_from_file functions require
  server-side file access, which is impractical for cloud/managed deployments.
- **Complexity:** Medium. Could be implemented as enhanced SQL functions that accept
  data via parameter, or as a protocol-level COPY integration.
- **Piggie SDK relevance:** Critical. Every SDK needs bulk import. If the server-side
  functions can't be enhanced, the SDK layer must provide a client-side bulk loader
  (which is what `agefreighter` does, but it should be first-class).
- **Related:** #2312 (overwrite support for load_labels_from_file).

### 12. agtype to JSONB Conversion (Issue #350)

- **Reactions:** 1 thumbs-up | **Comments:** 3
- **Status:** Open since 2022. No PR. Also related to #282 (JSONB operators for
  agtype).
- **Complexity:** Low-medium. agtype is already based on JSONB internally. Exposing
  clean cast functions is straightforward.
- **Piggie SDK relevance:** High. This is a constant pain point for anyone mixing
  Cypher results with SQL queries. The SDK needs to bridge graph results into
  standard PostgreSQL types for downstream processing. A clean `agtype::jsonb` cast
  would simplify every driver.

---

## Tier 4: Nice to Have / Lower Feasibility

### 13. Convert Existing Postgres Tables to Graph (Issue #363)

- **Reactions:** 9 thumbs-up | **Comments:** 1
- **Status:** Open since 2022. No PR. High community demand signal.
- **Complexity:** High. Would need to map relational schemas to graph schemas, create
  label tables from existing tables, handle foreign keys as edges.
- **Piggie SDK relevance:** Very high for migration stories. A "relational-to-graph"
  migration tool would be a killer SDK feature. This is more naturally a SDK/tooling
  contribution than an AGE core change.

### 14. SET/REMOVE Label Operations (Issues #464, #717)

- **Reactions:** 3 thumbs-up (#464), 1 (#717) | **Comments:** 7 + 4
- **Status:** Open since 2022-2023. No PRs. Linked to multi-label (#2082).
- **openCypher spec:** Yes, `SET n:NewLabel` and `REMOVE n:Label` are standard.
- **Complexity:** Medium. Depends on multi-label (#2082) landing first. Once
  multi-label exists, SET/REMOVE become modifications to the label set on existing
  vertices/edges.
- **Piggie SDK relevance:** Medium. Useful for dynamic graph evolution but not
  blocking core workflows.

### 15. datetime() Function (Issue #2323)

- **Reactions:** 1 thumbs-up (on #2323 which bundled this)
- **Status:** Documented as missing in the openCypher compatibility audit (#2323).
  No standalone issue.
- **openCypher spec:** Yes, standard temporal function (CIP2015-08-06).
- **Complexity:** Low-medium. AGE already has `timestamp()`. Adding `datetime()`,
  `date()`, `time()`, `duration()` and temporal arithmetic is additive function work.
- **Piggie SDK relevance:** Medium. Temporal operations matter for time-series graph
  patterns. Workaround exists (pass timestamps as parameters from application layer).

---

## Summary Matrix

| Rank | Issue(s) | Feature | Reactions | Spec Gap? | Complexity | SDK Relevance | Status |
|------|----------|---------|-----------|-----------|------------|---------------|--------|
| 1 | #1619 | MERGE ON CREATE/MATCH SET | 7 | Yes | Med-High | Critical | WE OWN THIS |
| 2 | #552-556 | Predicate functions (all/any/none/single) | 0 | Yes | Medium | High | No PR, no owner |
| 3 | #1577 | Pattern matching in WHERE | 1 | Yes | Medium | High | No PR, no owner |
| 4 | #1690 | CALL subquery | 1 | Yes | High | Very High | No PR, no owner |
| 5 | #45 | Unique constraints / indexing | 9 | Yes | High | Critical | Stalled since 2023 |
| 6 | #1121 | pgvector integration | 35 | N/A | Very High | Core Differentiator | Discussion only |
| 7 | #1783 | LlamaIndex graph store | 8 | N/A | Medium | Very High | No implementor |
| 8 | #2082 | Multiple labels | N/A | Yes | High (PR exists) | High | PR needs champion |
| 9 | #2198 | Bulk edge creation perf | 0 | N/A | Med-High | Critical | Active discussion |
| 10 | #2194 | SQL vs Cypher perf gap | 1 | N/A | Very High | High | Maintainers working |
| 11 | #432 | Bulk load via client conn | 4 | N/A | Medium | Critical | No PR |
| 12 | #350 | agtype to JSONB cast | 1 | N/A | Low-Med | High | No PR |
| 13 | #363 | Relational-to-graph conversion | 9 | N/A | High | Very High | No PR |
| 14 | #464,#717 | SET/REMOVE label | 4 | Yes | Med (needs #2082) | Medium | Blocked on multi-label |
| 15 | N/A | datetime() function | 1 | Yes | Low-Med | Medium | Not filed standalone |

---

## Recommended Sequencing

### Immediate (finish what we started)
1. **MERGE ON CREATE/MATCH SET (#1619)** -- unpause and complete

### Next sprint (openCypher spec compliance batch)
2. **Predicate functions (#552-556)** -- four functions, one pattern, high spec compliance value
3. **Pattern matching in WHERE (#1577)** -- completes a common Neo4j migration pain point

### Parallel SDK work (no AGE core changes needed)
4. **LlamaIndex graph store (#1783)** -- Python SDK contribution to LlamaIndex
5. **pgvector bridge functions** -- SQL-level utility functions for #1121

### Medium-term AGE core
6. **agtype to JSONB cast (#350)** -- small, high-leverage
7. **datetime() function** -- small, spec compliance
8. **CALL subquery (#1690)** -- large but architecturally important

### Help push existing PRs
9. **Multiple labels (#2082)** -- help rebase and champion
10. **Review performance PRs (#2287, #2295, #2303)** -- test and provide feedback

---

## Active PRs by Maintainers to Track

These are being worked by `jrgemignani` and `MuhammadTahaNaveed` and represent the
project's current performance improvement direction:

- **PR #2295** -- Optimize id()/start_id()/end_id() with direct column access
- **PR #2287** -- Add GROUP BY and ORDER BY optimization
- **PR #2303** -- Add vertex/edge composite types (major performance refactor)
- **PR #2277** -- Merge PG18 into master branch

Testing and reviewing these PRs is good community citizenship and keeps us aligned
with where the maintainers are taking the project.

---

## Issues NOT Worth Pursuing

- **#998 (Amazon RDS support)** -- 97 thumbs-up but this is an AWS decision, not a code contribution
- **#290 (GraphQL support)** -- 48 comments but stalled since 2023, scope is enormous
- **#431 (Gremlin support)** -- nice idea but orthogonal to our focus
- **#370 (Ruby driver)** -- not our language focus
- **#2327 (RDF/SPARQL)** -- different graph model entirely, massive scope
- **#54 (Citus compatibility)** -- interesting but not actionable for us now
