Production Checklist

This is a checklist for configuring and securing Cube.js for a production deployment.

When running Cube.js in production environments, make sure development mode is disabled. Running Cube.js in development mode in a production environment can lead to security vulnerabilities. You can read more on the differences between production and development mode here.

Note

Development mode is disabled by default.

# Set this to false or leave unset to disable development mode
CUBEJS_DEV_MODE=false

Cube.js requires Redis, an in-memory data structure store, to run in production.

It uses Redis for query caching and queue. Set the REDIS_URL environment variable to allow Cube.js to connect to Redis. If your Redis instance also has a password, please set it via the REDIS_PASSWORD environment variable. Set the REDIS_TLS environment variable to true if you want to enable SSL-secured connections. Ensure your Redis cluster allows at least 15 concurrent connections.

Note

Cube.js server instances used by same tenant environments should have same Redis instances. Otherwise they will have different query queues which can lead to incorrect pre-aggregation states and intermittent data access errors.

If REDIS_URL is provided Cube.js, will create a Redis connection pool with a minimum of 2 and maximum of 1000 concurrent connections, by default. The CUBEJS_REDIS_POOL_MIN and CUBEJS_REDIS_POOL_MAX environment variables can be used to tweak pool size limits. To disable connection pooling, and instead create connections on-demand, you can set CUBEJS_REDIS_POOL_MAX to 0.

If your maximum concurrent connections limit is too low, you may see TimeoutError: ResourceRequest timed out errors. As a rule of a thumb, you need to have Queue Size * Number of tenants concurrent connections to ensure the best performance possible. If you use clustered deployments, please make sure you have enough connections for all Cube.js server instances. A lower number of connections still can work, however Redis becomes a performance bottleneck in this case.

If you want to run Cube.js in production without Redis, you can use CUBEJS_CACHE_AND_QUEUE_DRIVER environment variable to memory.

Note

Serverless and clustered deployments can't be run without Redis as it is used to manage the query queue.

If you are using external pre-aggregations, you need to set up and configure external pre-aggregations storage.

Currently, we recommend using MySQL for external pre-aggregations storage. There is some additional MySQL configuration required to optimize for pre-aggregation ingestion and serving. The final configuration may vary depending on the specific use case.

To refresh in-memory cache and scheduled pre-aggregations in the background, we recommend running a separate Cube.js refresh worker instance. This allows your main Cube.js instance to continue to serve requests with high availability.

# Set to true so a Cube.js instance acts as a refresh worker
CUBEJS_SCHEDULED_REFRESH_TIMER=true

For Serverless deployments, use the Run Scheduled Refresh endpoint of the REST API instead of a refresh worker.

Production APIs should be served over HTTPS to be secure over the network.

Cube.js doesn't handle SSL/TLS for your API. To serve your API on HTTPS URL you should use a reverse proxy, like NGINX, Kong, Caddy or your cloud provider's load balancer SSL termination features.

Below you can find a sample nginx.conf to proxy requests to Cube.js. To learn how to set up SSL with NGINX please refer to NGINX docs.

server {
  listen 80;
  server_name cube.my-domain.com;

  location / {
    proxy_pass http://localhost:4000/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}