MA

maintainx-performance-tuning

Provides optimization patterns like caching and keep-alive agents for MaintainX API integrations.

Install

mkdir -p .claude/skills/maintainx-performance-tuning && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/8852" && unzip -o skill.zip -d .claude/skills/maintainx-performance-tuning && rm skill.zip

Installs to .claude/skills/maintainx-performance-tuning

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Optimize MaintainX API integration performance.
47 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Implement connection pooling with keep-alive
  • Configure multi-level caching using memory and Redis
  • Batch and deduplicate API requests with DataLoader
  • Optimize data fetching with cursor-based pagination
  • Prevent redundant concurrent API calls with request deduplication

How it works

The skill implements connection pooling to reuse TCP connections and a multi-level cache strategy to reduce redundant API calls. It also uses DataLoader to batch multiple requests for the same entity into a single operation.

Inputs & outputs

You give it
MaintainX API endpoint and request parameters
You get back
Optimized, cached, or batched API response data

When to use maintainx-performance-tuning

  • Reducing API latency in MaintainX
  • Optimizing data fetching patterns
  • Implementing request deduplication
  • Improving throughput for CMMS integrations

About this skill

MaintainX Performance Tuning

Overview

Optimize MaintainX integration performance with caching, connection pooling, efficient pagination, and request deduplication.

Prerequisites

  • MaintainX integration working
  • Node.js 18+
  • Redis (recommended for production caching)
  • Performance baseline measurements

Instructions

Step 1: Connection Pooling with Keep-Alive

// src/performance/pooled-client.ts
import axios from 'axios';
import http from 'node:http';
import https from 'node:https';

// Reuse TCP connections instead of opening new ones per request
const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 10 });
const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 10 });

const client = axios.create({
  baseURL: 'https://api.getmaintainx.com/v1',
  headers: {
    Authorization: `Bearer ${process.env.MAINTAINX_API_KEY}`,
    'Content-Type': 'application/json',
  },
  httpAgent,
  httpsAgent,
  timeout: 30_000,
});

// Benefit: Eliminates TCP handshake + TLS negotiation per request
// Typical improvement: 100-200ms saved per request

Step 2: Multi-Level Caching

// src/performance/cache.ts

interface CacheLayer<T> {
  get(key: string): Promise<T | undefined>;
  set(key: string, value: T, ttlMs: number): Promise<void>;
}

// L1: In-memory (fastest, per-process)
class MemoryCache<T> implements CacheLayer<T> {
  private store = new Map<string, { value: T; expiresAt: number }>();

  async get(key: string) {
    const entry = this.store.get(key);
    if (entry && entry.expiresAt > Date.now()) return entry.value;
    this.store.delete(key);
    return undefined;
  }

  async set(key: string, value: T, ttlMs: number) {
    this.store.set(key, { value, expiresAt: Date.now() + ttlMs });
  }
}

// L2: Redis (shared across processes)
class RedisCache<T> implements CacheLayer<T> {
  constructor(private redis: any) {}

  async get(key: string) {
    const data = await this.redis.get(`mx:${key}`);
    return data ? JSON.parse(data) : undefined;
  }

  async set(key: string, value: T, ttlMs: number) {
    await this.redis.setex(`mx:${key}`, Math.ceil(ttlMs / 1000), JSON.stringify(value));
  }
}

// Multi-level cache: check L1 first, then L2, then fetch
class MultiCache<T> {
  constructor(private l1: CacheLayer<T>, private l2: CacheLayer<T>) {}

  async getOrFetch(key: string, ttlMs: number, fetcher: () => Promise<T>): Promise<T> {
    // Check L1
    let value = await this.l1.get(key);
    if (value !== undefined) return value;

    // Check L2
    value = await this.l2.get(key);
    if (value !== undefined) {
      await this.l1.set(key, value, ttlMs / 2); // L1 shorter TTL
      return value;
    }

    // Fetch from API
    value = await fetcher();
    await this.l1.set(key, value, ttlMs / 2);
    await this.l2.set(key, value, ttlMs);
    return value;
  }
}

Step 3: DataLoader for Batch Loading

When multiple parts of your app need the same work order, batch and deduplicate:

// src/performance/dataloader.ts
import DataLoader from 'dataloader';

const workOrderLoader = new DataLoader<number, any>(
  async (ids: readonly number[]) => {
    // Batch: fetch multiple work orders in parallel
    const results = await Promise.all(
      ids.map((id) =>
        client.get(`/workorders/${id}`).then((r) => r.data)
      ),
    );
    // Return in same order as input ids
    return ids.map((id) => results.find((r) => r.id === id) || null);
  },
  {
    maxBatchSize: 25,
    cacheKeyFn: (id) => String(id),
  },
);

// These 3 calls collapse into 1 batched operation:
const [wo1, wo2, wo3] = await Promise.all([
  workOrderLoader.load(100),
  workOrderLoader.load(200),
  workOrderLoader.load(100), // deduped, same as first
]);

Step 4: Efficient Pagination

// Fetch only the fields you need (if API supports field selection)
// Use larger page sizes to reduce round trips

async function efficientFetchAll(client: any, endpoint: string, key: string) {
  const all = [];
  let cursor: string | undefined;
  let pageCount = 0;

  const startTime = Date.now();

  do {
    const { data } = await client.get(endpoint, {
      params: { limit: 100, cursor }, // Max page size
    });
    all.push(...data[key]);
    cursor = data.cursor;
    pageCount++;
  } while (cursor);

  const elapsed = Date.now() - startTime;
  console.log(`Fetched ${all.length} items in ${pageCount} pages (${elapsed}ms)`);
  return all;
}

// Parallel pagination for independent resources
async function fetchAllResources(client: any) {
  const [workOrders, assets, locations] = await Promise.all([
    efficientFetchAll(client, '/workorders', 'workOrders'),
    efficientFetchAll(client, '/assets', 'assets'),
    efficientFetchAll(client, '/locations', 'locations'),
  ]);

  return { workOrders, assets, locations };
}

Step 5: Request Deduplication

// src/performance/dedup.ts

class RequestDeduplicator {
  private inflight = new Map<string, Promise<any>>();

  async dedupe<T>(key: string, fetcher: () => Promise<T>): Promise<T> {
    if (this.inflight.has(key)) {
      return this.inflight.get(key)! as Promise<T>;
    }

    const promise = fetcher().finally(() => {
      this.inflight.delete(key);
    });

    this.inflight.set(key, promise);
    return promise;
  }
}

const dedup = new RequestDeduplicator();

// 10 concurrent calls to getWorkOrder(123) = 1 actual API call
async function getWorkOrder(id: number) {
  return dedup.dedupe(`wo:${id}`, () => client.get(`/workorders/${id}`));
}

Performance Benchmarks

OptimizationBeforeAfterImprovement
Connection pooling350ms/req150ms/req57% faster
L1 cache (hot path)150ms/req< 1ms/req99% faster
DataLoader batching10 calls1 call90% fewer requests
Max page size (100)50 pages10 pages5x fewer round trips
Request dedupN calls1 call(N-1) saved

Output

  • Connection pooling with keep-alive (reuses TCP connections)
  • Multi-level cache (L1 in-memory + L2 Redis)
  • DataLoader for batching and deduplication of entity fetches
  • Efficient pagination with max page sizes
  • Request deduplication preventing redundant concurrent calls

Error Handling

IssueCauseSolution
Stale cache dataTTL too longReduce TTL, invalidate on writes
Memory growthUnbounded cacheSet max size, use LRU eviction
DataLoader errorsOne item in batch failsHandle per-item errors in batch function
Connection pool exhaustionToo many concurrent requestsIncrease maxSockets or add queue

Resources

Next Steps

For cost optimization, see maintainx-cost-tuning.

Examples

Benchmark your API response times:

# Measure latency for 10 sequential requests
for i in $(seq 1 10); do
  curl -s -o /dev/null -w "Request $i: %{time_total}s\n" \
    "https://api.getmaintainx.com/v1/workorders?limit=1" \
    -H "Authorization: Bearer $MAINTAINX_API_KEY"
done

When not to use it

  • When performance baseline measurements are unavailable
  • When using environments without Redis for shared caching

Prerequisites

Working MaintainX integrationNode.js 18+RedisPerformance baseline measurements

Limitations

  • Stale cache data if TTL is too long
  • Memory growth from unbounded cache
  • Connection pool exhaustion under high concurrency

How it compares

Unlike standard sequential API calls, this approach reduces latency by reusing connections and collapsing multiple requests into batched operations.

Compared to similar skills

maintainx-performance-tuning side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
maintainx-performance-tuning (this skill)026dCautionIntermediate
chrome-devtools417moReviewIntermediate
bullmq-specialist256moNo flagsIntermediate
perf-lighthouse135moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by jeremylongshore

View all by jeremylongshore

analyzing-logs

jeremylongshore

Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.

14123

ollama-setup

jeremylongshore

Configure auto-configure Ollama when user needs local LLM deployment, free AI alternatives, or wants to eliminate hosted API costs. Trigger phrases: "install ollama", "local AI", "free LLM", "self-hosted AI", "replace OpenAI", "no API costs". Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

1167

backtesting-trading-strategies

jeremylongshore

Backtest crypto and traditional trading strategies against historical data. Calculates performance metrics (Sharpe, Sortino, max drawdown), generates equity curves, and optimizes strategy parameters. Use when user wants to test a trading strategy, validate signals, or compare approaches. Trigger with phrases like "backtest strategy", "test trading strategy", "historical performance", "simulate trades", "optimize parameters", or "validate signals".

1071

generating-database-seed-data

jeremylongshore

Process this skill enables AI assistant to generate realistic test data and database seed scripts for development and testing environments. it uses faker libraries to create realistic data, maintains relational integrity, and allows configurable data volumes. u... Use when working with databases or data models. Trigger with phrases like 'database', 'query', or 'schema'.

1033

cursor-codebase-indexing

jeremylongshore

Execute set up and optimize Cursor codebase indexing. Triggers on "cursor index setup", "codebase indexing", "index codebase", "cursor semantic search". Use when working with cursor codebase indexing functionality. Trigger with phrases like "cursor codebase indexing", "cursor indexing", "cursor".

885

testing-mobile-apps

jeremylongshore

Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like "test mobile app", "run iOS tests", or "validate Android functionality".

810

You might also like

chrome-devtools

mrgoonie

Browser automation, debugging, and performance analysis using Puppeteer CLI scripts. Use for automating browsers, taking screenshots, analyzing performance, monitoring network traffic, web scraping, form automation, and JavaScript debugging.

41157

bullmq-specialist

davila7

BullMQ expert for Redis-backed job queues, background processing, and reliable async execution in Node.js/TypeScript applications. Use when: bullmq, bull queue, redis queue, background job, job queue.

2595

perf-lighthouse

tech-leads-club

Run Lighthouse audits locally via CLI or Node API, parse and interpret reports, set performance budgets. Use when measuring site performance, understanding Lighthouse scores, setting up budgets, or integrating audits into CI. Triggers on: lighthouse, run lighthouse, lighthouse score, performance audit, performance budget.

1361

agentdb-performance-optimization

ruvnet

Optimize AgentDB performance with quantization (4-32x memory reduction), HNSW indexing (150x faster search), caching, and batch operations. Use when optimizing memory usage, improving search speed, or scaling to millions of vectors.

656

redis-inspect

civitai

Inspect Redis cache keys, values, and TTLs for debugging. Supports both main cache and system cache. Use for debugging cache issues, checking cached values, and monitoring cache state. Read-only by default.

646

turborepo-caching

wshobson

Configure Turborepo for efficient monorepo builds with local and remote caching. Use when setting up Turborepo, optimizing build pipelines, or implementing distributed caching.

535

Search skills

Search the agent skills registry