Running Apache AGE: Docker Quickstart and Cloud Postgres Provider Landscape
Apache AGE is a community Postgres extension, and that means there’s no guarantee it will be available for your favorite Postgres provider. In practice, the picture is uneven: some cloud providers ship AGE as an allow-listed extension, others don’t, and a few are pointing customers at unrelated alternatives entirely.
This post maps out where AGE actually runs today, walks through a local Docker setup, and gives you enough to decide where to deploy it in production.
This is part 2 of a 4-post series on Apache AGE. Part 1 covered AGE’s internals, AgType, and how it compares to other graph databases. The next two posts cover loading data and visual exploration with gdotv.
Cloud Postgres support at a glance
| Provider | AGE support | Notes |
|---|---|---|
| Self-hosted Postgres | ✅ Full | Build the extension from source or use the official apache/age Docker image |
| Azure Database for PostgreSQL | ✅ Available | Allow-listed extension; docs here |
| Azure HorizonDB | ✅ Available (preview) | In public preview at time of writing; access is gated and requires approval from Azure |
| EnterpriseDB (EDB) | ✅ Available | Shipped as a maintained extension; docs here |
| AWS RDS for PostgreSQL | ❌ Not available | AGE is not in the supported extensions list |
| Amazon Aurora PostgreSQL | ❌ Not available | Same situation as RDS |
| Google Cloud SQL for PostgreSQL | ❌ Not available | AGE is not in the allow-list |
| Supabase | ❌ Pointing elsewhere | Recommends pgRouting for graph workloads, per their blog |
| Snowflake | 🟡 Direction signaled | Native graph capabilities have been discussed publicly; nothing GA as of writing |
Cloud extension lists move. If you’re making a deployment decision off this table, double-check each row against the provider’s current docs at the time you read this.
Local quickstart with Docker
The fastest path to a working AGE environment is the official apache/age Docker image. It ships a Postgres server with the extension pre-installed and configured.
docker run -d \
--name age-postgres \
-p 5432:5432 \
-e POSTGRES_PASSWORD=password \
apache/age:latest
Once the container is up, connect with psql (or any Postgres client):
psql -h localhost -U postgres
Then enable the extension and create a graph:
CREATE EXTENSION IF NOT EXISTS age;
LOAD 'age';
SET search_path = ag_catalog, "$user", public;
SELECT create_graph('demo');
A few things worth knowing about that incantation:
CREATE EXTENSIONonly needs to run once per database. Subsequent connections to the same database don’t need it.LOAD 'age'and thesearch_pathchange are per-session. Some client libraries run them automatically on connect; if yours doesn’t, you’ll need to run them yourself before any Cypher queries work.create_graph(...)is itself just a regular SQL function call. There’s nothing graph-specific about how you invoke it.
A note on Postgres version coverage: the apache/age Docker image historically tracks specific Postgres major versions, and there’s typically a lag between a new Postgres release and the matching AGE build. If you want a specific Postgres version, check the tags on Docker Hub and pick the one that matches your target. For greenfield local setups, latest is the easiest start.
If you need a Postgres version newer than what the apache/age images cover, you can build AGE from source against your Postgres of choice. The AGE GitHub repository publishes release branches per Postgres major version (PG16, PG17, etc.), and the build is a fairly standard make install against your Postgres dev headers.
Azure Database for PostgreSQL
Azure was seemingly the first major cloud provider to ship AGE on its managed Postgres, and it’s currently the most polished cloud experience for AGE. It’s also fully compatible with Azure Entra ID authentication.
Enabling AGE on an Azure Postgres instance is a fully documented, two-step process:
- Allow-list the extension in the server parameters. Set the
azure.extensionsserver parameter to includeAGE(along with anything else you need). This requires a server restart to take effect. - Create the extension in the database where you want to use it:
CREATE EXTENSION age;
After that, the same LOAD 'age', SET search_path = ..., and create_graph(...) flow works as it does locally.
For authentication, Azure Postgres supports both traditional username/password and Microsoft Entra ID (formerly Azure AD). Entra ID gives you central identity management, no long-lived passwords, and the ability to gate access to AGE the same way you gate access to other Azure resources. It’s the recommended path for production.
When using gdotv with Azure-hosted AGE, Entra ID is a first-class authentication option in the connection setup, so you don’t have to wire up the az login and token-fetching path yourself.
Azure HorizonDB
HorizonDB is Azure’s newer next-generation Postgres-compatible database, designed for higher scale and broader workload coverage than the standard Azure Postgres offering. It supports the same allow-listed extension model, and AGE is among the supported extensions.
At the time of writing, HorizonDB is in public preview and access is gated: you have to request and be granted access from Azure before you can provision an instance. That’s worth knowing if you’re planning a deployment off the back of this post, since “spin one up to try AGE on it” isn’t a flow that’s open to everyone yet. Check the current availability status before assuming you can deploy on it.
The practical implications for AGE users on HorizonDB (once you do have access) are largely the same as on the standard Azure Postgres offering. The differences sit at the infrastructure layer (storage, scaling, pricing) and don’t change how you write your graph queries.
If you’re picking between HorizonDB and the standard Azure Postgres product, the decision is mostly about your broader Postgres workload profile rather than anything AGE-specific. Verify exact AGE version coverage on HorizonDB at the time of deployment, since the offering is still relatively new and the supported versions evolve.
EnterpriseDB
EnterpriseDB (EDB) ships Apache AGE as one of the actively maintained extensions in their distribution. The EDB pg_extensions catalog entry for AGE covers installation, configuration, and version coverage, and is a useful reference even outside an EDB context if you want a curated, vendor-maintained view of the extension.
For teams already running EDB Postgres or using EDB’s managed cloud offerings, AGE is available as a first-class extension rather than something you have to build and package yourself. The runtime experience once it’s installed mirrors any other AGE deployment: CREATE EXTENSION age;, the per-session LOAD 'age' and search_path setup, and create_graph(...) to start.
AWS RDS and Aurora: not yet
If your stack runs on AWS, the news is less good. Apache AGE is not currently in the supported extensions list for either RDS PostgreSQL or Aurora PostgreSQL. AWS curates the extension allow-list for both products, and AGE has not (as of writing) made the cut.
There’s no strong signal one way or the other on whether that’s likely to change. AWS adds new extensions to the supported list periodically, and AGE has a non-trivial enterprise user base, so it’s plausible that support will arrive eventually. But there’s no public roadmap commitment to point at.
In the meantime, your options on AWS are:
- Self-host Postgres + AGE on EC2 or EKS. You give up the managed-database conveniences (automated backups, point-in-time recovery, managed failover) but gain full control over the extension stack. For workloads where AGE is the primary database, this is the standard path.
- Wait for managed support, while running other parts of your application on AWS.
- Use a different cloud for the AGE workload, treating Azure Postgres as a graph-specific backing store and integrating it with your AWS-hosted services over the network. This adds latency and operational complexity, but it can be a pragmatic interim path.
Google Cloud SQL: similar story
Google Cloud SQL for PostgreSQL also doesn’t currently include AGE in its allow-listed extensions. The same options apply: self-host on GCE/GKE, wait for managed support, or run the AGE workload elsewhere and integrate over the network. As with AWS, there’s no public signal indicating an imminent change.
However, Google Cloud offers two graph database products of its own, namely Spanner Graph and BigQuery Graph, and they’re well worth checking out.
Snowflake: graph on the roadmap, not via AGE
Snowflake is not Postgres, so it’s not strictly a peer of the providers above, but it’s worth mentioning because customers evaluating “where can I do graph workloads in my data warehouse” sometimes end up comparing AGE on Postgres against native graph features in their analytics platform.
Snowflake has publicly discussed graph capabilities as part of its broader data platform strategy, and there’s been movement in that direction, but as of writing nothing graph-specific is generally available, and the path forward isn’t via AGE specifically (Snowflake isn’t a Postgres-compatible product). Verify the current state of Snowflake’s graph offering at the time you read this.
Supabase’s alternative: pgRouting
Supabase is a Postgres-as-a-service provider that doesn’t include AGE in its extension set. Instead, when graph-shaped questions come up, the Supabase team has publicly recommended pgRouting as a graph-adjacent option for their users.
It’s worth being clear about what pgRouting is and isn’t:
- What it is: a Postgres extension focused on geospatial routing (shortest paths, vehicle routing, contraction hierarchies) over data stored in regular relational tables. It’s mature, widely deployed, and very good at what it does.
- What it isn’t: a property-graph database. It doesn’t speak Cypher, it doesn’t have a label-per-table model with AgType-style flexible properties, and it’s not a general-purpose graph engine. It expects your graph to be a set of edges with weights, and the algorithms it provides are routing-shaped.
If your graph workload is genuinely about routing (you have nodes, edges, distances, and you want shortest paths or coverage trees), pgRouting is a credible answer. If your workload is property-graph shaped (you want labels, properties on both nodes and edges, ad-hoc Cypher pattern queries), pgRouting won’t fit, and AGE on a different provider is the more natural choice.
Picking a deployment
A short decision tree based on the above:
- You’re already on Azure Postgres: AGE is a server-parameter flip away. This is the smoothest hyperscaler-managed path today.
- You’re using EDB Postgres or EDB’s managed cloud: AGE is a supported, vendor-maintained extension. Same
CREATE EXTENSIONflow as anywhere else. - You’re already on AWS or GCP: self-host Postgres + AGE on compute (EC2/GCE or EKS/GKE) for full control, or wait for managed support to arrive. Don’t expect either RDS, Aurora, or Cloud SQL to surface AGE in the near term.
- You’re on Supabase: AGE isn’t on the menu. Either move the graph workload to a different host or evaluate whether pgRouting actually covers your use case.
- You’re greenfield: start with the local
apache/ageDocker container while you prototype, then make the cloud decision once you understand your graph’s size and traffic profile. - You’re picking between standard Azure Postgres and HorizonDB: decide based on your broader Postgres needs (scale, workload mix, pricing). Both support AGE; the difference is everywhere else.
For most teams, the practical answer today is: prototype locally, then deploy to whichever cloud Postgres your organization is already on, and accept self-hosting as the path of last resort if your provider doesn’t support AGE.
Where this fits in the series
- Part 1: Apache AGE Explained: how does it work and how does it fit in the Graph Database Landscape?. Background reading on what AGE is, how it stores graphs, and how it compares to popular alternatives.
- Part 3: Loading Data into Apache AGE: A Practical Guide with the Air Routes Dataset. Now that you have AGE running, the next post walks through loading data with
agload, AGE’s built-in CSV loader, using the air routes dataset as a worked example. - Part 4: Visualizing Apache AGE: Connecting gdotv and Exploring the Air Routes Graph. Connecting gdotv to your AGE instance and exploring the loaded graph: schema discovery, Cypher editor, graph visualization, neighbor expansion.