0
# Utilities and Performance
1
2
Sharp provides extensive utilities for performance monitoring, library configuration, and runtime optimization controls.
3
4
## Capabilities
5
6
### Cache Management
7
8
Control libvips operation cache for memory and performance optimization.
9
10
```javascript { .api }
11
/**
12
* Get or set libvips operation cache limits
13
* @param options - Cache configuration or boolean
14
* @returns Current cache statistics
15
*/
16
sharp.cache(options?: boolean | CacheOptions): CacheResult;
17
18
interface CacheOptions {
19
/** Maximum memory in MB (default 50) */
20
memory?: number;
21
/** Maximum open files (default 20) */
22
files?: number;
23
/** Maximum cached operations (default 100) */
24
items?: number;
25
}
26
27
interface CacheResult {
28
/** Memory usage statistics */
29
memory: {
30
current: number;
31
high: number;
32
max: number;
33
};
34
/** File handle statistics */
35
files: {
36
current: number;
37
max: number;
38
};
39
/** Cached items statistics */
40
items: {
41
current: number;
42
max: number;
43
};
44
}
45
```
46
47
**Usage Examples:**
48
49
```javascript
50
// Get current cache statistics
51
const cacheStats = sharp.cache();
52
console.log('Memory usage:', cacheStats.memory);
53
console.log('Open files:', cacheStats.files);
54
console.log('Cached items:', cacheStats.items);
55
56
// Set cache limits
57
sharp.cache({
58
memory: 100, // 100MB
59
files: 50, // 50 open files
60
items: 200 // 200 cached operations
61
});
62
63
// Disable caching
64
sharp.cache(false);
65
66
// Reset to defaults
67
sharp.cache(true);
68
69
// Monitor cache usage
70
const monitorCache = () => {
71
const stats = sharp.cache();
72
console.log(`Memory: ${stats.memory.current}MB / ${stats.memory.max}MB`);
73
console.log(`Files: ${stats.files.current} / ${stats.files.max}`);
74
console.log(`Items: ${stats.items.current} / ${stats.items.max}`);
75
76
if (stats.memory.current > stats.memory.max * 0.9) {
77
console.warn('Cache memory usage is high');
78
}
79
};
80
```
81
82
### Concurrency Control
83
84
Manage thread usage for optimal performance across different workloads.
85
86
```javascript { .api }
87
/**
88
* Get or set number of libvips worker threads
89
* @param concurrency - Number of threads (0 = auto-detect)
90
* @returns Current concurrency value
91
*/
92
sharp.concurrency(concurrency?: number): number;
93
```
94
95
**Usage Examples:**
96
97
```javascript
98
// Get current thread count
99
const currentThreads = sharp.concurrency();
100
console.log(`Current threads: ${currentThreads}`);
101
102
// Set thread count
103
sharp.concurrency(4); // Use 4 threads
104
sharp.concurrency(0); // Auto-detect (default)
105
106
// Optimize for workload
107
const optimizeForWorkload = (type) => {
108
const cpuCount = require('os').cpus().length;
109
110
switch (type) {
111
case 'batch':
112
// High throughput batch processing
113
sharp.concurrency(cpuCount);
114
break;
115
case 'server':
116
// Web server with many concurrent requests
117
sharp.concurrency(Math.max(2, cpuCount / 2));
118
break;
119
case 'single':
120
// Single image processing
121
sharp.concurrency(1);
122
break;
123
default:
124
// Auto-detect
125
sharp.concurrency(0);
126
}
127
};
128
```
129
130
### Task Monitoring
131
132
Monitor Sharp's internal task queue and processing status.
133
134
```javascript { .api }
135
/**
136
* Access internal task counters
137
* @returns Current task queue statistics
138
*/
139
sharp.counters(): SharpCounters;
140
141
interface SharpCounters {
142
/** Tasks waiting for worker threads */
143
queue: number;
144
/** Tasks currently being processed */
145
process: number;
146
}
147
```
148
149
**Usage Examples:**
150
151
```javascript
152
// Monitor task queue
153
const monitorTasks = () => {
154
const counters = sharp.counters();
155
console.log(`Queued: ${counters.queue}, Processing: ${counters.process}`);
156
157
if (counters.queue > 10) {
158
console.warn('High queue depth - consider increasing concurrency');
159
}
160
};
161
162
// Monitor during batch processing
163
const processBatch = async (images) => {
164
console.log('Starting batch processing...');
165
166
const interval = setInterval(monitorTasks, 1000);
167
168
try {
169
await Promise.all(images.map(processImage));
170
} finally {
171
clearInterval(interval);
172
console.log('Batch processing complete');
173
}
174
};
175
```
176
177
### SIMD Control
178
179
Enable or disable SIMD vector unit instructions for performance optimization.
180
181
```javascript { .api }
182
/**
183
* Get or set SIMD vector unit instruction usage
184
* @param enable - Enable SIMD instructions (optional)
185
* @returns Current SIMD status
186
*/
187
sharp.simd(enable?: boolean): boolean;
188
```
189
190
**Usage Examples:**
191
192
```javascript
193
// Check SIMD availability
194
const simdEnabled = sharp.simd();
195
console.log(`SIMD enabled: ${simdEnabled}`);
196
197
// Enable SIMD (if supported)
198
if (sharp.simd(true)) {
199
console.log('SIMD enabled for better performance');
200
} else {
201
console.log('SIMD not available on this system');
202
}
203
204
// Disable SIMD for debugging
205
sharp.simd(false);
206
207
// Performance comparison
208
const benchmarkSIMD = async (imagePath) => {
209
const image = sharp(imagePath);
210
211
// Test with SIMD disabled
212
sharp.simd(false);
213
const start1 = Date.now();
214
await image.clone().resize(800, 600).blur(2).toBuffer();
215
const time1 = Date.now() - start1;
216
217
// Test with SIMD enabled
218
sharp.simd(true);
219
const start2 = Date.now();
220
await image.clone().resize(800, 600).blur(2).toBuffer();
221
const time2 = Date.now() - start2;
222
223
console.log(`Without SIMD: ${time1}ms`);
224
console.log(`With SIMD: ${time2}ms`);
225
console.log(`Performance gain: ${((time1 - time2) / time1 * 100).toFixed(1)}%`);
226
};
227
```
228
229
### Operation Blocking
230
231
Block or unblock specific libvips operations for security or compatibility.
232
233
```javascript { .api }
234
/**
235
* Block libvips operations at runtime
236
* @param options - Operations to block
237
*/
238
sharp.block(options: { operation: string[] }): void;
239
240
/**
241
* Unblock libvips operations at runtime
242
* @param options - Operations to unblock
243
*/
244
sharp.unblock(options: { operation: string[] }): void;
245
```
246
247
**Usage Examples:**
248
249
```javascript
250
// Block potentially unsafe operations
251
sharp.block({
252
operation: ['VipsForeignLoadTiff', 'VipsForeignLoadPdf']
253
});
254
255
// Create allowlist by blocking all then unblocking specific operations
256
sharp.block({
257
operation: ['VipsForeignLoad'] // Block all loaders
258
});
259
260
sharp.unblock({
261
operation: [
262
'VipsForeignLoadJpegFile',
263
'VipsForeignLoadPngFile',
264
'VipsForeignLoadWebpFile'
265
]
266
});
267
268
// Security-focused configuration
269
const secureConfiguration = () => {
270
// Block operations that could be security risks
271
sharp.block({
272
operation: [
273
'VipsForeignLoadTiff', // TIFF can contain exploits
274
'VipsForeignLoadPdf', // PDF processing
275
'VipsForeignLoadSvg', // SVG can contain scripts
276
'VipsForeignLoadGif' // Limit GIF processing
277
]
278
});
279
280
// Set conservative limits
281
sharp.cache({
282
memory: 50, // Limit memory usage
283
files: 10, // Limit open files
284
items: 50 // Limit cached items
285
});
286
287
// Single thread for predictable behavior
288
sharp.concurrency(1);
289
};
290
```
291
292
### Library Information
293
294
Access version information and format capabilities.
295
296
```javascript { .api }
297
// Static properties providing library information
298
299
/** Available input/output formats and their capabilities */
300
sharp.format: FormatEnum;
301
302
/** Version information for Sharp and dependencies */
303
sharp.versions: {
304
sharp: string;
305
vips: string;
306
// Optional dependency versions
307
aom?: string;
308
cairo?: string;
309
exif?: string;
310
fontconfig?: string;
311
freetype?: string;
312
heif?: string;
313
jpeg?: string;
314
lcms?: string;
315
png?: string;
316
svg?: string;
317
tiff?: string;
318
webp?: string;
319
// ... other optional dependencies
320
};
321
322
/** Available interpolation methods */
323
sharp.interpolators: {
324
nearest: 'nearest';
325
bilinear: 'bilinear';
326
bicubic: 'bicubic';
327
locallyBoundedBicubic: 'lbb';
328
nohalo: 'nohalo';
329
vertexSplitQuadraticBasisSpline: 'vsqbs';
330
};
331
332
/** Event emitter for queue status changes */
333
sharp.queue: NodeJS.EventEmitter;
334
335
/** Gravity constants for positioning */
336
sharp.gravity: GravityEnum;
337
338
/** Strategy constants for cropping */
339
sharp.strategy: StrategyEnum;
340
341
/** Kernel constants for resizing */
342
sharp.kernel: KernelEnum;
343
344
/** Fit constants for resize behavior */
345
sharp.fit: FitEnum;
346
347
/** Boolean operation constants */
348
sharp.bool: BoolEnum;
349
```
350
351
**Usage Examples:**
352
353
```javascript
354
// Check format support
355
console.log('Supported formats:');
356
Object.keys(sharp.format).forEach(format => {
357
const info = sharp.format[format];
358
console.log(`${format}: input=${info.input.file}, output=${info.output.file}`);
359
});
360
361
// Check specific format capabilities
362
if (sharp.format.avif && sharp.format.avif.output.file) {
363
console.log('AVIF output is supported');
364
} else {
365
console.log('AVIF output not available');
366
}
367
368
// Version information
369
console.log('Library versions:');
370
console.log(`Sharp: ${sharp.versions.sharp}`);
371
console.log(`libvips: ${sharp.versions.vips}`);
372
373
if (sharp.versions.webp) {
374
console.log(`WebP: ${sharp.versions.webp}`);
375
}
376
377
// Check for optional features
378
const checkFeatures = () => {
379
const features = {
380
avif: !!sharp.versions.heif, // AVIF requires HEIF support
381
svg: !!sharp.versions.svg,
382
pdf: !!sharp.versions.poppler || !!sharp.versions.pdfium,
383
tiff: !!sharp.versions.tiff,
384
jpeg2000: !!sharp.versions.openjpeg
385
};
386
387
console.log('Available features:', features);
388
return features;
389
};
390
391
// Monitor queue events
392
sharp.queue.on('change', (queueLength) => {
393
console.log(`Queue length changed: ${queueLength}`);
394
});
395
```
396
397
### Performance Optimization Patterns
398
399
**Optimal Configuration for Different Use Cases:**
400
401
```javascript
402
// Web server configuration
403
const configureForWebServer = () => {
404
const cpuCount = require('os').cpus().length;
405
406
sharp.cache({
407
memory: 100, // 100MB cache
408
files: Math.min(cpuCount * 2, 20), // Reasonable file limit
409
items: 200 // Cache many operations
410
});
411
412
sharp.concurrency(Math.max(2, cpuCount / 2)); // Leave CPU for other tasks
413
sharp.simd(true); // Enable SIMD if available
414
415
// Monitor performance
416
setInterval(() => {
417
const stats = sharp.cache();
418
const counters = sharp.counters();
419
420
if (stats.memory.current > stats.memory.max * 0.8) {
421
console.warn('Sharp cache memory usage high');
422
}
423
424
if (counters.queue > 5) {
425
console.warn('Sharp queue backing up');
426
}
427
}, 30000);
428
};
429
430
// Batch processing configuration
431
const configureForBatch = () => {
432
const totalMemory = require('os').totalmem() / 1024 / 1024 / 1024; // GB
433
const memoryLimit = Math.min(Math.floor(totalMemory / 4), 500); // 25% of RAM, max 500MB
434
435
sharp.cache({
436
memory: memoryLimit,
437
files: 100, // Many files for batch processing
438
items: 1000 // Cache many operations
439
});
440
441
sharp.concurrency(0); // Use all available CPUs
442
sharp.simd(true); // Maximum performance
443
};
444
445
// Memory-constrained configuration
446
const configureForLowMemory = () => {
447
sharp.cache({
448
memory: 20, // Low memory limit
449
files: 5, // Few open files
450
items: 50 // Limited caching
451
});
452
453
sharp.concurrency(1); // Single thread to limit memory
454
sharp.simd(false); // Reduce complexity
455
};
456
```
457
458
**Performance Monitoring:**
459
460
```javascript
461
const createPerformanceMonitor = () => {
462
const stats = {
463
processedImages: 0,
464
totalTime: 0,
465
errors: 0
466
};
467
468
const monitor = {
469
async processImage(imagePath, operations) {
470
const startTime = Date.now();
471
472
try {
473
let pipeline = sharp(imagePath);
474
475
// Apply operations
476
for (const op of operations) {
477
pipeline = pipeline[op.method](...op.args);
478
}
479
480
const result = await pipeline.toBuffer();
481
482
const endTime = Date.now();
483
const processingTime = endTime - startTime;
484
485
stats.processedImages++;
486
stats.totalTime += processingTime;
487
488
// Log performance metrics
489
const avgTime = stats.totalTime / stats.processedImages;
490
console.log(`Processed ${imagePath} in ${processingTime}ms (avg: ${avgTime.toFixed(1)}ms)`);
491
492
return result;
493
} catch (error) {
494
stats.errors++;
495
console.error(`Error processing ${imagePath}:`, error.message);
496
throw error;
497
}
498
},
499
500
getStats() {
501
return {
502
...stats,
503
averageTime: stats.processedImages > 0 ? stats.totalTime / stats.processedImages : 0,
504
errorRate: stats.processedImages > 0 ? stats.errors / stats.processedImages : 0
505
};
506
},
507
508
reset() {
509
stats.processedImages = 0;
510
stats.totalTime = 0;
511
stats.errors = 0;
512
}
513
};
514
515
return monitor;
516
};
517
```
518
519
**Memory Management:**
520
521
```javascript
522
const createMemoryManager = () => {
523
return {
524
async processWithMemoryManagement(images, processor) {
525
const batchSize = 10; // Process in batches
526
const results = [];
527
528
for (let i = 0; i < images.length; i += batchSize) {
529
const batch = images.slice(i, i + batchSize);
530
531
// Process batch
532
const batchResults = await Promise.all(
533
batch.map(processor)
534
);
535
536
results.push(...batchResults);
537
538
// Check memory usage
539
const cacheStats = sharp.cache();
540
if (cacheStats.memory.current > cacheStats.memory.max * 0.8) {
541
console.log('Clearing cache due to high memory usage');
542
sharp.cache(false); // Clear cache
543
sharp.cache(true); // Re-enable with defaults
544
}
545
546
// Force garbage collection if available
547
if (global.gc) {
548
global.gc();
549
}
550
551
console.log(`Processed batch ${Math.floor(i/batchSize) + 1}/${Math.ceil(images.length/batchSize)}`);
552
}
553
554
return results;
555
}
556
};
557
};
558
```
559
560
## Enum Definitions
561
562
Complete definitions for all Sharp constants and enums.
563
564
```javascript { .api }
565
interface FormatEnum {
566
heif: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
567
jpeg: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
568
jp2: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
569
jxl: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
570
png: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
571
webp: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
572
gif: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
573
avif: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
574
tiff: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
575
dz: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
576
fits: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
577
magick: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
578
openslide: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
579
pdf: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
580
ppm: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
581
raw: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
582
svg: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
583
v: { id: string; input: { file: boolean; buffer: boolean; stream: boolean; }; output: { file: boolean; buffer: boolean; stream: boolean; }; };
584
}
585
586
interface GravityEnum {
587
north: 1;
588
northeast: 2;
589
east: 3;
590
southeast: 4;
591
south: 5;
592
southwest: 6;
593
west: 7;
594
northwest: 8;
595
center: 9;
596
centre: 9;
597
}
598
599
interface StrategyEnum {
600
entropy: 16;
601
attention: 17;
602
}
603
604
interface KernelEnum {
605
nearest: 'nearest';
606
linear: 'linear';
607
cubic: 'cubic';
608
mitchell: 'mitchell';
609
lanczos2: 'lanczos2';
610
lanczos3: 'lanczos3';
611
}
612
613
interface FitEnum {
614
contain: 'contain';
615
cover: 'cover';
616
fill: 'fill';
617
inside: 'inside';
618
outside: 'outside';
619
}
620
621
interface BoolEnum {
622
and: 'and';
623
or: 'or';
624
eor: 'eor';
625
}
626
627
interface Interpolators {
628
nearest: 'nearest';
629
bilinear: 'bilinear';
630
bicubic: 'bicubic';
631
locallyBoundedBicubic: 'lbb';
632
nohalo: 'nohalo';
633
vertexSplitQuadraticBasisSpline: 'vsqbs';
634
}
635
```
636
637
## Best Practices
638
639
1. **Cache Configuration**: Set appropriate cache limits based on available memory
640
2. **Concurrency**: Balance thread count with system resources and workload
641
3. **SIMD Usage**: Enable SIMD for better performance on supported systems
642
4. **Security**: Block unnecessary operations in production environments
643
5. **Monitoring**: Track cache usage and queue depth for optimization
644
6. **Memory Management**: Process large batches in chunks to prevent memory exhaustion
645
7. **Error Handling**: Monitor error rates and adjust configuration as needed