Speed Up Firebase Cold Starts with Firestore REST Calls

If you use serverless cloud functions, whether on AWS or Google Cloud, you know the pain of cold starts. Firebase functions is notorious for having cold start issues and we’ve previously written about Firebase cold start solutions. Most of these solutions require rewriting your code, such as dynamically import modules or the new Google Cloud Functions v2, which allows a Node.js instance to handle multiple request.

Out of the blue, Firebase stealthily announced a new feature to help with cold starts, preferRest.

The Cloud Firestore API now supports the preferRest setting to force the use of REST transport until an operation requires gRPC.

What does this mean? Hidden in the Firebase Github ticket is the description:

There is a longstanding issue with extremely slow cold-start times when using the official Nodejs Firestore library in serverless environments: https://issuetracker.google.com/issues/158014637. It appears that the underlying issue is very difficult to address (hence the unresolved years-old P1/S1 issue), and a proper interim fix is long overdue.

One solution is to use the Firestore REST API directly. This dramatically improves cold start times, but at the cost of a seriously degraded developer experience. There has been at least one attempt by a Firestore user to create an unofficial wrapper library (https://github.com/bountyrush/nodejs-firestore). This library works, but is maintained by a single developer, and is not a replacement for an official library for obvious reasons.

Basically, by not having the overhead of gRPC and using direct REST Firestore calls, you can potentially speed up Firebase cold start times.

How to Implement Firestore REST Calls with preferRest

We mentioned before the “stealthy” release, and we mean it. There is a new way to initialize Firestore in your functions that is not mentioned in the official Firebase documentation.

Normally you would initialize Firestore in Node.js (see the docs for other programming language examples) by doing the following:

const { initializeApp, applicationDefault, cert } = require('firebase-admin/app');
const { getFirestore, Timestamp, FieldValue } = require('firebase-admin/firestore');

initializeApp({
  credential: applicationDefault()
});

const db = getFirestore();

Use the getFirestore() function to create a database instance.

If you want to set preferRest, you need to initialize Firestore slightly differently with initializeFirestore:

const { initializeApp, applicationDefault, cert } = require('firebase-admin/app');
const { initializeFirestore, Timestamp, FieldValue } = require('firebase-admin/firestore');

const app = initializeApp({
  credential: applicationDefault()
});

const db = const db = initializeFirestore(app, { preferRest: true });

Pass in the initialize app and the object { preferRest: true }. That simple!

This is a new feature, so be sure to test throughly before releasing to production. As Firebase fan-favorite Puf says, “I haven’t tried it myself yet.”

YouTube player