Question
I am trying to install the PostgreSQL pg gem for Ruby on Ubuntu after installing Ruby 1.9.2 with RVM:
gem install pg
The native extension build fails even though pg_config and PostgreSQL header files are found:
checking for pg_config... yes
checking for libpq-fe.h... yes
checking for PQconnectdb() in -lpq... no
Can't find the PostgreSQL client library (libpq)
*** extconf.rb failed ***
How can I install the required PostgreSQL client development library and successfully install the pg gem?
Short Answer
The Ruby pg gem is a native extension: it must compile C code that links Ruby to PostgreSQL's client library, libpq. You will learn how to install the required Ubuntu development package, retry the gem installation, diagnose linker errors, and configure a custom PostgreSQL location when necessary.
Concept
The pg gem lets Ruby programs connect to PostgreSQL. Unlike a pure Ruby gem, it includes native C code. During installation, Ruby runs a build script named extconf.rb, generates a Makefile, and compiles the extension.
For this to work, the system needs PostgreSQL's client development files:
- Header files, such as
libpq-fe.h, describe the C functions available. - The
libpqlibrary provides implementations of functions such asPQconnectdb(). pg_configtells the installer where PostgreSQL headers and libraries are installed.
The important part of the error is:
checking for PQconnectdb() in -lpq... no
Can't find the PostgreSQL client library (libpq)
This means the installer found some PostgreSQL-related files, but the compiler/linker could not successfully link a test program against libpq. On Ubuntu, installing libpq-dev is normally the correct fix because it supplies the files needed to compile against PostgreSQL.
Mental Model
Think of the pg gem as an interpreter who helps Ruby speak PostgreSQL's language.
- Ruby is one person.
- PostgreSQL is another person.
libpqis the shared language and communication toolkit.- The
pggem is the interpreter built using that toolkit.
Having only the PostgreSQL server or runtime library is like having a finished toolkit locked in a box. To build the interpreter, you also need the development kit: the instructions (headers) and linkable components (development library). On Ubuntu, that kit is typically installed with libpq-dev.
Syntax and Examples
Install the PostgreSQL client development package, then install the gem:
sudo apt update
sudo apt install libpq-dev build-essential
gem install pg
libpq-dev provides PostgreSQL client headers, pg_config, and the library metadata needed to compile the extension. build-essential provides standard compilation tools such as gcc and make.
If you use Bundler, add the gem to your Gemfile:
gem "pg"
Then install the application's dependencies:
bundle install
If PostgreSQL was installed in a nonstandard location, explicitly give the gem the matching pg_config executable:
gem install pg -- --with-pg-config=/custom/postgresql/bin/pg_config
For a normal Ubuntu package installation, the path is commonly /usr/bin/pg_config, so this can also be used when multiple PostgreSQL installations exist:
gem install pg -- --with-pg-config=/usr/bin/pg_config
Step by Step Execution
Consider this installation sequence:
sudo apt install libpq-dev build-essential
gem install pg
apt install libpq-devinstalls PostgreSQL client development resources, including thelibpqlibrary used by compiled clients.apt install build-essentialensures the C compiler and build tools are available.gem install pgdownloads the gem source code.- Ruby runs the gem's
extconf.rbconfiguration script. - The script uses
pg_configto locate PostgreSQL include and library directories. - It compiles a small test that calls
PQconnectdb()and links it tolibpq. - If that test succeeds, it creates a Makefile.
- The native extension is compiled and installed into the active Ruby environment.
You can verify the installed gem with:
ruby -rpg -e 'puts PG.library_version'
A numeric PostgreSQL client library version indicates that Ruby successfully loaded the extension.
Real World Use Cases
The pg gem is used whenever a Ruby application needs to communicate with PostgreSQL, including:
- Ruby on Rails applications using PostgreSQL as their primary database.
- Background workers that read jobs, update records, or write processing results.
- API services that run SQL queries for users, orders, inventory, or analytics.
- Data import scripts that load CSV, JSON, or external API data into PostgreSQL.
- Command-line administration tools that execute queries or database maintenance tasks.
For example, a small Ruby script can connect and query a database after the gem is installed:
require "pg"
connection = PG.connect(dbname: "example_app")
result = connection.exec("SELECT current_database()")
puts result[0]["current_database"]
connection.close
The gem installation is a build-time concern; database credentials and connections are runtime concerns.
Real Codebase Usage
In real projects, developers usually do not run gem install pg manually for every dependency. The pg gem is declared in a Gemfile, often alongside a locked version in Gemfile.lock:
source "https://rubygems.org"
gem "pg"
The project setup documentation or container image installs operating-system dependencies before running Bundler:
sudo apt update
sudo apt install -y libpq-dev build-essential
bundle install
A Docker-based Ruby project commonly separates build dependencies from application code:
FROM ruby:3.3
RUN apt-get update \
&& apt-get install -y --no-install-recommends libpq-dev build-essential \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
For connection code, applications typically read configuration from environment variables rather than hard-coding credentials:
require "pg"
connection = PG.connect(ENV.fetch("DATABASE_URL"))
This keeps secrets out of source code and lets development, test, and production environments use different databases.
Common Mistakes
Installing only the PostgreSQL server or runtime package
A server installation does not always provide the development files required to compile native gems. Install the development package:
sudo apt install libpq-dev
Installing only the runtime library
The runtime library is useful for running already-compiled programs, but native gem compilation needs development resources too. Use libpq-dev, not only libpq5.
Retrying gem install pg without changing missing dependencies
Running the same command again will produce the same linker error until the required system package is installed.
Using the wrong pg_config with multiple PostgreSQL installations
If PostgreSQL is installed from multiple sources, pg_config may point to headers from one installation and libraries from another. Check the selected executable:
which pg_config
pg_config --version
pg_config --libdir
Then specify the intended one:
gem install pg -- --with-pg-config=/path/to/pg_config
Installing the gem under a different Ruby than the application uses
RVM, rbenv, system Ruby, and Bundler can use different Ruby installations. Check the active environment:
which ruby
ruby -v
which gem
gem env home
Install the gem through the same Ruby and dependency tool used by the project, often:
bundle install
Ignoring mkmf.log
When libpq-dev is already installed but compilation still fails, inspect the detailed compiler output named in the error. It may reveal an incompatible library path, missing compiler, or architecture mismatch.
Comparisons
| Item | Purpose | Needed to compile the pg gem? |
|---|---|---|
pg Ruby gem | Ruby interface for PostgreSQL | Yes |
libpq | PostgreSQL client C library | Yes |
libpq-dev on Ubuntu | Development headers and link support for libpq | Yes |
libpq5 on Ubuntu | Runtime PostgreSQL client library | Usually not sufficient alone |
| PostgreSQL server | Runs databases locally | No, not specifically for compilation |
pg_config | Reports PostgreSQL build paths and version | Usually used by the installer |
gem install pg installs a Ruby dependency. apt install libpq-dev installs an operating-system dependency. Native gems often require both layers.
| Command | Best use |
|---|---|
gem install pg | Install the gem directly into the active Ruby environment |
bundle install | Install dependencies declared by a project Gemfile |
gem install pg -- --with-pg-config=... | Use a particular PostgreSQL installation |
Cheat Sheet
# Install native build tools and PostgreSQL client development files
sudo apt update
sudo apt install libpq-dev build-essential
# Install directly
gem install pg
# Install from a project's Gemfile
bundle install
# Check which pg_config is selected
which pg_config
pg_config --version
pg_config --includedir
pg_config --libdir
# Use a specific PostgreSQL installation
gem install pg -- --with-pg-config=/usr/bin/pg_config
# Test that Ruby can load the gem
ruby -rpg -e 'puts PG.library_version'
Key rule: if a native gem reports that it cannot find libpq, install libpq-dev and ensure the intended pg_config is on the path.
FAQ
Why does the pg gem need a C compiler?
The gem contains native code that links Ruby to PostgreSQL's C client library. That code must be compiled for your machine and Ruby installation.
What Ubuntu package fixes “Can't find the PostgreSQL client library (libpq)”?
Install the PostgreSQL development package:
sudo apt install libpq-dev
Do I need to install the PostgreSQL server to install the pg gem?
No. You need the PostgreSQL client development files to build the gem. A server is only needed if you want to run a database locally.
What is pg_config?
pg_config is a PostgreSQL utility that reports paths and build settings, such as the directories containing headers and libraries. The gem installer uses it to find libpq.
Why does the error say headers were found but PQconnectdb() was not?
Headers declare that PQconnectdb() exists, but the linker must also find a compatible libpq library containing its implementation. The missing or unusable library causes this failure.
Should I run sudo gem install pg?
Usually no, especially when using RVM. Install gems as the current user in the active Ruby environment. Use sudo for apt system packages, not normally for RVM-managed gems.
How do I troubleshoot after installing libpq-dev?
Check which pg_config, verify its version and library path with pg_config --libdir, and inspect the mkmf.log file referenced by the failed gem installation.
Mini Project
Description
Create a small Ruby command-line database health check. It uses the pg gem to read a connection URL, connect to PostgreSQL, and report the server version. This demonstrates both successful native-gem installation and a minimal real database connection.
Goal
Build a script that connects using DATABASE_URL and prints the PostgreSQL server version or a useful error message.
Requirements
Install libpq-dev and the pg gem in the Ruby environment you will use.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.