#global variables

12 messages · Page 1 of 1 (latest)

latent tapir
#

global variables

dry sorrelBOT
#

Hi @latent tapir. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

In the context of Convex, "global variables" typically refer to global state managed by the Convex backend. This global state is shared and synchronized across all clients of your application, enabling real-time collaboration and consistency.

Convex allows you to manage this global state using its backend as a service, where data is stored in the Convex database and accessed via queries and mutations. For example, in multiplayer applications like Fast5, the global game state (such as the current round or player guesses) is managed on the backend and reactively updated for all clients. This is achieved by binding Convex query functions to frontend state management tools (like Recoil), ensuring that any change in the backend state is automatically reflected in the UI for all users. Here’s a simplified example of how a global state atom is kept in sync with Convex:

// Recoil atom for global state
export const backendRoundState = atom({
  key: 'backendRoundState',
  default: null,
});

// Bind Convex query to atom
const [, setBackendRound] = useRecoilState(backendRoundState);
const roundQuery = useQuery('queryRound', Id.fromString(gameId));

useEffect(() => {
  setBackendRound(roundQuery);
}, [roundQuery, setBackendRound]);

This approach ensures that the global state is authoritative and secure, as only the backend can be trusted to maintain the integrity of shared data, especially in scenarios where cheating or data tampering could be a concern (e.g., multiplayer games) Local and Remote State (Making Fast5 1), Backend Matters (Making Fast5 2).

#

If you meant "global variables" in the sense of environment variables, Convex also supports per-deployment environment variables, which are accessible in backend functions via process.env. These are not shared between clients but are used for configuration and secrets Environment Variables.

If you have a more specific use case or context for "global variables," please clarify!

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@latent tapir Kapa.ai is still learning and improving, please let me know how I did by reacting below.

latent tapir
#

@dry sorrel variables declared outside of mutation or query

dry sorrelBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Variables declared outside of a Convex mutation or query function (i.e., at the module/global scope) are allowed, but their values are not re-evaluated on every function run. Instead, they are initialized once when the module is loaded and persist for the lifetime of the server process. This means that if you assign a value to a variable at the top level (outside any function), it will not change between function runs, even if the underlying data or time changes.

For example, if you do:

const globalRand = Math.random(); // Only evaluated once when the module loads
const globalNow = Date.now();     // Only evaluated once when the module loads

export const updateSomething = mutation({
  args: {},
  handler: () => {
    // These values will not change between function runs
    console.log(globalRand, globalNow);
  },
});

If you want values that are fresh for each function execution (such as the current time or a new random number), you must declare and compute them inside the handler function. Convex ensures determinism and transactional guarantees by "freezing" system time and seeding randomness per function execution, but only within the function scope. Top-level variables are not re-evaluated per run and can lead to unexpected behavior if you expect them to update automatically.

For more details, see the section on restrictions on queries and mutations.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@latent tapir Kapa.ai is still learning and improving, please let me know how I did by reacting below.

latent tapir
#

@dry sorrel what about singleton

dry sorrelBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Convex does not support true singletons in the sense of a global, mutable variable that persists across function calls and is shared between all function executions. Variables declared outside of mutation or query functions are only initialized once per server process and do not update between function runs. This means you cannot use a module-level variable as a reliable singleton for shared, mutable state across your application.

If you need singleton-like behavior (such as a global counter or a unique resource), you should store that state in the Convex database and access it via queries and mutations. This ensures consistency, durability, and correct synchronization across all clients and function executions. For example, you might have a "counter" table with a single document, and mutations would read and update that document as needed.

This approach is necessary because Convex functions are designed to be deterministic and stateless outside of their database interactions, and any state you want to persist must be stored in the database, not in global variables or singletons in your code. For more details, see the explanation of global variables and determinism in Convex functions here.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: