Handle Obsidian file system operations and throttling patterns.
Use when processing many files, handling bulk operations,
or preventing performance issues from excessive operations.
Trigger with phrases like "obsidian rate limit", "obsidian bulk operations",
"obsidian file throttling", "obsidian performance limits".
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Handle Obsidian file system operations and throttling patterns.
Use when processing many files, handling bulk operations,
or preventing performance issues from excessive operations.
Trigger with phrases like "obsidian rate limit", "obsidian bulk operations",
"obsidian file throttling", "obsidian performance limits".
allowed-tools
Read, Write, Edit
version
1.13.0
license
MIT
author
Jeremy Longshore <jeremy@intentsolutions.io>
tags
["saas","obsidian","performance"]
compatibility
Designed for Claude Code, also compatible with Codex and OpenClaw
Obsidian Rate Limits
Overview
Obsidian has no traditional API rate limits, but it runs on Electron with a single-threaded UI. This skill covers debouncing, batching, throttling, and async queue patterns to keep plugins responsive and prevent UI freezes.
Prerequisites
Understanding of JavaScript event loop and requestAnimationFrame
Familiarity with async/await and Promises
Working Obsidian plugin with file operations
Instructions
Step 1: Debounce vault.on('modify') Events
vault.on('modify') fires on every keystroke when a user types in a note. Without debouncing, your handler runs hundreds of times per second.
import { Plugin, TFile, debounce } from'obsidian';
exportdefaultclassThrottledPluginextendsPlugin {
asynconload() {
// Obsidian provides a built-in debounce utilityconst debouncedHandler = debounce(
(file: TFile) =>this.handleFileModified(file),
500, // wait 500ms after last keystroketrue// run on leading edge too (immediate first call)
);
this.registerEvent(
this.app.vault.on('modify', debouncedHandler)
);
}
private () {
cache = ...(file);
(cache?.?.) {
.(file);
}
}
}
async
handleFileModified
file: TFile
// This runs at most once per 500ms per burst of edits
const
this
app
metadataCache
getFileCache
if
frontmatter
tracked
await
this
updateIndex
If you need per-file debouncing (common when multiple files change simultaneously):
Periodic tasks with registerInterval and overlap guards
Error Handling
Issue
Cause
Solution
UI freezes during bulk operation
Processing all files synchronously
Batch with await sleep(0) between batches
Data corruption
Concurrent writes to same file
Use a write queue to serialize operations
Memory pressure on large vaults
Loading all file contents at once
Process in batches of 50, release references
Missed file changes
Debounce interval too long
Keep debounce under 500ms; use leading edge
Timers leak after disable
Using raw setInterval
Always use this.registerInterval()
Layout thrashing
Updating DOM on every event
Coalesce with requestAnimationFrame
Examples
Vault Statistics Collector
// Efficient vault scan that doesn't freeze UIasyncgetVaultStats(): Promise<{ total: number; words: number }> {
const files = this.app.vault.getMarkdownFiles();
let words = 0;
for (let i = 0; i < files.length; i += 50) {
const batch = files.slice(i, i + 50);
for (const file of batch) {
const content = awaitthis.app.vault.cachedRead(file);
words += content.split(/\s+/).length;
}
awaitsleep(0);
}
return { total: files.length, words };
}
Debounced Search Index Rebuild
// Rebuild search index at most once per 2 secondsprivate rebuildIndex = debounce(async () => {
const files = this.app.vault.getMarkdownFiles();
this.index.clear();
for (const file of files) {
const cache = this.app.metadataCache.getFileCache(file);
if (cache?.frontmatter) {
this.index.set(file.path, cache.frontmatter);
}
}
}, 2000, true);
For event handling patterns that complement these throttling strategies, see obsidian-webhooks-events. For production deployment readiness, see obsidian-prod-checklist.