or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

color-channels.mdcomposition.mdconstructor-input.mdindex.mdmetadata-stats.mdoperations-filters.mdoutput-formats.mdresize-geometry.mdutilities-performance.md

utilities-performance.mddocs/

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