> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Drive Ingestion

> Sync a Google Drive folder into cognee memory incrementally, with deleted files forgotten automatically

A minimal guide to ingesting a Google Drive folder into cognee. The Google Drive connector extracts Google Docs, Google Sheets, PDFs, and plain text, Markdown and CSV files from a folder — and, by default, its subfolders — then cognifies them like any other document. Re-running the sync only processes files that changed, and files removed from the folder are forgotten.

Anything else in the folder is skipped: Slides, Drawings, Forms, images, and Office formats such as `.docx` and `.xlsx`. So is any file over 25 MB (raise it with `GOOGLE_DRIVE_MAX_FILE_SIZE_MB`), and a Google Sheet contributes its first sheet only, which is all Drive's export returns. See [What gets indexed](/integrations/google-drive-integration#what-gets-indexed) for the full table — the hosted connector reads files through the same code path.

## Before You Start

* Complete [Quickstart](/getting-started/quickstart) to understand basic operations
* Ensure you have [LLM Providers](/setup-configuration/llm-providers) configured — the script calls `cognee.recall()`, which needs an LLM for the final completion
* Read [Datasets](/core-concepts/further-concepts/datasets) — the folder is synced into the `google_drive_demo` dataset
* Install the connector extra: `pip install "cognee[google-drive]"`
* Enable the Google Drive API in the Google Cloud Console and set up **one** of these auth modes:
  * **Service account** (recommended, no interactive step): create a service account, download a JSON key for it, and share the target folder with the service account's `client_email` (Viewer access is enough). Then set `GOOGLE_DRIVE_AUTH_MODE=service_account` and `GOOGLE_DRIVE_CREDENTIALS_PATH=/path/to/service-account.json`
  * **OAuth user credentials** (for a folder in your own My Drive): create an OAuth Client ID of type "Desktop app" and download its JSON. Then set `GOOGLE_DRIVE_AUTH_MODE=oauth`, `GOOGLE_DRIVE_CREDENTIALS_PATH=/path/to/oauth-client-secret.json`, and `GOOGLE_DRIVE_TOKEN_PATH=/path/to/cache-the-user-token.json`. The first run opens a browser for one-time consent; later runs reuse the cached, auto-refreshed token
* Set `GOOGLE_DRIVE_FOLDER_ID` to the folder's Drive ID, taken from its URL

<Note>
  This guide drives the connector from your own script, with credentials you hold on disk. If you instead want users to connect their own Drive account to a running Cognee backend over a web OAuth consent, use the [Google Drive integration](/integrations/google-drive-integration) — it is configured with a different set of `GOOGLE_DRIVE_*` variables (`GOOGLE_DRIVE_CLIENT_ID`, `GOOGLE_DRIVE_REDIRECT_URI`, and so on) and syncs over its own REST endpoints.
</Note>

## Code in Action

```python theme={null}
import asyncio

import cognee
from cognee.tasks.ingestion.connectors import google_drive_source


async def main():
    drive_source = google_drive_source()  # reads GOOGLE_DRIVE_* env vars

    print("=== Initial sync ===")
    result = await cognee.remember(
        drive_source,
        dataset_name="google_drive_demo",
        primary_key="id",
        # "merge" is required: it's what makes re-runs incremental and what
        # makes deletions propagate via orphan cleanup. The default
        # ("replace") would re-extract every file on every run instead.
        write_disposition="merge",
        # The DLT ingestion default caps a table at 50 rows; Drive folders
        # commonly exceed that, so lift the cap.
        max_rows_per_table=0,
    )
    print(result)

    answer = await cognee.recall("Summarize what's in the Drive folder.")
    print("Recall:", answer)

    print("\n=== Incremental re-sync (only changed/removed files are processed) ===")
    result = await cognee.remember(
        google_drive_source(),
        dataset_name="google_drive_demo",
        primary_key="id",
        write_disposition="merge",
        max_rows_per_table=0,
    )
    print(result)


if __name__ == "__main__":
    asyncio.run(main())
```

## What Just Happened

### Step 1: Create the Drive Source

```python theme={null}
drive_source = google_drive_source()  # reads GOOGLE_DRIVE_* env vars
```

`google_drive_source()` returns a dlt source for the folder. Called with no arguments, it takes the auth mode, credentials, token path, and folder ID from the `GOOGLE_DRIVE_*` environment variables set up in Before You Start.

### Step 2: Run the Initial Sync

```python theme={null}
result = await cognee.remember(
    drive_source,
    dataset_name="google_drive_demo",
    primary_key="id",
    # "merge" is required: it's what makes re-runs incremental and what
    # makes deletions propagate via orphan cleanup. The default
    # ("replace") would re-extract every file on every run instead.
    write_disposition="merge",
    # 0 = no row cap. This is already the default; pass it to be explicit,
    # or to override a positive DLT_MAX_ROWS_PER_TABLE.
    max_rows_per_table=0,
)
print(result)
```

Passing the source to `remember()` extracts every file, chunks it, and builds the graph. `primary_key="id"` keys each row by its Drive file ID, and `write_disposition="merge"` upserts on that key — which is what makes later runs incremental and lets deletions propagate.

`max_rows_per_table=0` means no row cap, but it changes nothing here: Google Drive is a document source, and Cognee always reads a document source's whole staging table, whatever `max_rows_per_table` or `DLT_MAX_ROWS_PER_TABLE` says. (The upstream script's inline comment still describes an older 50-row default, which cognee dropped in favor of unlimited ingestion.)

### Step 3: Recall From the Folder

```python theme={null}
answer = await cognee.recall("Summarize what's in the Drive folder.")
print("Recall:", answer)
```

Once synced, the folder's contents are ordinary cognee memory, so `recall()` can answer questions about them.

### Step 4: Re-Sync Incrementally

```python theme={null}
result = await cognee.remember(
    google_drive_source(),
    dataset_name="google_drive_demo",
    primary_key="id",
    write_disposition="merge",
    max_rows_per_table=0,
)
print(result)
```

The second call uses a fresh source with the same dataset, key, and write disposition. Only files that were added or changed since the previous run are processed, and files deleted or trashed in Drive are removed from memory. Run this on a schedule to keep the dataset in step with the folder.

<Columns cols={2}>
  <Card title="dlt (Data Load Tool)" icon="database" href="/integrations/dlt-integration">
    The dlt ingestion path the connector builds on, including write dispositions.
  </Card>

  <Card title="remember()" icon="brain" href="/python-api/remember">
    Every option `remember()` accepts when ingesting a source.
  </Card>
</Columns>
