> Discover all available pages from the documentation index: https://mastra.ai/llms.txt # OracleDB storage The OracleDB storage provider stores Mastra application state in Oracle Database. It implements Mastra's composite storage interface, so one `OracleStore` instance can back memory, workflow snapshots, observability, scores, scorer definitions, MCP client metadata, and agent registry data. ## Installation **npm**: ```bash npm install @mastra/oracledb@latest ``` **pnpm**: ```bash pnpm add @mastra/oracledb@latest ``` **Yarn**: ```bash yarn add @mastra/oracledb@latest ``` **Bun**: ```bash bun add @mastra/oracledb@latest ``` ## Usage ```ts import { OracleStore } from '@mastra/oracledb' const storage = new OracleStore({ id: 'oracle-storage', user: process.env.ORACLE_DATABASE_USER, password: process.env.ORACLE_DATABASE_PASSWORD, connectString: process.env.ORACLE_DATABASE_CONNECT_STRING, }) ``` Use it with Mastra: ```ts import { Mastra } from '@mastra/core/mastra' export const mastra = new Mastra({ storage, }) ``` ## Parameters **id** (`string`): Unique identifier for this storage instance. **user** (`string`): Oracle Database user. Required unless using pool or externalAuth. **password** (`string`): Password for the Oracle Database user. Required unless using pool or externalAuth. **connectString** (`string`): Oracle connect string, service name, TNS alias, or Autonomous Database connect descriptor. Required unless using pool. **pool** (`oracledb.Pool`): Existing Oracle connection pool. When provided, Mastra uses the pool but doesn't close it when store.close() is called. **poolManager** (`OraclePoolManager`): Shared Oracle pool manager. Use this to share one Oracle pool between OracleStore and OracleVector. **schemaName** (`string`): Oracle schema name used to qualify storage tables. **poolMin** (`number`): Minimum number of Oracle pool connections. (Default: `0`) **poolMax** (`number`): Maximum number of Oracle pool connections. (Default: `4`) **poolIncrement** (`number`): Number of connections to add when the pool grows. (Default: `1`) **configDir** (`string`): Directory containing Oracle Network configuration files such as tnsnames.ora. **walletLocation** (`string`): Oracle wallet directory for mTLS connections such as Autonomous Database. **walletPassword** (`string`): Password for the Oracle wallet, when required by the wallet configuration. **externalAuth** (`boolean`): Use Oracle external authentication instead of username/password authentication. **disableInit** (`boolean`): When true, automatic schema initialization is disabled. Use this when schema changes are applied separately before the app starts. (Default: `false`) **messageBatchSize** (`number`): Number of messages sent per Oracle executeMany call when saving messages. The operation still commits once at the transaction boundary. (Default: `200`) **skipDefaultIndexes** (`boolean`): When true, default storage indexes aren't created during initialization. **indexes** (`OracleCreateIndexOptions[]`): Custom Oracle index definitions to create during initialization. Indexes are routed to the storage domain that owns the target table. **migrationTableName** (`string`): Oracle table used to track storage schema migrations. (Default: `'MASTRA_ORACLE_MIGRATIONS'`) **vectorRegistryTableName** (`string`): OracleVector registry table used to discover semantic-recall vector tables when threads or messages are deleted. Set this to match OracleVector's registryTableName when that option is customized. ## Connection examples The basic username/password constructor is shown above. For Autonomous Database, add wallet options to the same constructor: ```ts const storage = new OracleStore({ id: 'oracle-storage', user: process.env.ORACLE_DATABASE_USER, password: process.env.ORACLE_DATABASE_PASSWORD, connectString: process.env.ORACLE_DATABASE_CONNECT_STRING, walletLocation: process.env.ORACLE_DATABASE_WALLET_DIR, walletPassword: process.env.ORACLE_DATABASE_WALLET_PASSWORD, configDir: process.env.ORACLE_DATABASE_CONFIG_DIR, }) ``` For external authentication, set `externalAuth: true` and omit `password`. To reuse an existing `oracledb.Pool`, pass it as `pool`. Mastra uses it but doesn't close it. `OracleStore` backs memory, workflow snapshots, observability, scores, scorer definitions, MCP client metadata, and agent registry data. When using the store outside a `Mastra` instance, call `await storage.init()` and access a domain with `await storage.getStore('memory')`. ## Initialization When you pass `OracleStore` to `Mastra`, `init()` is called automatically before storage operations run. If you use `OracleStore` directly, call `init()` before reading or writing: ```ts await storage.init() ``` > **Warning:** If initialization is disabled or skipped, storage operations require the Oracle tables and indexes to already exist. `OracleStore.init()` runs repeatable migrations and records the result in the migration ledger table. The default ledger table is `MASTRA_ORACLE_MIGRATIONS`. ```ts await storage.migrate() const history = await storage.listMigrations() ``` Repeatable migrations are idempotent. They reconcile the tables and indexes owned by each storage domain on startup, which lets new domain indexes or compatible schema additions apply without changing application code. Initialization also creates the provider's default indexes for common Mastra query paths. Use `skipDefaultIndexes` when indexes are managed separately, or pass `indexes` for custom Oracle indexes. Custom definitions support Oracle options such as `bitmap`, `online`, `invisible`, `parallel`, `compress`, `noLogging`, and `reverse`, as well as function-based expressions like `JSON_VALUE(...)`. Custom indexes are useful when your app repeatedly filters on JSON metadata or when database administrators (DBAs) want to test an index before the optimizer uses it: ```ts const storage = new OracleStore({ id: 'oracle-storage', user, password, connectString, indexes: [ { name: 'idx_messages_status', table: 'mastra_messages', columns: [ "JSON_VALUE(metadata, '$.status' RETURNING VARCHAR2(32) NULL ON ERROR)", 'thread_id', ], online: true, invisible: true, }, ], }) ``` Use `invisible` for staged rollout, then remove it after validating query plans. Use `skipDefaultIndexes: true` only when a DBA-managed indexing strategy replaces the defaults. Use `disableInit: true` when schema changes are applied by a separate deployment step or by a database administrator. ## Schema export Use `exportSchemas()` to generate Oracle DDL without connecting to a database. This is useful when schema changes are reviewed or applied outside application startup. ```ts import { exportSchemas } from '@mastra/oracledb' const ddl = exportSchemas({ schemaName: 'MASTRA_APP', domains: [ 'memory', 'workflows', 'observability', 'scores', 'scorerDefinitions', 'mcpClients', 'agents', ], }) console.log(ddl) ``` `domains` defaults to every supported domain, including `vector`, when omitted. ## Operational notes Use the same `OraclePoolManager` when `OracleStore` and `OracleVector` should share one Oracle connection lifecycle: ```ts import { OracleStore, OracleVector } from '@mastra/oracledb' const storage = new OracleStore({ id: 'oracle-storage', user, password, connectString }) const vector = new OracleVector({ id: 'oracle-vector', poolManager: storage.getPoolManager(), }) ``` `OracleStore` exposes `storage.db` and `await storage.getPool()` for advanced use cases. When using these APIs directly, you're responsible for transaction boundaries and connection lifecycle. JSON metadata, payloads, and snapshots are stored in native Oracle JSON columns and encoded server-side, so the rows are readable directly with standard Oracle JDBC tools such as DBeaver and SQL Developer. ## Usage example ### Adding OracleDB memory to an agent ```ts import { Agent } from '@mastra/core/agent' import { Memory } from '@mastra/memory' import { OracleStore } from '@mastra/oracledb' const storage = new OracleStore({ id: 'oracle-storage', user: process.env.ORACLE_DATABASE_USER, password: process.env.ORACLE_DATABASE_PASSWORD, connectString: process.env.ORACLE_DATABASE_CONNECT_STRING, }) export const oracleAgent = new Agent({ id: 'oracle-agent', name: 'Oracle Agent', instructions: 'You are an assistant with persistent OracleDB-backed memory.', model: 'openai/gpt-5.6-sol', memory: new Memory({ storage }), }) ``` ## Related - [OracleDB vector store](https://mastra.ai/reference/vectors/oracledb) - [Storage overview](https://mastra.ai/reference/storage/overview) - [Working memory](https://mastra.ai/docs/memory/working-memory) - [Workflow snapshots](https://mastra.ai/docs/workflows/snapshots)