This is a checklist for configuring and securing Cube for a production deployment.
When running Cube in production environments, make sure development mode is disabled both on API Instances and Refresh Worker. Running Cube in development mode in a production environment can lead to security vulnerabilities. Enabling Development Mode in Cube Cloud is not recommended. Development Mode will expose your data to the internet. You can read more on the differences between production and development mode here.
Development mode is disabled by default.
# Set this to false or leave unset to disable development mode CUBEJS_DEV_MODE=false
To refresh in-memory cache and pre-aggregations in the background, we recommend running a separate Cube Refresh Worker instance. This allows your Cube API Instance to continue to serve requests with high availability.
# Set to true so a Cube instance acts as a refresh worker CUBEJS_REFRESH_WORKER=true
While Cube can operate with in-memory cache and queue storage, there're multiple parts of Cube which require Cube Store in production mode. Replicating Cube instances without Cube Store can lead to source database degraded performance, various race conditions and cached data inconsistencies.
Cube Store manages in-memory cache, queue and pre-aggregations for Cube. Follow the instructions here to set it up.
Depending on your database, Cube may need to "stage" pre-aggregations inside
your database first before ingesting them into Cube Store. In this case, Cube
will require write access to the
prod_pre_aggregations schema inside your
database. The schema name can be modified by the
variable; see the Environment Variables reference for more
You may consider enabling an export bucket which allows Cube to build large pre-aggregations in a much faster manner. It is currently supported for BigQuery, Redshift and Snowflake. Check the relevant documentation for your configured database to set it up.
If you're using JWTs, you can configure Cube to correctly decode them and inject
their contents into the Security Context. Add your authentication
provider's configuration under the
jwt property of your
configuration file, or if using environment variables, see
CUBEJS_JWT_* in the Environment Variables
Cube provides Kubernetes-API compatible (opens in a new tab) health check
(or probe) endpoints that indicate the status of the deployment. Configure your
monitoring service of choice to use the
/livez API endpoints so you can check on the Cube
deployment's health and be alerted to any issues.
There's no one-size-fits-all when it comes to sizing a Cube cluster and its resources. Resources required by Cube significantly depend on the amount of traffic Cube needs to serve and the amount of data it needs to process. The following sizing estimates are based on default settings and are very generic, which may not fit your Cube use case, so you should always tweak resources based on consumption patterns you see.
Each Cube cluster should contain at least 2 Cube API instances. Every Cube API instance should have at least 3GB of RAM and 2 CPU cores allocated for it.
Refresh workers tend to be much more CPU and memory intensive, so at least 6GB
of RAM is recommended. Please note that to take advantage of all available RAM,
the Node.js heap size should be adjusted accordingly by using the
--max-old-space-size option (opens in a new tab):
The Cube Store router node should have at least 6GB of RAM and 4 CPU cores allocated for it. Every Cube Store worker node should have at least 8GB of RAM and 4 CPU cores allocated for it. The Cube Store cluster should have at least two worker nodes.
Depending on data model size, every Core Cube API instance can serve 1 to 10
requests per second. Every Core Cube Store router node can serve 50-100 queries
per second. As a rule of thumb, you should provision 1 Cube Store worker node
per one Cube Store partition or 1M of rows scanned in a query. For example if
your queries scan 16M of rows per query, you should have at least 16 Cube Store
worker nodes provisioned. Please note that the number of raw data rows doesn't
usually equal the number of rows in pre-aggregation. At the same time, queries
don't usually scan all the data in pre-aggregations, as Cube Store uses
partition pruning to optimize queries.
EXPLAIN ANALYZE can be used to see
scanned partitions involved in a Cube Store query. Cube Cloud ballpark
performance numbers can differ as it has different Cube runtime.