Postgres 17 is out today, and we’re here for it. In keeping with our version policy, the latest major version is now available for all Neon users including those on the Free plan. Get your Postgres 17 database and start exploring the latest features immediately.
How to speed run Postgres 17 on Neon
Step 1: Create a Neon account. We only need your login info (no credit card).
Step 2: Select `Postgres 17` for your project
Step 3: That’s it. Your Postgres 17 database is already up and running. You can start querying directly from the Neon SQL Editor or connecting with psql.
Testing new PG 17 features
Simplifying queries using MERGE with RETURNING
One of the things we’re most excited about Postgres 17 is how it improves the functionality of the MERGE command by adding RETURNING clause support. Why this matters:
- It streamlines queries. You can conditionally insert, update, or delete records without writing multiple queries.
- You get the results of the operation instantly – this is especially useful for application logic that depends on the outcome.
To quickly test it, create a sample table:
Use the MERGE command with RETURNING:
Output will look like this:
merge_action | id | first_name | last_name | hero_name |
INSERT | 1 | Wade | Wilson | Deadpool |
What is happening:
- The MERGE command checks if a hero with the hero_name ‘Deadpool’ exists.
- If matched, it updates the existing record’s first_name and last_name.
- If not matched, it inserts a new record into the heroes table.
- RETURNING merge_action() returns the action performed (INSERT or UPDATE) and the full row data.
Generating random integers with the improved random() function
Another great addition in Postgres 17 is the improvement of the random() function to accept range parameters, allowing it to generate random integers within a specified range. You can use the random(min, max) function to generate a random integer between min and max, inclusive:
Generating random numbers directly within Postgres is useful for many things, for example creating test data—you could use random() to populate existing tables with random values as you run some tests. For example, consider these two tables, with student names and scores:
The test_scores table is still empty, but you could insert test scores for every student:
And when you query the table, you should see random values:
student_id | name | score |
1 | Alice | 78 |
2 | Bob | 92 |
3 | Charlie | 85 |
4 | Diana | 67 |
5 | Ethan | 74 |
Another nice thing you can do is to combine random() with generate series() for creating bulk data without an existing `students` table, e.g.:
What’s would happen here:
- generate_series(1, 1000) would generate numbers from 1 to 1000, simulating 1000 students.
- random(50, 100) would assign a random score to each simulated student.
Querying JSON data with JSON_TABLE
Postgres 17 also introduces JSON_TABLE, a feature that simplifies working with JSON data by transforming it into a relational format. You can query and manipulate JSON structures as if they were regular tables. How it works is straightforward—for example, imagine you have this array:
To transform this data into a relational table, you’d run:
It would transform it into a table like this:
product_name | price | stock |
Laptop | 1200 | 25 |
Smartphone | 800 | 50 |
Tablet | 500 | 40 |
If you had an existing products table with a JSONB column…
…you could use JSON_TABLE to query the data together:
Reducing connection latency with sslnegotiation=direct
A nice one: Postgres 17 introduces the sslnegotiation
connection parameter, which allows clients to control how SSL negotiation is handled when establishing a connection. By using the sslnegotiation=direct
option, you can reduce the latency of establishing a secure connection by skipping unnecessary negotiation steps.
At Neon, we’ve implemented support for sslnegotiation=direct
within our proxy layer. This means that even if your database is running an older version of Postgres, you can still take advantage of faster connection times when using a Postgres 17 client with this option.
Let’s demo it:
Before
Without specifying the sslnegotiation
parameter, the client and server engage in an initial negotiation to determine if SSL is required, which adds extra round trips and increases connection time:
After
By adding sslnegotiation=direct to your connection string, the client skips the initial negotiation and directly initiates an SSL connection, reducing the overall connection time:
Getting insights into memory usage via EXPLAIN
The last one. Postgres 17 comes with an enhancement to the EXPLAIN command by allowing it to report the memory usage of the query planner during the preparation of execution plans. This gives you information about the resources consumed during query planning, helping you identify queries that consume excessive memory during the planning phase.
In Postgres 17, the EXPLAIN output includes a summary section that reports the memory usage of the optimizer during the planning phase:
The new line Planning Memory Usage: 10,240 kB
tells you memory consumed by the optimizer during the planning phase.
Upgrading to Postgres 17
While minor version upgrades in Neon happen automatically, there is still manual work necessary to upgrade major versions. If you want to test moving an existing database running an older major version of Postgres to 17, follow the steps outlined in our upgrading your Postgres version guide. If you are using any extensions, be sure to check extension support for Postgres 17 on Neon before upgrading.
Get started with Postgres 17
Start here to create a free Neon account with Postgres 17 ready to go. We’re on Discord if you have any questions.