Skip to content

Attachments & Media

N2O downloads images and files from Notion and stores them locally in your vault — so everything works offline, and Notion’s expiring S3 URLs never cause broken embeds.


Downloaded media lands in _files/ subfolders placed next to the content that references them:

Notion/
├── Projects/ ← database folder
│ ├── _files/ ← all media for items in this database
│ │ ├── photo-a1b2c3d4.png
│ │ └── report-f9e8d7c6.pdf
│ ├── Project Alpha.md
│ └── Project Beta.md
└── _pages/ ← standalone pages folder
├── _files/ ← all media for standalone pages
│ └── banner-7c3f1a2b.jpg
└── Meeting Notes.md

Database items share one _files/ folder per database. Standalone pages (not inside a database) share one _files/ folder inside your standalone pages folder (default: _pages/).


Downloaded files use content-addressed naming:

{original-name}-{8-char-hash}.{ext}

The hash is based on the file content, which means:

  • The same file always gets the same name — no duplicates
  • Different files with the same name get different hashes — no collisions
  • Filenames stay stable across re-syncs — Obsidian links never break

Example: screenshot-a1b2c3d4.png, report-f9e8d7c6.pdf


Notion hosts uploaded files on Amazon S3 with signed URLs that expire after about 1 hour. N2O handles this automatically:

  • Files are downloaded immediately during sync (before URLs expire)
  • If a download fails, N2O marks the page and retries on the next sync — getting a fresh URL from Notion

If you see a broken image after sync, running sync again will fix it.


Notion-hosted images, videos, and PDFs are protected during push. If you edit text around an image in Obsidian and push the changes, N2O detects which media was originally uploaded to Notion and preserves it — the file itself stays untouched in Notion.

Cover images are display-only in Obsidian. The cover photo from a Notion page is downloaded and shown in Obsidian, but it is not pushed back to Notion. Editing or removing the cover: frontmatter field has no effect on your Notion cover.

External URL images (not uploaded to Notion, just linked) can be replaced on push — they’re treated as regular content, not as protected media.


TypeFormats
ImagesJPEG, PNG, GIF, WebP, SVG, AVIF, HEIC
VideoMP4, WebM, MOV
AudioMP3, OGG, WAV, FLAC
DocumentsPDF
OtherAny file attached via Notion’s file block

N2O detects file types from the Content-Type header, file magic bytes, or URL extension — in that order. If detection fails, files are saved as .bin.


Cover photos are downloaded to _files/ and referenced in frontmatter:

cover: "cover-a1b2c3d4.jpg"

Icons appear in frontmatter as-is for emoji, or mapped to the closest emoji for Notion’s built-in SVG icons:

icon: "🚀"

When Generate Thumbnails is enabled (on by default, under Sync Configuration > Sync Behavior), N2O generates smaller versions of large cover images:

  • Stored in _files/_thumbs/
  • Max 800px wide, 85% JPEG quality
  • Only for files over 512 KB
  • Skipped for GIF, SVG, ICO, BMP

Thumbnails are used as preview images in Bases gallery and card views — they load faster than full-size covers.


Images linked from external URLs (not uploaded to Notion) are also downloaded when possible, and stored in _files/ like any other attachment.

N2O blocks downloads from private/loopback addresses (localhost, 127.0.0.1, private IP ranges) to prevent SSRF. If an external server blocks the download, the image stays as a remote URL:

![Description](https://example.com/image.png)

LimitValue
Per-file timeout60 seconds
Large file warning50 MB
Total per sync warning100 MB
Concurrent downloads3

These are soft warnings, not hard stops — N2O logs them but continues syncing.


When a page is deleted from Notion or an image block is removed, the downloaded file in _files/ becomes an orphan. N2O scans for orphaned attachments during sync and removes them automatically.


If you prefer to keep images as remote URLs rather than downloading them, toggle off Download Media in Sync Configuration > Sync Behavior. Images will remain as external URL references in your Markdown.