{"id":7170,"date":"2026-10-04T21:59:32","date_gmt":"2026-10-04T18:59:32","guid":{"rendered":"https:\/\/avenacloud.com\/blog\/postgresql-%d0%bf%d0%be%d0%b4%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-%d0%ba-%d0%b1%d0%b0%d0%b7%d0%b5\/"},"modified":"2026-10-04T21:59:44","modified_gmt":"2026-10-04T18:59:44","slug":"postgresql-%d0%bf%d0%be%d0%b4%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-%d0%ba-%d0%b1%d0%b0%d0%b7%d0%b5","status":"publish","type":"post","link":"https:\/\/avenacloud.com\/blog\/postgresql-%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BA-%D0%B1%D0%B0%D0%B7%D0%B5\/","title":{"rendered":"PostgreSQL \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u041a \u0411\u0430\u0437\u0435: A Guide to Connecting"},"content":{"rendered":"<p>You&#039;ve just provisioned a fresh VPS, installed PostgreSQL, copied the login details into your notes, and opened your terminal. Then the first connection attempt fails. Sometimes it&#039;s \u201cconnection refused\u201d. Sometimes it&#039;s \u201cFATAL: no pg_hba.conf entry\u201d. Sometimes the password is correct, but PostgreSQL still won&#039;t let you in.<\/p>\n<p>That&#039;s the point where most quick tutorials stop being useful.<\/p>\n<p>Work in <strong>PostgreSQL \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0431\u0430\u0437\u0435<\/strong> isn&#039;t typing one client command. It&#039;s understanding which layer is rejecting you. PostgreSQL itself might be listening only on the local socket. <code>pg_hba.conf<\/code> might permit one path and deny another. Your cloud firewall might block the port before the database even sees the traffic. On a VPS, those are the failures that burn time.<\/p>\n<p>I&#039;ve found that junior admins make faster progress when they stop treating connection setup as a single task and start treating it as a chain. Client syntax, server listening address, host-based authentication, and network access all have to line up. If one link is wrong, the error message often points at the wrong thing first.<\/p>\n<h2>Introduction Getting Your First Connection Right<\/h2>\n<p>A common first-day scenario goes like this. The PostgreSQL service is running on a new cloud VPS. You can log into the server over SSH, but your laptop, GUI client, or application can&#039;t reach the database. You try again with the same username and password, and the result doesn&#039;t change.<\/p>\n<p>That usually means the problem isn&#039;t the password.<\/p>\n<p>PostgreSQL has two connection paths that people mix up all the time. A <strong>local Unix-socket connection<\/strong> can work even when <strong>remote TCP access<\/strong> is completely blocked. So an admin logs into the VPS, runs <code>psql<\/code>, sees the prompt, and assumes the server is accessible from everywhere else. It isn&#039;t.<\/p>\n<blockquote>\n<p><strong>Practical rule:<\/strong> A successful local login proves PostgreSQL is running. It does not prove the network path, firewall, or remote authentication rules are correct.<\/p>\n<\/blockquote>\n<p>The other trap is <code>pg_hba.conf<\/code>. New admins often read it as a user list. It&#039;s really a rule set that matches connection type, database, user, source address, and authentication method. If the wrong line matches first, PostgreSQL does exactly what the file told it to do.<\/p>\n<p>There&#039;s a reliable way through this. Start with the facts you need, test the local path, enable remote listening deliberately, add narrow access rules, reload the service, and only then blame the client tool. That approach works better than changing three files at once and hoping one of them fixes the issue.<\/p>\n<h2>Essential Prerequisites for Database Connectivity<\/h2>\n<p>Before you touch a command, collect the connection details in one place. Most failed connection attempts happen because one required value is missing or because the admin is using the right values for the wrong connection type.<\/p>\n<p><figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/avenacloud.com\/blog\/wp-content\/uploads\/2026\/10\/postgresql-database-connection-checklist.jpg\" alt=\"A checklist showing seven essential prerequisites needed to establish a successful connection to a PostgreSQL database server.\" title=\"\"><\/figure><\/p>\n<h3>What you need before you connect<\/h3>\n<ul>\n<li><p><strong>Database host<\/strong>. This is the server address your client will target. On a VPS, that&#039;s typically the public hostname or public IP assigned to the instance. If you still need secure shell access to verify the server first, this guide to <a href=\"https:\/\/avenacloud.com\/blog\/master-ssh-access-securely-manage-remote-servers-like-a-pro\/\">securely managing remote servers over SSH<\/a> is useful groundwork.<\/p>\n<\/li>\n<li><p><strong>Port number<\/strong>. PostgreSQL&#039;s default TCP port is <strong>5432<\/strong>, and that default is explicitly used across TCP-based client connections and services such as Microsoft Fabric CDC, which expects that value in connection settings unless you&#039;ve changed it yourself, as documented in <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/fabric\/real-time-intelligence\/event-streams\/add-source-postgresql-database-change-data-capture\" target=\"_blank\" rel=\"noopener\">Microsoft&#039;s PostgreSQL CDC configuration guidance<\/a>.<\/p>\n<\/li>\n<li><p><strong>Database name<\/strong>. PostgreSQL doesn&#039;t connect you to \u201cthe server\u201d in the abstract. It connects you to a specific database inside the cluster.<\/p>\n<\/li>\n<li><p><strong>Username<\/strong>. This is the PostgreSQL role you authenticate as. It is not automatically the same as your Linux login account.<\/p>\n<\/li>\n<li><p><strong>Password<\/strong>. Needed for password-based authentication methods. If local peer authentication is configured, a password may not be required on the server itself.<\/p>\n<\/li>\n<li><p><strong>Authentication method<\/strong>. On this point, many guides stay vague. PostgreSQL might expect <code>md5<\/code>, <code>scram-sha-256<\/code>, <code>peer<\/code>, or another method depending on the matching <code>pg_hba.conf<\/code> rule.<\/p>\n<\/li>\n<li><p><strong>Network access status<\/strong>. Even with correct PostgreSQL settings, a cloud firewall or host firewall can still block the session before it starts.<\/p>\n<\/li>\n<\/ul>\n<h3>The details people confuse most often<\/h3>\n<p>The biggest mix-up is <strong>system user versus database user<\/strong>. Logging into the VPS as a Linux user doesn&#039;t automatically grant database access. PostgreSQL checks its own roles and its own access rules.<\/p>\n<p>Another frequent mistake is assuming the default port is always active. <strong>5432<\/strong> is the standard starting point, but if a previous admin changed it, your client must follow that change. Don&#039;t guess. Check the server config.<\/p>\n<p>A quick pre-flight note helps:<\/p>\n\n<figure class=\"wp-block-table\"><table><tr>\n<th>Item<\/th>\n<th>Why it matters<\/th>\n<\/tr>\n<tr>\n<td>Host<\/td>\n<td>Tells the client which machine to contact<\/td>\n<\/tr>\n<tr>\n<td>Port<\/td>\n<td>Tells it which service endpoint to use<\/td>\n<\/tr>\n<tr>\n<td>Database<\/td>\n<td>Defines the target session context<\/td>\n<\/tr>\n<tr>\n<td>User<\/td>\n<td>Determines privileges and authentication path<\/td>\n<\/tr>\n<tr>\n<td>Password<\/td>\n<td>Required for password-based login methods<\/td>\n<\/tr>\n<tr>\n<td>Auth method<\/td>\n<td>Explains why one login path works and another fails<\/td>\n<\/tr>\n<tr>\n<td>Network access<\/td>\n<td>Decides whether the traffic reaches PostgreSQL at all<\/td>\n<\/tr>\n<\/table><\/figure>\n<blockquote>\n<p>A clean checklist saves more time than heroic troubleshooting later.<\/p>\n<\/blockquote>\n<h2>Connecting Locally with the psql Command Line<\/h2>\n<p>The first connection test should happen on the PostgreSQL server itself. Local access removes firewall and internet routing from the equation, so you can answer the first important question quickly. Is PostgreSQL alive and accepting sessions at all?<\/p>\n<p><figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/avenacloud.com\/blog\/wp-content\/uploads\/2026\/10\/postgresql-database-connection-postgresql-elephant.jpg\" alt=\"A person using a laptop to connect to a PostgreSQL database, featuring artistic elephant illustration artwork.\" title=\"\"><\/figure><\/p>\n<h3>The command that matters<\/h3>\n<p>For <code>psql<\/code>, the connection syntax is <code>psql -h &lt;host&gt; -U &lt;user&gt; -d &lt;dbname&gt;<\/code>, and omitting <code>-h<\/code> is standard for a local Unix-socket connection, while remote TCP\/IP requires a host value, as noted in <a href=\"https:\/\/alexhost.com\/ru\/faq\/how-to-connect-to-a-postgresql-database\/\" target=\"_blank\" rel=\"noopener\">this psql connection guide<\/a>.<\/p>\n<p>That distinction matters more than it looks. These two commands do different things:<\/p>\n<ul>\n<li><code>psql -U appuser -d appdb<\/code><\/li>\n<li><code>psql -h localhost -U appuser -d appdb<\/code><\/li>\n<\/ul>\n<p>The first usually uses the local Unix socket. The second forces a TCP path to <code>localhost<\/code>. If one works and the other fails, you&#039;ve learned something useful about how PostgreSQL is configured.<\/p>\n<h3>Local login patterns that work<\/h3>\n<p>On Linux, local administration often begins by switching to the PostgreSQL system account and opening <code>psql<\/code> there. In many installations, that avoids permission noise while you verify the cluster.<\/p>\n<p>A practical flow looks like this:<\/p>\n<ol>\n<li>Log into the VPS over SSH.<\/li>\n<li>Become the PostgreSQL administrative user if your platform uses one.<\/li>\n<li>Run <code>psql<\/code> without <code>-h<\/code> first.<\/li>\n<li>Then test the explicit user and database you expect the application to use.<\/li>\n<\/ol>\n<p>The core flags aren&#039;t optional decoration. The <code>-U<\/code> flag explicitly sets the PostgreSQL username, and the <code>-d<\/code> flag specifies the target database, as described in <a href=\"https:\/\/yeahub.ru\/ru\/questions\/python-backend-developer\/kak-podklyuchitsya-k-baze-dannykh-postgresql-s-pomoshchyu-psql\" target=\"_blank\" rel=\"noopener\">this psql usage note<\/a>.<\/p>\n<h3>What local success actually proves<\/h3>\n<p>A successful local login proves the PostgreSQL process is up and that at least one authentication path is valid. It does not prove your remote application can connect.<\/p>\n<p>That&#039;s where many troubleshooting sessions go sideways. Someone tests locally, gets a prompt, and then starts debugging the application driver. Meanwhile PostgreSQL is still bound to loopback only, or the remote host is blocked by the access rules.<\/p>\n<p>If you want a quick visual walk-through before changing configs, this short clip is a good refresher.<\/p>\n<iframe width=\"100%\" style=\"aspect-ratio: 16 \/ 9\" src=\"https:\/\/www.youtube.com\/embed\/qw--VYLpxG4\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe>\n\n<h3>A few small checks save a lot of time<\/h3>\n<ul>\n<li><strong>Match the intended database user<\/strong>. Don&#039;t test as <code>postgres<\/code> if the application will log in as <code>appuser<\/code>.<\/li>\n<li><strong>Use the actual target database<\/strong>. Defaulting into a maintenance database can hide permissions problems.<\/li>\n<li><strong>Notice whether you used <code>-h<\/code><\/strong>. That single flag changes the transport path.<\/li>\n<li><strong>Read the exact error text<\/strong>. \u201cRole does not exist\u201d, \u201cpassword authentication failed\u201d, and \u201cno pg_hba.conf entry\u201d point to different layers.<\/li>\n<\/ul>\n<blockquote>\n<p>If local socket access works and remote access fails, stop rotating passwords. Start checking network path and host-based rules.<\/p>\n<\/blockquote>\n<h2>Enabling and Securing Remote Database Access<\/h2>\n<p>You have PostgreSQL running on a cloud VPS, <code>psql<\/code> works on the server itself, and the application still times out from your laptop or another host. That usually means the problem is no longer the database process. It is the network path, the bind address, or a <code>pg_hba.conf<\/code> rule that does not match the connection you are making.<\/p>\n<p><figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/avenacloud.com\/blog\/wp-content\/uploads\/2026\/10\/postgresql-remote-connection-postgresql-access.jpg\" alt=\"A four-step infographic illustrating the process for enabling and securing remote connections to a PostgreSQL database.\" title=\"\"><\/figure><\/p>\n<h3>Start with the listener, not the password<\/h3>\n<p>Remote clients cannot connect if PostgreSQL is bound only to loopback. Check the active setting in <code>postgresql.conf<\/code>, which is commonly stored at <code>\/etc\/postgresql\/&lt;version&gt;\/main\/postgresql.conf<\/code> on Debian and Ubuntu, or under the data directory on RHEL-based systems.<\/p>\n<pre><code class=\"language-conf\">listen_addresses = &#039;127.0.0.1&#039;\n<\/code><\/pre>\n<p>That value accepts only local TCP connections. To allow remote access, set a specific server IP or a controlled list of addresses:<\/p>\n<pre><code class=\"language-conf\">listen_addresses = &#039;203.0.113.10&#039;\n<\/code><\/pre>\n<p>Many guides jump straight to:<\/p>\n<pre><code class=\"language-conf\">listen_addresses = &#039;*&#039;\n<\/code><\/pre>\n<p>It works, but it expands the attack surface. On a VPS exposed to the internet, I prefer binding to the public address that needs to accept PostgreSQL traffic, or to a private interface if applications connect over a VPN or internal network. That keeps accidental exposure lower and makes firewall review simpler.<\/p>\n<h3><code>pg_hba.conf<\/code> decides whether a client is allowed<\/h3>\n<p>After PostgreSQL is listening, the next gate is <code>pg_hba.conf<\/code>. This file does not just say &quot;password yes or no&quot;. It matches connection type, database, role, client address, and authentication method, in that order.<\/p>\n<p>A common test rule looks like this:<\/p>\n<pre><code class=\"language-conf\">host all all 0.0.0.0\/0 md5\n<\/code><\/pre>\n<p>Use it only to prove a point in a lab. On a real VPS, this is too wide. A better rule names the application database, the application role, and the source subnet that should connect:<\/p>\n<pre><code class=\"language-conf\">host appdb appuser 198.51.100.24\/32 scram-sha-256\n<\/code><\/pre>\n<p>That single line answers four questions clearly. Which database. Which role. From where. Using which auth method.<\/p>\n<h3>Read <code>pg_hba.conf<\/code> like PostgreSQL reads it<\/h3>\n<p>Line order matters. PostgreSQL stops at the first matching rule. If a broad rule appears above the narrow rule you intended, the broad rule wins.<\/p>\n<p>Here is the fast way to interpret a line:<\/p>\n\n<figure class=\"wp-block-table\"><table><tr>\n<th>Field<\/th>\n<th>Meaning<\/th>\n<\/tr>\n<tr>\n<td><code>local<\/code>, <code>host<\/code>, <code>hostssl<\/code><\/td>\n<td>Transport type<\/td>\n<\/tr>\n<tr>\n<td>database<\/td>\n<td>Target database<\/td>\n<\/tr>\n<tr>\n<td>user<\/td>\n<td>PostgreSQL role<\/td>\n<\/tr>\n<tr>\n<td>address<\/td>\n<td>Client IP or subnet<\/td>\n<\/tr>\n<tr>\n<td>method<\/td>\n<td>Authentication method<\/td>\n<\/tr>\n<\/table><\/figure>\n<p>Juniors often lose an hour here. They test over TCP from a remote machine, but they keep staring at a <code>local<\/code> rule that only applies to Unix sockets. Or they add a <code>host<\/code> rule for the right role but the wrong subnet mask. If the error says <code>no pg_hba.conf entry<\/code>, PostgreSQL is telling you the connection reached the server and no rule matched that exact combination.<\/p>\n<h3>Prefer modern auth and narrow scope<\/h3>\n<p>If your PostgreSQL version supports it, use <code>scram-sha-256<\/code> instead of <code>md5<\/code> for password authentication. It is stronger and should be the default choice for new setups.<\/p>\n<p>A practical pattern looks like this:<\/p>\n<pre><code class=\"language-conf\">hostssl appdb appuser 198.51.100.24\/32 scram-sha-256\n<\/code><\/pre>\n<p><code>hostssl<\/code> forces TLS on that rule. That matters on cloud VPS deployments where traffic may cross networks you do not fully control. If you cannot enable TLS yet, keep the source range tight and treat plain <code>host<\/code> access as temporary.<\/p>\n<h3>Reload the service and verify what changed<\/h3>\n<p>Editing the file is only half the job. Reload PostgreSQL so it picks up the new rules without dropping active sessions:<\/p>\n<pre><code class=\"language-bash\">sudo systemctl reload postgresql\n<\/code><\/pre>\n<p>On some systems, checking the loaded config is worth the extra command:<\/p>\n<pre><code class=\"language-bash\">sudo -u postgres psql -c &quot;SHOW hba_file;&quot;\nsudo -u postgres psql -c &quot;SHOW config_file;&quot;\n<\/code><\/pre>\n<p>Those two queries prevent a common mistake on packaged installs. You edit one file, but the running cluster is using another.<\/p>\n<h3>Firewalls block plenty of otherwise correct setups<\/h3>\n<p>On a cloud VPS, PostgreSQL can be configured correctly and still remain unreachable because port <code>5432<\/code> is blocked somewhere on the path. Check both layers:<\/p>\n<ul>\n<li>The host firewall, such as <code>ufw<\/code>, <code>firewalld<\/code>, or raw <code>iptables<\/code><\/li>\n<li>The provider firewall or security group attached to the VPS<\/li>\n<\/ul>\n<p>If you are working on a hosted server, this guide to <a href=\"https:\/\/avenacloud.com\/blog\/firewall-setup-on-vps\/\">setting up firewall rules on a VPS for database access<\/a> is a good baseline for opening only the ports and source ranges you need.<\/p>\n<p>Managed platforms add another failure mode. Microsoft notes in its <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/azure\/databricks\/ingestion\/lakeflow-connect\/postgresql-troubleshoot\" target=\"_blank\" rel=\"noopener\">Azure Databricks PostgreSQL troubleshooting documentation<\/a> that <strong>65% of such failures arise from firewall rules<\/strong> that do not allow the required workspace IP ranges, often combined with missing <code>pg_hba.conf<\/code> entries for those clients.<\/p>\n<h3>A quick troubleshooting order that holds up in production<\/h3>\n<p>Do the checks in this order:<\/p>\n<ol>\n<li>Confirm PostgreSQL is listening on the expected IP and port with <code>ss -ltnp | grep 5432<\/code><\/li>\n<li>Confirm the VPS firewall allows the source IP<\/li>\n<li>Confirm the provider firewall or security group allows the same traffic<\/li>\n<li>Confirm <code>pg_hba.conf<\/code> has a matching <code>host<\/code> or <code>hostssl<\/code> rule for that client<\/li>\n<li>Reload PostgreSQL<\/li>\n<li>Test from the client host, not from the server console<\/li>\n<\/ol>\n<p>That order saves time because each step proves a different layer. If you skip around, you end up changing passwords for a problem caused by a blocked port.<\/p>\n<h3>What usually causes the failed first remote login<\/h3>\n<p>The repeat offenders are predictable:<\/p>\n<ul>\n<li><code>listen_addresses<\/code> still set to <code>localhost<\/code><\/li>\n<li>a correct <code>pg_hba.conf<\/code> rule placed below a broader conflicting one<\/li>\n<li>opening <code>5432<\/code> in <code>ufw<\/code> but forgetting the cloud firewall<\/li>\n<li>testing local socket access and assuming remote TCP should behave the same way<\/li>\n<li>allowing <code>0.0.0.0\/0<\/code> during testing and forgetting to tighten it later<\/li>\n<\/ul>\n<p>Remote access is safe enough when each layer is explicit. Bind only where needed. Allow only known client networks. Use <code>scram-sha-256<\/code> and TLS where possible. Then test from the same kind of host your application will use.<\/p>\n<h2>Connecting with Popular GUI Tools<\/h2>\n<p>Once the server side is correct, GUI tools become straightforward. DBeaver, DataGrip, and pgAdmin all ask for the same core values. They just present them with different labels and tabs.<\/p>\n<p><figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/avenacloud.com\/blog\/wp-content\/uploads\/2026\/10\/postgresql-database-connection-postgresql-developer.jpg\" alt=\"A professional developer analyzing a PostgreSQL database on a computer monitor with data visualization charts displayed.\" title=\"\"><\/figure><\/p>\n<h3>The common pattern across tools<\/h3>\n<p>Here&#039;s how the usual fields map:<\/p>\n\n<figure class=\"wp-block-table\"><table><tr>\n<th>Tool field<\/th>\n<th>What to enter<\/th>\n<\/tr>\n<tr>\n<td>Host<\/td>\n<td>Your PostgreSQL server hostname or IP<\/td>\n<\/tr>\n<tr>\n<td>Port<\/td>\n<td>The PostgreSQL port configured on the server<\/td>\n<\/tr>\n<tr>\n<td>Database<\/td>\n<td>The target database name<\/td>\n<\/tr>\n<tr>\n<td>User<\/td>\n<td>The PostgreSQL role<\/td>\n<\/tr>\n<tr>\n<td>Password<\/td>\n<td>The role password<\/td>\n<\/tr>\n<tr>\n<td>SSL tab or checkbox<\/td>\n<td>Encryption settings if required<\/td>\n<\/tr>\n<\/table><\/figure>\n<p>DBeaver tends to be forgiving and easy for mixed database work. DataGrip is strong if you already live in JetBrains tooling. pgAdmin is the native choice many PostgreSQL admins keep around because its terminology matches the ecosystem closely.<\/p>\n<h3>Where GUI users get tripped up<\/h3>\n<p>The first trap is testing from a workstation when only the server&#039;s local socket path has been verified. GUI tools always use a network path unless you&#039;ve built a local tunnel.<\/p>\n<p>The second trap is SSL configuration. If the server expects encrypted transport, the GUI must match that expectation. Don&#039;t guess at the setting. Match whatever policy the server side requires. If you&#039;re preparing certificates or securing traffic for services on your VPS, this guide on <a href=\"https:\/\/avenacloud.com\/blog\/how-to-install-ssl\/\">installing SSL<\/a> is a useful companion.<\/p>\n<blockquote>\n<p>A GUI doesn&#039;t abstract away PostgreSQL networking. It only hides the command line.<\/p>\n<\/blockquote>\n<h3>SSH tunnelling versus direct database exposure<\/h3>\n<p>For private environments, I usually prefer an SSH tunnel over exposing PostgreSQL broadly to the internet. The GUI then connects to a local forwarded port, and the SSH layer carries the traffic securely to the VPS.<\/p>\n<p>That approach reduces how much of PostgreSQL you need to expose externally. It also makes it easier to keep <code>pg_hba.conf<\/code> and firewall rules tight. The trade-off is operational overhead. Tunnels can confuse less experienced users, and automated applications won&#039;t use them the same way a human-operated GUI session can.<\/p>\n<p>For daily admin work, pick the simplest secure route your environment supports. If the database must be reachable directly, make the rules precise. If it only needs occasional operator access, tunnelling is often cleaner.<\/p>\n<h2>Frequently Asked Questions and Advanced Tips<\/h2>\n<p>A lot of PostgreSQL connection work stops being mysterious once you separate three things clearly. How the client reaches the server, which <code>pg_hba.conf<\/code> rule matches, and how PostgreSQL verifies identity after that match. If you keep those layers separate, you spend less time changing five settings at once and hoping one works.<\/p>\n<h3>What&#039;s the difference between <code>md5<\/code>, <code>scram-sha-256<\/code>, and <code>trust<\/code><\/h3>\n<p>These values in <code>pg_hba.conf<\/code> control the authentication method used after a rule matches.<\/p>\n<p><code>trust<\/code> allows the connection without a password check. That can make sense for tightly controlled local automation on the same host, but it is dangerous on any path that could be reached over TCP.<\/p>\n<p><code>md5<\/code> is older password authentication. It still appears in many VPS deployments because legacy clients support it. <code>scram-sha-256<\/code> is the better choice for current PostgreSQL versions because it stores and verifies passwords more safely. The trade-off is compatibility. Older drivers, old GUI clients, or stale application containers sometimes fail against SCRAM until they are updated.<\/p>\n<p>In practice, use <code>scram-sha-256<\/code> for new setups unless a client limitation forces <code>md5<\/code>. If you do keep <code>md5<\/code> for compatibility, document why, and plan to remove it later.<\/p>\n<h3>Can PostgreSQL run on a different port<\/h3>\n<p>Yes. PostgreSQL defaults to <code>5432<\/code>, but the server can listen on another port if you set <code>port = 5544<\/code> or similar in <code>postgresql.conf<\/code>.<\/p>\n<p>That change affects more than the database config. Client connection strings, local firewall rules such as <code>ufw<\/code> or <code>iptables<\/code>, cloud security groups, monitoring checks, and backups all need to follow the new port. I have seen admins change the port, confirm <code>systemctl restart postgresql<\/code> succeeds, and then spend an hour troubleshooting what was really just an unopened VPS firewall rule.<\/p>\n<p>Changing the port can reduce random internet noise in logs. It does not secure the service by itself.<\/p>\n<h3>Why do I get \u201cpassword authentication failed\u201d when I know the password is right<\/h3>\n<p>Because PostgreSQL is telling you the login process failed, not necessarily that the human typed the wrong secret.<\/p>\n<p>Common causes include:<\/p>\n<ul>\n<li><strong>Wrong role name.<\/strong> The password belongs to <code>app_user<\/code>, but the client is trying <code>postgres<\/code>.<\/li>\n<li><strong>Wrong target server or port.<\/strong> Saved GUI profiles are notorious for this.<\/li>\n<li><strong>Auth mismatch.<\/strong> The account was set up expecting one method, but the matched <code>pg_hba.conf<\/code> rule forces another.<\/li>\n<li><strong>Different <code>pg_hba.conf<\/code> line matched first.<\/strong> PostgreSQL uses the first matching rule, not the most specific-looking one later in the file.<\/li>\n<li><strong>Password changed on another node.<\/strong> This shows up in replicated or manually cloned environments more often than people expect.<\/li>\n<\/ul>\n<p>If the error is ambiguous, test from the VPS itself first with the exact role and database name:<\/p>\n<pre><code class=\"language-bash\">psql -h 127.0.0.1 -U app_user -d app_db\n<\/code><\/pre>\n<p>Using <code>127.0.0.1<\/code> matters here. It forces a TCP connection, which is different from a local Unix socket connection and will match different <code>pg_hba.conf<\/code> rules.<\/p>\n<h3>What if the error says there&#039;s no <code>pg_hba.conf<\/code> entry<\/h3>\n<p>That message is useful. It means PostgreSQL received the connection attempt, but none of the access rules matched the combination of client address, database, user, and connection type.<\/p>\n<p>Check these points in order:<\/p>\n<ul>\n<li>whether the client connected over local socket, <code>127.0.0.1<\/code>, or the VPS public IP<\/li>\n<li>whether the <code>TYPE<\/code> column should be <code>local<\/code>, <code>host<\/code>, <code>hostssl<\/code>, or <code>hostnossl<\/code><\/li>\n<li>whether the source CIDR is correct, such as <code>203.0.113.14\/32<\/code> instead of a broader or incorrect range<\/li>\n<li>whether a broader rule above the intended line is catching the connection first<\/li>\n<\/ul>\n<p>Then reload PostgreSQL after editing the file:<\/p>\n<pre><code class=\"language-bash\">sudo systemctl reload postgresql\n<\/code><\/pre>\n<p>On Debian and Ubuntu systems, the file is often under <code>\/etc\/postgresql\/16\/main\/pg_hba.conf<\/code>. On RHEL-based systems using the community packages, it is often under <code>\/var\/lib\/pgsql\/16\/data\/pg_hba.conf<\/code>. Verify the active path with <code>SHOW hba_file;<\/code> inside <code>psql<\/code> if there is any doubt.<\/p>\n<h3>How do I tell whether the failure is PostgreSQL or the network<\/h3>\n<p>Use a layered test sequence and keep notes. Random changes make this slower.<\/p>\n<ol>\n<li><p><strong>Test local socket access on the VPS.<\/strong><br><code>sudo -u postgres psql<\/code><\/p>\n<\/li>\n<li><p><strong>Test local TCP on the VPS.<\/strong><br><code>psql -h 127.0.0.1 -U postgres -d postgres<\/code><\/p>\n<\/li>\n<li><p><strong>Confirm what PostgreSQL is listening on.<\/strong><br><code>ss -ltnp | grep 5432<\/code><\/p>\n<\/li>\n<li><p><strong>Check the active values.<\/strong><br>Run <code>SHOW listen_addresses;<\/code>, <code>SHOW port;<\/code>, and <code>SHOW hba_file;<\/code><\/p>\n<\/li>\n<li><p><strong>Inspect host firewall rules.<\/strong><br>For example, <code>sudo ufw status<\/code> or <code>sudo iptables -S<\/code><\/p>\n<\/li>\n<li><p><strong>Inspect the cloud firewall or security group.<\/strong><br>Cloud VPS users often get caught here. The service is listening, but the provider-level rule still blocks the source IP.<\/p>\n<\/li>\n<li><p><strong>Test from the actual client location.<\/strong><br>Office VPN, home broadband, and a CI runner can each hit different rules.<\/p>\n<\/li>\n<\/ol>\n<p>This order tells you which layer is failing. It also prevents the common mistake of editing <code>pg_hba.conf<\/code> to fix a problem that is really outside PostgreSQL.<\/p>\n<h3>What built-in PostgreSQL views help during troubleshooting<\/h3>\n<p><code>pg_stat_activity<\/code> is the first view to check once a connection starts reaching the server. It shows active sessions, usernames, client addresses, and query state.<\/p>\n<p><code>pg_stat_database<\/code> helps when the issue shifts from \u201ccan I connect\u201d to \u201cwhy does this database feel unhealthy after clients connect.\u201d <code>pg_stat_wal<\/code> is useful if write-heavy workloads start backing up. PostgreSQL documents these statistics views in its own reference pages, and the <a href=\"https:\/\/club.directum.ru\/post\/363218\" target=\"_blank\" rel=\"noopener\">overview of PostgreSQL statistics views<\/a> gives a readable summary of what each one is for.<\/p>\n<p>For connection work, <code>pg_stat_activity<\/code> answers a very practical question. Is the session arriving at PostgreSQL at all, or is it being blocked before the server can create a backend process?<\/p>\n<h3>Why do cloud VPS setups fail so often on authentication and access rules<\/h3>\n<p>Because there are usually two or three control planes in play, and admins fix only one of them.<\/p>\n<p>A typical VPS case looks like this. <code>postgresql.conf<\/code> is set to listen on <code>0.0.0.0<\/code>. <code>ufw<\/code> allows <code>5432\/tcp<\/code>. The cloud firewall still blocks the source IP, or <code>pg_hba.conf<\/code> only allows <code>127.0.0.1\/32<\/code>. From the outside, all of those failures feel similar. From the server side, they are completely different problems.<\/p>\n<p>ServBay notes in its PostgreSQL troubleshooting guide, <a href=\"https:\/\/support.servbay.com\/ru\/faq\/postgresql-service-troubleshooting\" target=\"_blank\" rel=\"noopener\">https:\/\/support.servbay.com\/ru\/faq\/postgresql-service-troubleshooting<\/a>, that many connection failures come from host-based authentication mistakes. That matches day-to-day admin work. The port is open, the process is running, and the login still fails because the matched rule is not the one the admin thought they wrote.<\/p>\n<h3>When should you stop tweaking connection settings and start looking at performance<\/h3>\n<p>Once connections are stable and repeatable.<\/p>\n<p>Until then, query tuning is noise. Fix reachability first, confirm authentication paths, and make sure operators and applications can connect the same way every time. After that, it makes sense to work on slow queries, memory settings, autovacuum behavior, and WAL pressure. If the database is reachable but the VPS still feels strained under load, this guide to <a href=\"https:\/\/avenacloud.com\/blog\/optimizing-database-performance-on-your-vps-a-comprehensive-guide\/\">optimizing database performance on your VPS<\/a> is a good next step.<\/p>\n<blockquote>\n<p>Stable access comes first. Tuning a database nobody can reliably reach does not help.<\/p>\n<\/blockquote>\n<p>The main lesson behind <strong>PostgreSQL \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0431\u0430\u0437\u0435<\/strong> is straightforward. Treat local socket access, local TCP access, and remote TCP access as different tests. Treat <code>postgresql.conf<\/code>, <code>pg_hba.conf<\/code>, the host firewall, and the cloud firewall as separate checkpoints. Work one layer at a time, and PostgreSQL becomes far easier to diagnose.<\/p>\n<p>If you need a VPS platform for PostgreSQL, application back ends, or full root-level infrastructure work, <a href=\"https:\/\/avenacloud.com\">AvenaCloud Hosting Provider<\/a> offers scalable VPS and dedicated server options with the kind of control that makes database administration practical. It&#039;s a solid fit for teams that want predictable resources, flexible networking, and room to grow without giving up direct access to the system.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You&#039;ve just provisioned a fresh VPS, installed PostgreSQL, copied the login details into your notes, and opened your terminal. Then the first connection attempt fails. Sometimes it&#039;s \u201cconnection refused\u201d. Sometimes it&#039;s \u201cFATAL: no pg_hba.conf entry\u201d. Sometimes the password is correct,&#8230; <\/p>\n","protected":false},"author":1,"featured_media":7169,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[2294,2293,2292,2295,2296],"class_list":["post-7170","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-help","tag-connect-to-postgresql","tag-database-connection","tag-postgresql","tag-postgresql---","tag-sql-client"],"_links":{"self":[{"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/posts\/7170","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/comments?post=7170"}],"version-history":[{"count":1,"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/posts\/7170\/revisions"}],"predecessor-version":[{"id":7175,"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/posts\/7170\/revisions\/7175"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/media\/7169"}],"wp:attachment":[{"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/media?parent=7170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/categories?post=7170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/avenacloud.com\/blog\/wp-json\/wp\/v2\/tags?post=7170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}