Apache AGE: openCypher Queries Inside PostgreSQL
Graph database optimized for fast analysis and real-time data processing. It is provided as an extension to PostgreSQL.
At a glance
- What is it?
- Apache AGE adds a graph model to an existing PostgreSQL instance so the same database answers SQL and openCypher. It suits teams that already run Postgres and want graph traversal without a second database, and it is the wrong pick if you need a standalone graph engine tuned for deep traversal.
- Who is it for?
- Adopt Apache AGE if you already operate PostgreSQL 11 through 18 and want graph traversal, hybrid SQL and Cypher queries, and property indexes on vertices and edges without running a second database. Do not adopt it if you need a graph engine whose storage layer was designed for traversal rather than built as a Postgres extension, or if you are on a Postgres major version outside that list.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 11 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem AGE solves: two databases, one dataset
Most teams that need relationship traversal end up running PostgreSQL for transactions and a separate graph database for the connected parts of the same data. That means a sync job, a second set of credentials, and a consistency window where the two stores disagree. Apache AGE takes the other route: it is a PostgreSQL extension, so the graph lives in the same storage as the relational tables. The README describes the project's principle as creating "a single storage that handles both the relational and graph data model" so users can write standard ANSI SQL alongside openCypher.
The audience is narrow but real. If your data is already in Postgres, if your queries mix aggregates over tables with path lookups over relationships, and if you would rather not operate another database, AGE targets exactly that. The README lists fraud detection, master data management, product recommendations, identity and relationship management, knowledge management and experience personalization as the kinds of workloads it is aimed at. Those are all cases where relationships matter but the surrounding data is ordinary relational rows.
How AGE works: an extension, not a fork
AGE is built as a PostgreSQL extension rather than a database fork. The Makefile declares MODULE_big = age and relies on PGXS, the standard PostgreSQL extension build infrastructure. The repository ships age.control, which is the file PostgreSQL reads to know the extension exists and what version it is, plus a set of upgrade scripts in the root: age--1.6.0--1.7.0.sql, age--1.7.0--1.8.0.sql and age--1.8.0--y.y.y.sql. Those files are how an installed extension moves between versions, which is a different upgrade path from replacing a whole database binary.
Functionally, the extension adds a graph model on top of relational storage and accepts openCypher as a query language. The README's feature list names Cypher query support, hybrid querying that allows SQL and/or Cypher, querying multiple graphs, hierarchical graph label organization, and property indexes on both vertices and edges. The C source under src/ is where the query parsing and execution live; the repository also carries a regress/ directory and a REGRESS setup in the Makefile, so the project tests itself through PostgreSQL's own regression harness rather than a bespoke test runner.
The practical consequence of the extension design is that you inherit PostgreSQL's behaviour. Anything Postgres does, AGE does, because it is Postgres. The cost is the same coin: AGE's graph features are constrained by what a Postgres extension can express, and the supported server versions are pinned to the majors the project has built against.
Installing Apache AGE and running a first query
The README says AGE supports PostgreSQL 11, 12, 13, 14, 15, 16, 17 and 18, and that supporting the latest versions is on the roadmap. Check that first, because a mismatch here wastes the rest of the install. The pg_config utility reports the version of PostgreSQL you are actually building against:
pg_configBefore building, install the Linux dependencies for your distribution. The README gives these per-OS commands:
sudo apt-get install build-essential libreadline-dev zlib1g-dev flex bisonThen build and install the extension from the source directory. If Postgres is not on your PATH, the README shows passing the binary explicitly:
make installmake PG_CONFIG=/path/to/postgres/bin/pg_config installThe faster path is Docker. The README pulls the published image and starts a container with a mapped port and credentials supplied as environment variables:
docker pull apache/agedocker run \
--name age \
-p 5455:5432 \
-e POSTGRES_USER=postgresUser \
-e POSTGRES_PASSWORD=postgresPW \
-e POSTGRES_DB=postgresDB \
-d \
apache/ageNote the port mapping: the container listens on 5432 internally and is published on 5455 on the host, so a client connects to localhost:5455. After that, the README points to the Apache AGE documentation for installation details, built-in functions and Cypher query examples rather than repeating them in the repository README.
Where AGE is the wrong tool
The extension model has a hard boundary: AGE runs only on the PostgreSQL majors the project has built against. The README lists 11 through 18 and says supporting the latest versions is on the roadmap. If your platform pins you to a version outside that list, AGE is not an option until the project adds it, and you cannot work around it by installing from source.
There is a second boundary that matters more for some workloads. AGE is a graph model layered onto relational storage inside PostgreSQL. That is what makes the hybrid query possible, and it is also what makes AGE a different proposition from a database whose storage engine was designed around traversal from the start. If your workload is dominated by deep, multi-hop path exploration over a graph far larger than memory, the design premise of AGE is not the one you want, and no amount of Cypher support changes that. The README does not publish traversal benchmarks or scaling limits, so there is nothing in the repository to help you size that decision. You would have to measure it against your own data.
One more thing the README does not document: rollback. There are forward upgrade scripts in the repository root, but nothing in the README describes downgrading an installed AGE extension. Treat a version upgrade as a one-way step until you have read the upgrade SQL files yourself.
Apache AGE compared with Neo4j and other graph databases
The comparison people search for most is Apache AGE against Neo4j, and the difference is architectural rather than a matter of feature checklists. Neo4j is a standalone graph database: you run it as its own server, with its own storage, and you move data into it. AGE is an extension inside PostgreSQL, so there is no second server and no data movement, but the graph shares a process and a query planner with everything else in that Postgres instance. Which one is right depends on whether the graph is the system or a feature of the system. If relationships are one part of an application that also does ordinary relational work, AGE keeps that in one place. If the graph is the product, a dedicated engine is the more natural fit.
The same split applies to the other names that come up in searches. Dgraph, ArangoDB and Memgraph are all standalone systems with their own storage and their own operational story. None of them gives you openCypher inside an existing Postgres connection, and none of them lets a single query mix SQL aggregates with graph pattern matching the way AGE's hybrid querying does. That hybrid capability is the actual differentiator, not raw graph speed. The README makes no performance claims, and there are no benchmark numbers in the repository to compare against, so anyone citing a speed advantage in either direction is working from something other than this project.
Maintenance, releases and the Apache-2.0 licence
The repository is not archived and the last push was on 2026-09-19. Recent releases track PostgreSQL majors individually: PG15/v1.8.0-rc0 on 2026-09-19, PG18/v1.8.0-rc0 on 2026-07-09, and PG17/v1.7.0-rc0 on 2026-02-11. That naming convention is the important operational detail. Releases are cut per Postgres major version, so upgrading Postgres and upgrading AGE are two separate decisions, and you should expect to move to a different AGE release tag when you move Postgres versions. The release candidates in that list also mean the newest tags are not final releases.
Upgrade cost inside AGE itself is managed through the SQL migration files in the repository root. A jump from 1.6.0 to 1.7.0 has a corresponding age--1.6.0--1.7.0.sql, and 1.7.0 to 1.8.0 has age--1.7.0--1.8.0.sql. Reading those files tells you what a version bump actually does to your catalog. The file named age--1.8.0--y.y.y.sql is the placeholder for the next upgrade path.
AGE is licensed under Apache-2.0, and the repository carries both a LICENSE and a NOTICE file, which is the standard Apache Software Foundation arrangement. Apache-2.0 is permissive and includes a patent grant, but this is not legal advice: if you redistribute AGE inside a product, read the NOTICE file and your own counsel's guidance on attribution.
Editorial conclusion
Adopt Apache AGE if you already operate PostgreSQL 11 through 18 and want graph traversal, hybrid SQL and Cypher queries, and property indexes on vertices and edges without running a second database. Do not adopt it if you need a graph engine whose storage layer was designed for traversal rather than built as a Postgres extension, or if you are on a Postgres major version outside that list. Before committing, check pg_config output against the supported versions, read the upgrade SQL files in the repository root to see what a version jump actually changes, and confirm the driver you use appears under drivers/.
Frequently asked questions
How does Apache AGE work?
It is a PostgreSQL extension that adds a graph model on top of relational storage, so the same database handles relational tables and graph data. Queries can be written in openCypher, in SQL, or mixed in one statement.
Who uses the Apache AGE?
The README names fraud detection, master data management, product recommendations, identity and relationship management, knowledge management and experience personalization as the kinds of workloads it targets. It does not list named customers.
What query language does Apache AGE support?
The README lists Cypher query support alongside hybrid querying that allows SQL and/or Cypher. It also supports querying multiple graphs at the same time.
Is Apache AGE open source?
Yes. The repository is licensed under Apache-2.0 and carries both a LICENSE and a NOTICE file, the standard Apache Software Foundation arrangement.
Is Apache AGE free?
It is distributed under the Apache-2.0 licence, which is permissive and includes a patent grant. That is a licence fact, not legal advice for your specific use.
How do I install Apache AGE?
Either build the extension from source with make install, passing PG_CONFIG if Postgres is not on your PATH, or pull the apache/age Docker image and run a container against it. The README lists PostgreSQL 11 through 18 as supported.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/apache-age)