diff --git a/src/vs/base/common/glob.ts b/src/vs/base/common/glob.ts
index 6c2b7680f8b3d..8b750c0924f97 100644
--- a/src/vs/base/common/glob.ts
+++ b/src/vs/base/common/glob.ts
@@ -355,9 +355,7 @@ function parsePattern(arg1: string | IRelativePattern, options: IGlobOptions): P
 		...options,
 		equals: ignoreCase ? equalsIgnoreCase : (a: string, b: string) => a === b,
 		endsWith: ignoreCase ? endsWithIgnoreCase : (str: string, candidate: string) => str.endsWith(candidate),
-		// TODO: the '!isLinux' part below is to keep current behavior unchanged, but it should probably be removed
-		// in favor of passing correct options from the caller.
-		isEqualOrParent: (base: string, candidate: string) => isEqualOrParent(base, candidate, !isLinux || ignoreCase)
+		isEqualOrParent: (base: string, candidate: string) => isEqualOrParent(base, candidate, options.ignoreCase ?? !isLinux /* preserve old behaviour for when option is not adopted */)
 	};
 
 	// Check cache
@@ -371,13 +369,13 @@ function parsePattern(arg1: string | IRelativePattern, options: IGlobOptions): P
 	let match: RegExpExecArray | null;
 	if (T1.test(pattern)) {
 		parsedPattern = trivia1(pattern.substring(4), pattern, internalOptions); 			// common pattern: **/*.txt just need endsWith check
-	} else if (match = T2.exec(trimForExclusions(pattern, internalOptions))) { 	// common pattern: **/some.txt just need basename check
+	} else if (match = T2.exec(trimForExclusions(pattern, internalOptions))) { 				// common pattern: **/some.txt just need basename check
 		parsedPattern = trivia2(match[1], pattern, internalOptions);
-	} else if ((options.trimForExclusions ? T3_2 : T3).test(pattern)) { // repetition of common patterns (see above) {**/*.txt,**/*.png}
+	} else if ((options.trimForExclusions ? T3_2 : T3).test(pattern)) { 					// repetition of common patterns (see above) {**/*.txt,**/*.png}
 		parsedPattern = trivia3(pattern, internalOptions);
-	} else if (match = T4.exec(trimForExclusions(pattern, internalOptions))) { 	// common pattern: **/something/else just need endsWith check
+	} else if (match = T4.exec(trimForExclusions(pattern, internalOptions))) { 				// common pattern: **/something/else just need endsWith check
 		parsedPattern = trivia4and5(match[1].substring(1), pattern, true, internalOptions);
-	} else if (match = T5.exec(trimForExclusions(pattern, internalOptions))) { 	// common pattern: something/else just need equals check
+	} else if (match = T5.exec(trimForExclusions(pattern, internalOptions))) { 				// common pattern: something/else just need equals check
 		parsedPattern = trivia4and5(match[1], pattern, false, internalOptions);
 	}
 
diff --git a/src/vs/workbench/api/common/extHostFileSystemEventService.ts b/src/vs/workbench/api/common/extHostFileSystemEventService.ts
index 685b854451c3f..38ce2571b0200 100644
--- a/src/vs/workbench/api/common/extHostFileSystemEventService.ts
+++ b/src/vs/workbench/api/common/extHostFileSystemEventService.ts
@@ -5,7 +5,7 @@
 
 import { Emitter, Event, AsyncEmitter, IWaitUntil, IWaitUntilData } from '../../../base/common/event.js';
 import { GLOBSTAR, GLOB_SPLIT, IRelativePattern, parse } from '../../../base/common/glob.js';
-import { URI } from '../../../base/common/uri.js';
+import { URI, UriComponents } from '../../../base/common/uri.js';
 import { ExtHostDocumentsAndEditors } from './extHostDocumentsAndEditors.js';
 import type * as vscode from 'vscode';
 import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, SourceTargetPair, IWorkspaceEditDto, IWillRunFileOperationParticipation, MainContext, IRelativePatternDto } from './extHost.protocol.js';
@@ -52,7 +52,7 @@ class FileSystemWatcher implements vscode.FileSystemWatcher {
 		return Boolean(this._config & 0b100);
 	}
 
-	constructor(mainContext: IMainContext, configuration: ExtHostConfigProvider, fileSystemInfo: ExtHostFileSystemInfo, workspace: IExtHostWorkspace, extension: IExtensionDescription, dispatcher: Event<FileSystemEvents>, globPattern: string | IRelativePatternDto, options: FileSystemWatcherCreateOptions) {
+	constructor(mainContext: IMainContext, configuration: ExtHostConfigProvider, fileSystemInfo: ExtHostFileSystemInfo, workspace: IExtHostWorkspace, extension: IExtensionDescription, dispatcher: Event<LazyRevivedFileSystemEvents>, globPattern: string | IRelativePatternDto, options: FileSystemWatcherCreateOptions) {
 		this._config = 0;
 		if (options.ignoreCreateEvents) {
 			this._config += 0b001;
@@ -68,7 +68,18 @@ class FileSystemWatcher implements vscode.FileSystemWatcher {
 			!((fileSystemInfo.getCapabilities(Schemas.file) ?? 0) & FileSystemProviderCapabilities.PathCaseSensitive) :
 			fileSystemInfo.extUri.ignorePathCasing(URI.revive(globPattern.baseUri));
 
-		const parsedPattern = parse(globPattern, { ignoreCase });
+		// Performance: pre-lowercase pattern and paths to use fast case-sensitive
+		// matching instead of repeated case-insensitive comparisons in the hot loop.
+		// By normalizing to lowercase upfront, we enforce `ignoreCase: false` so the
+		// glob parser uses strict `===` / `endsWith` instead of character-by-character
+		// case-folding on every comparison.
+		let matchGlob: string | IRelativePattern = globPattern;
+		if (ignoreCase) {
+			matchGlob = typeof globPattern === 'string'
+				? globPattern.toLowerCase()
+				: { base: globPattern.base.toLowerCase(), pattern: globPattern.pattern.toLowerCase() };
+		}
+		const parsedPattern = parse(matchGlob, { ignoreCase: false /* speeds up matching, but requires us to lowercase paths and patterns */ });
 
 		// 1.64.x behavior change: given the new support to watch any folder
 		// we start to ignore events outside the workspace when only a string
@@ -95,25 +106,22 @@ class FileSystemWatcher implements vscode.FileSystemWatcher {
 			}
 
 			if (!options.ignoreCreateEvents) {
-				for (const created of events.created) {
-					const uri = URI.revive(created);
-					if (parsedPattern(uri.fsPath) && (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri))) {
+				for (const { uri, lowerCaseFsPath } of events.created) {
+					if (parsedPattern(ignoreCase ? lowerCaseFsPath : uri.fsPath) && (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri))) {
 						this._onDidCreate.fire(uri);
 					}
 				}
 			}
 			if (!options.ignoreChangeEvents) {
-				for (const changed of events.changed) {
-					const uri = URI.revive(changed);
-					if (parsedPattern(uri.fsPath) && (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri))) {
+				for (const { uri, lowerCaseFsPath } of events.changed) {
+					if (parsedPattern(ignoreCase ? lowerCaseFsPath : uri.fsPath) && (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri))) {
 						this._onDidChange.fire(uri);
 					}
 				}
 			}
 			if (!options.ignoreDeleteEvents) {
-				for (const deleted of events.deleted) {
-					const uri = URI.revive(deleted);
-					if (parsedPattern(uri.fsPath) && (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri))) {
+				for (const { uri, lowerCaseFsPath } of events.deleted) {
+					if (parsedPattern(ignoreCase ? lowerCaseFsPath : uri.fsPath) && (!excludeOutOfWorkspaceEvents || workspace.getWorkspaceFolder(uri))) {
 						this._onDidDelete.fire(uri);
 					}
 				}
@@ -247,18 +255,28 @@ interface IExtensionListener<E> {
 	(e: E): any;
 }
 
-class LazyRevivedFileSystemEvents implements FileSystemEvents {
+interface RevivedFileSystemEvent {
+	readonly uri: URI;
+	readonly lowerCaseFsPath: string;
+}
+
+class LazyRevivedFileSystemEvents {
 
 	readonly session: number | undefined;
 
-	private _created = new Lazy(() => this._events.created.map(URI.revive) as URI[]);
-	get created(): URI[] { return this._created.value; }
+	private _created = new Lazy(() => this._events.created.map(LazyRevivedFileSystemEvents._revive));
+	get created(): RevivedFileSystemEvent[] { return this._created.value; }
 
-	private _changed = new Lazy(() => this._events.changed.map(URI.revive) as URI[]);
-	get changed(): URI[] { return this._changed.value; }
+	private _changed = new Lazy(() => this._events.changed.map(LazyRevivedFileSystemEvents._revive));
+	get changed(): RevivedFileSystemEvent[] { return this._changed.value; }
 
-	private _deleted = new Lazy(() => this._events.deleted.map(URI.revive) as URI[]);
-	get deleted(): URI[] { return this._deleted.value; }
+	private _deleted = new Lazy(() => this._events.deleted.map(LazyRevivedFileSystemEvents._revive));
+	get deleted(): RevivedFileSystemEvent[] { return this._deleted.value; }
+
+	private static _revive(uriComponents: UriComponents): RevivedFileSystemEvent {
+		const uri = URI.revive(uriComponents);
+		return { uri, lowerCaseFsPath: uri.fsPath.toLowerCase() };
+	}
 
 	constructor(private readonly _events: FileSystemEvents) {
 		this.session = this._events.session;
@@ -267,7 +285,7 @@ class LazyRevivedFileSystemEvents implements FileSystemEvents {
 
 export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServiceShape {
 
-	private readonly _onFileSystemEvent = new Emitter<FileSystemEvents>();
+	private readonly _onFileSystemEvent = new Emitter<LazyRevivedFileSystemEvents>();
 
 	private readonly _onDidRenameFile = new Emitter<vscode.FileRenameEvent>();
 	private readonly _onDidCreateFile = new Emitter<vscode.FileCreateEvent>();
diff --git a/src/vs/workbench/api/test/browser/extHostFileSystemEventService.test.ts b/src/vs/workbench/api/test/browser/extHostFileSystemEventService.test.ts
index 6c8569d03ac6e..5de7a467c47e4 100644
--- a/src/vs/workbench/api/test/browser/extHostFileSystemEventService.test.ts
+++ b/src/vs/workbench/api/test/browser/extHostFileSystemEventService.test.ts
@@ -8,20 +8,34 @@ import { IMainContext } from '../../common/extHost.protocol.js';
 import { NullLogService } from '../../../../platform/log/common/log.js';
 import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
 import { ExtHostFileSystemInfo } from '../../common/extHostFileSystemInfo.js';
+import { URI } from '../../../../base/common/uri.js';
+import { FileSystemProviderCapabilities } from '../../../../platform/files/common/files.js';
+import { IExtHostWorkspace } from '../../common/extHostWorkspace.js';
+import { RelativePattern } from '../../common/extHostTypes.js';
+import { nullExtensionDescription } from '../../../services/extensions/common/extensions.js';
+import { ExtHostConfigProvider } from '../../common/extHostConfiguration.js';
 
 suite('ExtHostFileSystemEventService', () => {
 
 	ensureNoDisposablesAreLeakedInTestSuite();
 
-	test('FileSystemWatcher ignore events properties are reversed #26851', function () {
+	const protocol: IMainContext = {
+		getProxy: () => { return undefined!; },
+		set: undefined!,
+		dispose: undefined!,
+		assertRegistered: undefined!,
+		drain: undefined!
+	};
 
-		const protocol: IMainContext = {
-			getProxy: () => { return undefined!; },
-			set: undefined!,
-			dispose: undefined!,
-			assertRegistered: undefined!,
-			drain: undefined!
-		};
+	const protocolWithProxy: IMainContext = {
+		getProxy: () => ({ $watch() { }, $unwatch() { }, dispose() { } }) as never,
+		set: undefined!,
+		dispose: undefined!,
+		assertRegistered: undefined!,
+		drain: undefined!
+	};
+
+	test('FileSystemWatcher ignore events properties are reversed #26851', function () {
 
 		const fileSystemInfo = new ExtHostFileSystemInfo();
 
@@ -38,4 +52,102 @@ suite('ExtHostFileSystemEventService', () => {
 		watcher2.dispose();
 	});
 
+	test('FileSystemWatcher matches case-insensitively via pre-lowercasing', function () {
+		const fileSystemInfo = new ExtHostFileSystemInfo();
+		// Default: no PathCaseSensitive capability → ignoreCase=true for string patterns
+
+		const workspace: Pick<IExtHostWorkspace, 'getWorkspaceFolder'> = {
+			getWorkspaceFolder: () => ({ uri: URI.file('/workspace'), name: 'test', index: 0 })
+		};
+
+		const service = new ExtHostFileSystemEventService(protocol, new NullLogService(), undefined!);
+		const watcher = service.createFileSystemWatcher(workspace as IExtHostWorkspace, undefined!, fileSystemInfo, undefined!, '**/*.TXT', {});
+
+		const created: URI[] = [];
+		const sub = watcher.onDidCreate(uri => created.push(uri));
+
+		// lowercase path should match uppercase pattern on case-insensitive fs
+		service.$onFileEvent({
+			session: undefined,
+			created: [URI.file('/workspace/file.txt')],
+			changed: [],
+			deleted: []
+		});
+
+		assert.strictEqual(created.length, 1);
+
+		sub.dispose();
+		watcher.dispose();
+	});
+
+	test('FileSystemWatcher matches case-sensitively when PathCaseSensitive', function () {
+		const fileSystemInfo = new ExtHostFileSystemInfo();
+		fileSystemInfo.$acceptProviderInfos(URI.file('/'), FileSystemProviderCapabilities.PathCaseSensitive);
+
+		const workspace: Pick<IExtHostWorkspace, 'getWorkspaceFolder'> = {
+			getWorkspaceFolder: () => ({ uri: URI.file('/workspace'), name: 'test', index: 0 })
+		};
+
+		const service = new ExtHostFileSystemEventService(protocol, new NullLogService(), undefined!);
+		const watcher = service.createFileSystemWatcher(workspace as IExtHostWorkspace, undefined!, fileSystemInfo, undefined!, '**/*.TXT', {});
+
+		const created: URI[] = [];
+		const sub = watcher.onDidCreate(uri => created.push(uri));
+
+		// lowercase path should NOT match uppercase pattern on case-sensitive fs
+		service.$onFileEvent({
+			session: undefined,
+			created: [URI.file('/workspace/file.txt')],
+			changed: [],
+			deleted: []
+		});
+
+		assert.strictEqual(created.length, 0);
+
+		// uppercase path SHOULD match
+		service.$onFileEvent({
+			session: undefined,
+			created: [URI.file('/workspace/file.TXT')],
+			changed: [],
+			deleted: []
+		});
+
+		assert.strictEqual(created.length, 1);
+
+		sub.dispose();
+		watcher.dispose();
+	});
+
+	test('FileSystemWatcher matches relative pattern case-insensitively via pre-lowercasing', function () {
+		const fileSystemInfo = new ExtHostFileSystemInfo();
+		fileSystemInfo.$acceptProviderInfos(URI.file('/'), FileSystemProviderCapabilities.FileReadWrite); // no PathCaseSensitive → ignoreCase=true
+
+		const workspace: Pick<IExtHostWorkspace, 'getWorkspaceFolder'> = {
+			getWorkspaceFolder: () => ({ uri: URI.file('/workspace'), name: 'test', index: 0 })
+		};
+
+		const configProvider = {
+			getConfiguration: () => ({ get: () => ({}) })
+		} as unknown as ExtHostConfigProvider;
+
+		const service = new ExtHostFileSystemEventService(protocolWithProxy, new NullLogService(), undefined!);
+		const watcher = service.createFileSystemWatcher(workspace as IExtHostWorkspace, configProvider, fileSystemInfo, nullExtensionDescription, new RelativePattern('/Workspace', '**/*.TXT'), {});
+
+		const created: URI[] = [];
+		const sub = watcher.onDidCreate(uri => created.push(uri));
+
+		// lowercase path should match mixed-case base + uppercase extension on case-insensitive fs
+		service.$onFileEvent({
+			session: undefined,
+			created: [URI.file('/workspace/file.txt')],
+			changed: [],
+			deleted: []
+		});
+
+		assert.strictEqual(created.length, 1);
+
+		sub.dispose();
+		watcher.dispose();
+	});
+
 });
