# Storage Storage is a very important aspect of the library, which should not be overlooked. It is primarily used to handle caching and authorization (you wouldn't want to log in every time, right?). ## In-memory storage The simplest way to store data is to store it in-memory and never persist it anywhere, and this is exactly what `MemoryStorage` does. ```ts{4} import { MemoryStorage } from '@mtcute/core' const tg = new TelegramClient({ storage: new MemoryStorage() }) ``` ::: warning It is highly advised that you use some kind of persisted storage! With in-memory storage, you will need to re-authorize every time (assuming you don't use [session strings](#session-strings)), and also caching won't work past a single run. ::: ## SQLite storage The preferred storage for a server application is the one using SQLite, because it does not require loading the entire thing into memory, and is also faster than simply reading/writing a file. mtcute implements sqlite storages in runtime-specific packages, using the best libraries available for each runtime: - Node.js: [better-sqlite3](https://www.npmjs.com/package/better-sqlite3) - Bun: `bun:sqlite` - Deno: [@db/sqlite](https://jsr.io/@db/sqlite) ```ts{4} import { SqliteStorage } from '@mtcute/node' // or '@mtcute/bun' / '@mtcute/deno' const tg = new TelegramClient({ storage: new SqliteStorage('my-account.session') }) ``` ::: tip In runtime-specific packages, SQLite storage is the default, and you can simply pass a string with file name instead of instantiating `SqliteStorage` manually: ```ts const tg = new TelegramClient({ storage: 'my-account.session' }) ``` ::: To improve performance, we use WAL mode by default ([Learn more](https://github.com/JoshuaWise/better-sqlite3/blob/master/docs/performance.md)). When using WAL, along with your SQLite file there may also be `-shm` and `-wal` files. If you don't like seeing those files, instead of disabling WAL altogether, consider putting your storage in a folder (i.e. `new SqliteStorage('storage/my-account')`). If you are in fact having problems with WAL mode, you can disable it with `disableWal` parameter. ## IndexedDB storage The preferred storage for a Web application is the one using IndexedDB, which is basically a browser's version of SQLite. ```ts{4} import { IdbStorage } from '@mtcute/web' const tg = new TelegramClient({ storage: new IdbStorage('my-account') }) ``` > Note that the string passed will be used as-is as the database name, > so you might want to prefix it to avoid conflicts. ::: tip In `@mtcute/web`, IndexedDB storage is the default, and you can simply pass a string with file name instead of instantiating `IdbStorage` manually: ```ts const tg = new TelegramClient({ storage: 'my-account' }) ``` ::: ## Session strings Sometimes it might be useful to export storage data to a string, and import it later to another storage. For example, when deploying userbot applications to a server, where you'll be using another storage. To generate a session string, simply call `exportSession`: ```ts await tg.start() console.log(await tg.exportSession()) ``` This will output a fairly long string (about 400 chars) to your console, which can then be imported: ```ts const tg = new TelegramClient({...}) await tg.importSession(SESSION_STRING) // or await tg.start({ session: SESSION_STRING }) ``` You can import session into any storage, including in-memory storage. This may be useful when deploying to services like [Heroku](https://www.heroku.com), where their ephemeral file system makes it impossible to use file-based storage. ::: warning Anyone with this string will be able to authorize as you and do anything. Treat this as your password, and **never give it away**! In case you have accidentally leaked this string, make sure to revoke this session in account settings: "Privacy & Security" > "Active sessions" > find the one containing "mtcute" > Revoke, or, in case this is a bot, revoke bot token with [@BotFather](https://t.me/botfather) Also note that you can't log in with the same session string from multiple IPs at once, and that would immediately revoke that session. ::: ::: details What is included? You might be curious about the information that the session string includes, and why is it so long. Most of the string is occupied by 256 bytes long MTProto authorization key, which, when Base64 encoded, results in **344** characters. Additionally, information about user (their ID and whether the user is a bot) and their DC is included, which results in an average of ~**400** characters ::: ## Implementing custom storage The easiest way to implement a custom storage would be to make a subclass of `MemoryStorage`. Additionaly, mtcute abstracts away the sqlite storage implementation, so you can use the the `BaseSqliteStorage` API to implement sqlite storage using your library of choice (see [Node.js implementation](https://github.com/mtcute/mtcute/tree/master/packages/node/src/sqlite) for reference). ### Architecture A storage provider in mtcute is composed of: - **Driver**: the core of the storage, which handles reading and writing data to the storage and implements lifecycle methods like `load` and `save`. Driver also manages migrations for the storage, however the migrations themselves are not part of the driver, but are registered separately by repositories - **Repository**: a set of methods to read and write data of a specific entity to the storage, allowing for more efficient and organized access to the data. Repositories are registered in the driver and are used to access the data in the storage Such composable architecture allows for custom storages to implement a specific set of repositories, and to reuse the same driver for different providers. In mtcute, these sets of repositories are defined: - [IMtStorageProvider](https://ref.mtcute.dev/types/_mtcute_core.index.IMtStorageProvider.html), used by `BaseTelegramClient` for low-level MTProto data storage - [ITelegramStorageProvider](https://ref.mtcute.dev/interfaces/_mtcute_core.index.ITelegramStorageProvider.html), used by `TelegramClient` for basic caching and update handling operations required for the client to work - [IStateStorageProvider](https://ref.mtcute.dev/types/_mtcute_dispatcher.IStateStorageProvider.html), used by `Dispatcher` for FSM and Scenes storage