diff --git a/docs/jdbc.md b/docs/jdbc.md
index 8f8b76478..b57accfe3 100644
--- a/docs/jdbc.md
+++ b/docs/jdbc.md
@@ -9,18 +9,54 @@ First start PGAdapter:
```shell
wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter.tar.gz && tar -xzvf pgadapter.tar.gz
-java -jar pgadapter.jar -p my-project -i my-instance -d my-database
+java -jar pgadapter.jar -p my-project -i my-instance
```
-Connect to PGAdapter like this:
+Connect to PGAdapter using TCP like this:
```java
// Make sure the PG JDBC driver is loaded.
Class.forName("org.postgresql.Driver");
// Replace localhost and 5432 with the host and port number where PGAdapter is running.
-// prepareThreshold=0 disables the use of server-side prepared statements in JDBC.
-try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/?prepareThreshold=0")) {
+try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/my-database")) {
+ try (ResultSet resultSet = connection.createStatement().executeQuery("select 'Hello world!' as hello")) {
+ while (resultSet.next()) {
+ System.out.printf("Greeting from Cloud Spanner PostgreSQL: %s\n", resultSet.getString(1));
+ }
+ }
+}
+```
+
+
+### Unix Domain Sockets
+Connect to PGAdapter using Unix Domain Sockets like this:
+
+Add this to your dependencies:
+```xml
+
+ com.kohlschutter.junixsocket
+ junixsocket-core
+ 2.5.0
+ pom
+
+
+ com.kohlschutter.junixsocket
+ junixsocket-common
+ 2.5.0
+
+```
+
+```java
+// Make sure the PG JDBC driver is loaded.
+Class.forName("org.postgresql.Driver");
+
+// '/tmp' is the default domain socket directory for PGAdapter. This can be changed using the -dir
+// command line argument. 5432 is the default port number used by PGAdapter. Change this in the
+// connection string if PGAdapter is running on a custom port.
+try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost/my-database"
+ + "?socketFactory=org.newsclub.net.unix.AFUNIXSocketFactory$FactoryArg"
+ + "&socketFactoryArg=/tmp/.s.PGSQL.5432")) {
try (ResultSet resultSet = connection.createStatement().executeQuery("select 'Hello world!' as hello")) {
while (resultSet.next()) {
System.out.printf("Greeting from Cloud Spanner PostgreSQL: %s\n", resultSet.getString(1));
@@ -33,3 +69,39 @@ try (Connection connection = DriverManager.getConnection("jdbc:postgresql://loca
This example uses the pre-built jar to run PGAdapter as a standalone process.
See [README](../README.md) for more possibilities on how to run PGAdapter.
+
+## Performance Considerations
+
+The following will give you the best possible performance when using the JDBC driver with PGAdapter.
+
+### Unix Domain Sockets
+Use Unix Domain Socket connections for the lowest possible latency when PGAdapter and the client
+application are running on the same host. See https://jdbc.postgresql.org/documentation/head/connect.html
+for more information on connection options for the JDBC driver.
+
+### JDBC Batching
+Use the JDBC batching API when executing multiple DDL or DML statements. PGAdapter will combine
+DML and DDL statements that are executed in a JDBC batch into a single request on Cloud Spanner.
+This can significantly reduce the overhead of executing multiple DML or DDL statements.
+
+Example for DML statements:
+
+```java
+try (java.sql.Statement statement = connection.createStatement()) {
+ statement.addBatch("insert into my_table (key, value) values ('k1', 'value1')");
+ statement.addBatch("insert into my_table (key, value) values ('k2', 'value2')");
+ // This will execute the above statements as a single batch DML request on Cloud Spanner.
+ int[] updateCounts = statement.executeBatch();
+}
+```
+
+Example for DDL statements:
+
+```java
+try (java.sql.Statement statement = connection.createStatement()) {
+ statement.addBatch("create table singers (singerid varchar primary key, name varchar)");
+ statement.addBatch("create index idx_singers_name on singers (name)");
+ // This will execute the above statements as a single DDL update request on Cloud Spanner.
+ int[] updateCounts = statement.executeBatch();
+}
+```