PostgreSQL RPM repository reduces EPEL dependency on RHEL
Devrim Gündüz, maintainer of the official PostgreSQL RPM repository, removed most of the EPEL dependencies in RHEL 8, 9, and 10. PostGIS, pgBackRest, patroni, and dozens of Python tools now install using only PGDG and RHEL's own repositories.

For years, installing much of the official PostgreSQL RPM repository's packages on RHEL (and its rebuilds, such as Rocky Linux and AlmaLinux) started with dnf install epel-release. PostGIS, pgBackRest, pgcli, patroni, pg_statviz, ora2pg, and dozens of extensions pulled in at least one EPEL dependency.
According to a report by Devrim Gündüz, maintainer of the PostgreSQL RPM repository (PGDG), published on Planet PostgreSQL, this changed over the past few weeks. In RHEL 8, 9, and 10, the GIS stack, the most popular extensions, and nearly all of the project's Python tools now install using only the PGDG repositories and the operating system's own repositories (BaseOS, AppStream, and CRB).
For those who administer databases in enterprise environments, this is an infrastructure change, not a feature change: fewer points of failure, fewer corporate firewall exceptions to open, and a more predictable upgrade path.
Why EPEL became a problem
EPEL (Extra Packages for Enterprise Linux) is maintained by the Fedora community and remains a solid project. The problem, according to Gündüz, is not EPEL's quality, but the structural dependency it created in PostgreSQL's packaging:
EPEL is a great project, and this is not a complaint about it. But relying on it caused us real problems.
Devrim Gündüz, maintainer of the PostgreSQL RPM repository
The friction points listed in the post are specific to those who operate databases in production:
- Blocked access: many companies only allow the operating system vendor's repository plus PGDG, and do not authorize enabling EPEL due to internal policy.
- Mismatched lifecycles: EPEL packages are updated, rebuilt with new sonames, or discontinued on EPEL's own schedule, which broke PGDG packages without any change on PostgreSQL's side.
- Old versions with known CVEs: EPEL 8 and 9 distribute
hdf5versions 1.10 and 1.12, Apache Arrow 8 and 9, and netCDF 4.7 and 4.8, all behind upstream. - EPEL 10 by minor release: EPEL 10 follows RHEL 10's minor releases (10.2, 10.3...), which makes it harder to know which EPEL package the user is actually getting.
What changed: GIS, extensions, and Python tools
The largest share of the work was in the geospatial stack. GDAL depended on more than 20 EPEL libraries: hdf4, hdf5, netCDF, cfitsio, freexl, Apache Arrow, libkml, xerces-c, armadillo, libdeflate, GPSBabel, and others. All of them are now packaged by PGDG itself, in more recent upstream versions than the ones EPEL distributed, including Apache Arrow 26, which brought the Parquet driver for GDAL as a bonus.
No GDAL driver was removed in this process, which the post highlights as a contrast with a recent change in RHEL itself. PostGIS versions 3.3 through 3.7, SFCGAL (now compiled against PGDG's own CGAL packages), osm2pgsql, and pointcloud no longer need EPEL on any supported version of RHEL.
Outside of GIS, the list of changes is extensive:
pgBackRestnow useslibssh2packaged by PGDG itself (with Fedora's CVE patches), keeping SFTP repositories working without EPEL.pgsodiumandpg_pwhashuse their ownlibsodium,libargon2, andlibscrypt; as a side effect,pgsodium'sipcryptfunctions now also work on RHEL 8 and 9, andpg_pwhashgainsscryptsupport on RHEL 10.mongo_fdwandpostgresbsonusemongo-c-driver1.30 compiled by the repository itself.pg_topandpgmonetano longer depend onlibbsdandcJSON.
Python was, according to Gündüz himself, the most laborious part. On RHEL 8, pgcli, patroni, and other Python tools now run on a Python 3.12 stack built entirely by PGDG. On RHEL 9, the pgcli stack, the typing-extensions used by psycopg 3, and pillow (compiled against its own libimagequant) leave EPEL. On RHEL 10, around 35 Python modules, from boto3 and pydantic to matplotlib and pandas, are now maintained by PGDG, covering pg_statviz, patroni, barman, pgcli, pg_activity, pgldapsync, pghoard, rohmu, and sshtunnel.
How coexistence with EPEL was solved technically
Most of the new libraries are installed under their own prefix, such as /usr/pgdg-hdf5 or /usr/pgdg-libarrow. PGDG packages find these libraries via rpath, without using files in ld.so.conf.d and without appearing in the RPM's provides. In practice, this means the two worlds do not collide: anyone who keeps EPEL enabled continues using EPEL's libraries for whatever they installed from there, while PGDG packages use their own.
On RHEL 10 the solution is different, because a Python module can only exist once in the system. PGDG's python3.12- packages obsolete the equivalent python3- packages from EPEL, and their release numbers start at 42, so that a regular dnf upgrade with both repositories enabled migrates the system to PGDG's packages automatically.
There are two documented caveats worth noting before running the upgrade in production:
python3-snappygoes from EPEL's version 0.7.2 to PGDG's 0.6.1, because PGDG's package carries a higher Epoch, which in RPM takes precedence over the version number.- EPEL packages also obsolete PGDG's equivalent names, up to EPEL's own version; PGDG keeps its RHEL 10 versions always equal to or above EPEL's precisely so that an EPEL update doesn't reverse the choice.
CRB (PowerTools in earlier RHEL versions) is still required as before; this part hasn't changed.
What still depends on EPEL
Not everything left EPEL, and the author's own list is straightforward about why: either the dependency is a project too large to repackage, or it's EPEL-only by nature.
| PGDG package | Depends on | Note |
|---|---|---|
| check_patroni, check_pgactivity, check_pgbackrest | nagios-plugins | Nagios monitoring |
| plr, dbt2, dbttools | R | statistical language |
| firebird_fdw, libfq | Firebird | Firebird database |
| tds_fdw, pgloader | FreeTDS | connectivity with SQL Server/Sybase |
| pg_snakeoil | ClamAV | antivirus |
| pgbadger | perl-Text-CSV_XS | log analysis |
| postgresql_autodoc | perl-HTML-Template | automatic documentation |
| pgpool-II, pgmemcache (RHEL 10) | libmemcached-awesome | distributed cache |
| pgcopydb (RHEL 10) | gc | C garbage collector |
| pgmodeler (RHEL 9) | Qt 6 | visual modeling |
Anyone who depends on one of these packages and wants to see it migrate out of EPEL can file the request in the pgdg-packaging/pgdg-rpms repository on GitHub; Gündüz himself asks for feedback there, and the full work is documented in issue 422 of the same repository.
What changes for those running PostgreSQL on production RHEL
This change doesn't alter any PostgreSQL functionality itself, but it reduces the external dependency surface of a stack that, in enterprise environments, usually goes through case-by-case security approval. Three practical effects are worth noting:
- Less third-party approval: companies that only allow the vendor's repository and PGDG no longer need to negotiate EPEL's approval to install PostGIS, pgBackRest, or Patroni.
- Less risk of breakage from someone else's lifecycle: since the support libraries now follow PGDG's own release schedule, an EPEL update no longer breaks a PostgreSQL extension out of the blue.
- Attention to the upgrade on RHEL 10: since PGDG's Python packages replace EPEL's via obsoletes, it's worth reviewing provisioning scripts that pin an exact Python package version (such as the
python3-snappycase) before running a massdnf upgrade.
The angle that remains open concerns those who operate packages not covered by the list above: Firebird, FreeTDS, R, and Qt still pull in EPEL, so a dnf install epel-release remains routine in specific database integration scenarios. For the rest of the more common stack, the external dependency has become the exception, not the rule.
Translated from the Brazilian Portuguese original · Read the original
PostgreSQL 16's reserved_connections guarantees a connection for monitoring and backup when the application exhausts the pool
Released in PostgreSQL 16, in 2023, the parameter creates a second connection reserve, separate from the superuser's, so that monitoring, backup, and DBA can still get in when the application consumes the whole pool.





