title: Slow Database Access from GCP Cloud Run
body: <p>Calling the POST method in the following code takes about 35ms when run on a GCP virtual machine (as a container), but when deployed to GCP Cloud Run (as a container) it runs much slower, taking about 6500ms, almost 200x slower.</p>
  <p>I generously increased the Cloud Run CPU and memory allocations but the speed remained the same. I narrowed it down to the database code, by putting it in a loop of 10 times, which made it almost 10 times slower.</p>
  <p>In both cases there are 10 connections to the database. However, in the Cloud Run case, the connections build up slowly, starting with 1 then 2 more after a few seconds, and then it waits for requests and adds another 2 every request until 10. In contrast, when running it on the VM (as a container) it instantly establishes 10 connections and nothing changes with the requests.</p>
  <p>Any idea why such a drastic difference in performance? I'm sure it's something I'm doing wrong as Cloud Run would be almost useless if this is normal.</p>
  <p>The database is a Cloud SQL postgresql instance.</p>
  <p><strong>Update 1:</strong> I should point out that I am not using the instance unix socket. Could that be relevant?</p>
  <p><strong>Update 2:</strong> Adding this extra line of code does not fix the problem:</p>
  <pre><code>addDataSourceProperty(&quot;unixSocketPath&quot;, &quot;/cloudsql/valiant-index-344017:asia-southeast1:main&quot;)
  </code></pre>
  <p><strong>Update 3:</strong> I'm building this using Jib and uploading the image to gcr.io then deploying to cloud run. See <code>build.gradle.kts</code> after the source code.</p>
  <p><strong>Update 4:</strong> For completeness I'm also appending <code>src/main/resources/application.conf</code> (after the first two files below) which is needed to make the code run.</p>
  <p>Following is the full program <code>App.kt</code>:</p>
  <pre><code>package com.example
  
  import com.zaxxer.hikari.HikariConfig
  import com.zaxxer.hikari.HikariDataSource
  import io.ktor.server.application.*
  import io.ktor.server.plugins.contentnegotiation.*
  import io.ktor.server.request.*
  import io.ktor.server.response.*
  import io.ktor.server.routing.*
  import io.ktor.serialization.kotlinx.json.*
  import kotlinx.serialization.*
  import kotlinx.serialization.json.*
  import org.jetbrains.exposed.sql.Database
  import org.jetbrains.exposed.sql.Table
  import org.jetbrains.exposed.sql.insert
  import org.jetbrains.exposed.sql.transactions.transaction
  import org.postgresql.util.PSQLException
  
  
  @Serializable
  data class Message (val id: Int, val message: String)
  
  object Foo: Table() {
    val n = integer(&quot;n&quot;)
  }
  
  fun Application.main() {
    HikariConfig().run {
      jdbcUrl = &quot;jdbc:postgresql:///main&quot;
      username = &quot;main&quot;
      password = &quot;yourpasswordhere&quot;
      addDataSourceProperty(&quot;socketFactory&quot;, &quot;com.google.cloud.sql.postgres.SocketFactory&quot;)
      addDataSourceProperty(&quot;cloudSqlInstance&quot;, &quot;valiant-index-344017:asia-southeast1:main&quot;)
      HikariDataSource(this)
    }.let {
      Database.connect(it)
    }
    install(ContentNegotiation) {
      json(Json {
        prettyPrint = true
        isLenient = true
      })
    }
    routing {
      get(&quot;/&quot;) {
        call.respondText(&quot;hello&quot;)
      }
      post(&quot;/&quot;) {
        try {
          val message = call.receive&lt;Message&gt;()
          try {
            (0 until 10).forEach { i -&gt;   // ***** THIS CODE BLOCK IS SLOW *****
              transaction {
                Foo.insert {
                  it[n] = message.id * 10 + i
                }
              }
            }
            call.respond&lt;Message&gt;(Message(message.id, &quot;ok&quot;))
          } catch (e: PSQLException) {
            println(&quot;exception: $e&quot;)
            call.respond&lt;Message&gt;(Message(0, &quot;exception: $e&quot;))
          }
        } catch (e: Throwable) {
          println(&quot;err: $e&quot;)
          call.respondText(&quot;err: $e&quot;)
        }
      }
    }
  }
  </code></pre>
  <p><strong>Update 3:</strong> <code>build.gradle.kts</code> is below. I'm using Jib not a Dockerfile.</p>
  <pre><code>plugins {
      kotlin(&quot;jvm&quot;) version &quot;1.7.10&quot;
      kotlin(&quot;plugin.serialization&quot;) version &quot;1.7.10&quot;
      id(&quot;com.google.cloud.tools.jib&quot;) version &quot;2.1.0&quot;
      application
  }
  
  repositories {
      mavenCentral()
  }
  
  dependencies {
      implementation(&quot;io.ktor:ktor-server-core:latest.release&quot;)
      implementation(&quot;io.ktor:ktor-server-netty:latest.release&quot;)
      implementation(&quot;io.ktor:ktor-server-content-negotiation:latest.release&quot;)
      implementation(&quot;io.ktor:ktor-serialization-kotlinx-json:latest.release&quot;)
      implementation(&quot;com.google.cloud.sql:postgres-socket-factory:latest.release&quot;)
      implementation(&quot;com.zaxxer:HikariCP:latest.release&quot;)
      implementation(&quot;org.postgresql:postgresql:latest.release&quot;)
      implementation(&quot;org.jetbrains.exposed:exposed-core:latest.release&quot;)
      implementation(&quot;org.jetbrains.exposed:exposed-dao:latest.release&quot;)
      implementation(&quot;org.jetbrains.exposed:exposed-jdbc:latest.release&quot;)
      implementation(&quot;ch.qos.logback:logback-classic:latest.release&quot;)
  }
  
  application {
      mainClass.set(&quot;io.ktor.server.netty.EngineMain&quot;)
  }
  
  kotlin.sourceSets.all {
      languageSettings.optIn(&quot;kotlin.RequiresOptIn&quot;)
  }
  
  jib {
      to.image = &quot;gcr.io/valiant-index-344017/bgcl/wordchase_host&quot;
      container.mainClass = &quot;io.ktor.server.netty.EngineMain&quot;
  }
  </code></pre>
  <p><strong>Update 4:</strong> <code>src/main/resources/application.conf</code> below for completeness:</p>
  <pre><code>ktor {
    deployment {
      port = ${PORT}
    }
    application {
      modules = [ com.example.AppKt.main ]
    }
  }
  </code></pre>