- Configure Authentication
- Enable HTTP TLS or gRPC TLS or both
- Set the log format to “json” and log level to “info”
- Disable the Playground
- Set Cluster
- Set Database Options
- Set Maximum Results
- Set Concurrency Limits
Cluster recommendations
We recommend:- Turn on in-memory caching in Check API via flags. This will reduce latency of requests, but it will increase the staleness of OpenFGA’s responses. Please see Cache Expiration for details on the flags.
- Prefer having a small pool of servers with high capacity (memory and CPU cores) instead of a big pool of servers, to increase cache hit ratios and simplify pool management.
- Turn on metrics collection via the flags
--metrics-enabledand--datastore-metrics-enabled. This will allow you to debug issues. - Turn on tracing via the flag
--trace-enabled, but set sampling ratio to a low value, for example--trace-sample-ratio=0.3. This will allow you to debug issues without overwhelming the tracing server. However, keep in mind that enabling tracing comes with a slight performance cost.
Database recommendations
To ensure good performance for OpenFGA, it is recommended that the database be:- Co-located in the same physical datacenter and network as your OpenFGA servers. This will minimize latency of database calls.
- Used exclusively for OpenFGA and not shared with other applications. This allows scaling the database independently and avoiding contention with your database.
- Bootstrapped and managed with the
openfga migratecommand. This will ensure the appropriate database indexes are created.
PostgreSQL
For PostgreSQL, tune the server database with the following parameters:- OPENFGA_DATASTORE_MIN_OPEN_CONNS: This parameter should be the minimum number of database connections you want to maintain. This helps ensure that a baseline pool of connections is always available. As a starting point, consider setting this to a small, fixed baseline (for example between 5 and 20 connections), or roughly 10–30% of the maximum connections your PostgreSQL instance allows, while ensuring it does not exceed that database limit. If you are running multiple instances of the OpenFGA server, you should divide this setting equally among the instances.
-
OPENFGA_DATASTORE_MIN_IDLE_CONNS: This parameter controls the minimum number of connections to keep in the idle pool. This value must not exceed
OPENFGA_DATASTORE_MIN_OPEN_CONNS, since OpenFGA validates on startup thatMinOpenConns >= MinIdleConns. As a starting point, set this to around 50–75% of yourOPENFGA_DATASTORE_MIN_OPEN_CONNSvalue to maintain a stable connection pool and avoid the overhead of frequently recreating connections, then adjust based on observed connection churn and database load. -
The server setting OPENFGA_DATASTORE_MAX_OPEN_CONNS should be set to be equal to your database’s max connections. For example, in Postgres, you can see this value via running the SQL query
SHOW max_connections;. If you are running multiple instances of the OpenFGA server, you should divide this setting equally among the instances. For example, if your database’smax_connectionsis 100, and you have 2 OpenFGA instances,OPENFGA_DATASTORE_MAX_OPEN_CONNSshould be set to 50 for each instance.
MySQL and SQLite
For MySQL and SQLite, tune the server database with the following parameters:-
The server setting OPENFGA_DATASTORE_MAX_OPEN_CONNS should be set to be equal to your database’s max connections. For example, in MySQL, you can see this value via running the SQL query
SHOW VARIABLES LIKE 'max_connections';. If you are running multiple instances of the OpenFGA server, you should divide this setting equally among the instances. For example, if your database’smax_connectionsis 100, and you have 2 OpenFGA instances,OPENFGA_DATASTORE_MAX_OPEN_CONNSshould be set to 50 for each instance. - The OPENFGA_DATASTORE_MAX_IDLE_CONNS should be set to a value no greater than the maximum open connections (see the bullet point above), but it should be set sufficiently high enough to avoid having to recreate connections on each request.
OPENFGA_DATASTORE_MAX_IDLE_CONNS to the same number as OPENFGA_DATASTORE_MAX_OPEN_CONNS.
- If idle connections are getting reaped frequently, then consider increasing the OPENFGA_DATASTORE_CONN_MAX_IDLE_TIME to a large value. When in doubt, prioritize keeping connections around for longer rather than shorter, because doing so will drastically improve performance.
Concurrency limits
Before modifying concurrency limits please make sure you’ve followed the guidance for Database Recommendations
Determining the right values for these settings will be based on a variety of factors including, but not limited to, the database specific deployment topology, the FGA model(s) involved, and the relationship tuples in the system. However, here are some high-level guidelines:
-
If a single ListObjects or ListUsers query is negatively impacting other query endpoints by increasing their latency or their error rate, then consider setting a lower value for
OPENFGA_MAX_CONCURRENT_READS_FOR_LIST_OBJECTSorOPENFGA_MAX_CONCURRENT_READS_FOR_LIST_USERS. -
If a single Check query is negatively impacting other query endpoints by increasing their latency or their error rate, then consider setting a lower value for
OPENFGA_MAX_CONCURRENT_READS_FOR_CHECK.
OPENFGA_RESOLVE_NODE_LIMIT and OPENFGA_RESOLVE_NODE_BREADTH_LIMIT settings, respectively. Consider these guidelines:
-
OPENFGA_RESOLVE_NODE_LIMITlimits the resolution depth of a single query, and thus it sets an upper bound on how deep a relationship hierarchy may be. A high value will allow a single query to involve more hierarchical resolution and therefore more database queries, while a low value will reduce the number of hierarchical resolutions that will be allowed and thus reduce the number of database queries. -
OPENFGA_RESOLVE_NODE_BREADTH_LIMITlimits the resolution breadth. It sets an upper bound on the number of in-flight resolutions that can be taking place on one or more usersets. A high value will allow a single query to involve more concurrent evaluations to take place and therefore more database queries and server processes, while a low value will reduce the overall number of concurrent resolutions that will be allowed and thus reduce the number of database queries and server processes.
Maximum results
Both the ListObjects and ListUsers endpoints will continue retrieving results until one of the following conditions is met:- The maximum number of results is found
- The entire pool of possible results has been searched
- The API times out
OPENFGA_LIST_OBJECTS_MAX_RESULTS or OPENFGA_LIST_USERS_MAX_RESULTS configuration properties. This adjustment can lead to immediate improvements in time and resource efficiency.
Related Sections
Check the following sections for more on how to run OpenFGA in production environment.Data and API Best Practices
Learn the best practices for managing data and invoking APIs in production environment
Migrating Relations
Learn how to migrate relations in a production environment