billdoor
billdoor

Reputation: 2043

cloud firestore Gets painfully slow

up until now i built a project using cloud sql as my backend database.

As the data is structured in quite small records, i thought, a document storage would be better suited for it - especially as postgres does not easily scale. So I wanted to try Datastore - which is deprecated and replaced by firestore - fine.

I inserted one document into one collection, created a test sql database on cloud sql with one table and inserted the same record, then I ran a simple benchmark in Go.

Soooo: **cloud sql postgres can return 6000 (198.650 ns/op) responses in the same time as firebase manages around 66 (17.006.551 ns/op).**

I must be doing something wrong here. Even if postgres does not scale, it can slow down by 100 times before it comes close to the performance of firestore with one index on one collection containing one document.

I run my benchmarks from a 4-core, 8GB ram compute instance with this flags:

go test -bench=. -benchtime=1s -test.parallel=1 -cpu=1

This is the benchmark i use for firestore:

func Benchmark_fetchSingle(b *testing.B) {

    ctx := context.Background()

    client, _ := firestore.NewClient(ctx, "project-123", option.WithCredentialsFile("key.json"))
    defer client.Close()
    for n := 0; n < b.N; n++ {
        c,_ := client.Collection("documents").Doc("DOCUMENTID").Get(ctx)
        c = c
    }
}

this is the one for cloud sql (postgres):

func Benchmark_sql(b *testing.B) {
    psqlInfo := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s " +
        "sslmode=require sslrootcert=server.chain.cert sslcert=client.cert sslkey=client.key",
        "ip.address.0.0", "5432", "user", "password", "database")
    sqldb, _ := sql.Open("postgres", psqlInfo)
    stmt, _ := sqldb.Prepare(`select property1, property2 from documents where pk = $1;`)
    defer sqldb.Close()

    for n := 0; n < b.N; n++ {
        rows, _ := stmt.Query("DOCUMENTPK")

        rows.Next()
        stuff := struct{
            P1 string
            P2 string}{}
        rows.Scan(&(stuff.P1), &(stuff.P2))
        stuff = stuff
        rows.Close()
    }
}

Did it missconfigure firestore? I think theres also spanner and bigtable as no-sql alternatives - but their cost are immense for my simple usecase (at least the estimations, which i find quite intransparent)

Upvotes: 0

Views: 745

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598797

It's incredibly hard to help with performance problems without ending up in a discussion about how to measure things, which is off-topic on Stack Overflow. So instead I'll try to explain how to understand Firestore's performance characteristics, and hopefully you can map that back to the results you see.

Firestore's main (and quite unique) performance guarantee is that the performance depends on the size of the result set and not on the size of the collection. In simpler words: if it takes 1 second to retrieve 10 documents from a collection of (say) 1,000 documents, it will also take 1 second to retrieve those 10 documents when the collection contains 1,000,000 or 1,000,000,000 documents.

Note that this says nothing about the actual performance, as that depends on many other factors. It merely speaks to the change performance in performance as the collection grows. As in: the performance will not change in that case. So while most databases have declining performance when the underlying database growth (typically somewhere around O(n log n)), Firestore's performance is flat (O(1), or O(10) in the example of retrieving 10 documents).

Upvotes: 3

Related Questions