DO

documenso-performance-tuning

Improves Documenso response times and reduces API calls through caching and batching.

Install

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

Installs to .claude/skills/documenso-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 Documenso integration performance with caching, batching, and
70 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Reduce Documenso API calls with templates
  • Cache Documenso document metadata
  • Batch Documenso operations with concurrency control
  • Process Documenso signing requests asynchronously
  • Paginate through Documenso documents efficiently

How it works

It optimizes Documenso integrations by reducing API round-trips using templates, caching document metadata, batching operations with concurrency control, and processing bulk signing workflows asynchronously.

Inputs & outputs

You give it
Documenso API calls, document metadata, bulk operations, document lists
You get back
Optimized Documenso integration performance

When to use documenso-performance-tuning

  • Reduce API calls per document
  • Implement Redis caching for metadata
  • Batch bulk signing operations
  • Refactor manual document creation to templates

About this skill

Documenso Performance Tuning

Overview

Optimize Documenso integrations for speed and efficiency. Key strategies: reduce API round-trips with templates, cache document metadata, batch operations with concurrency control, and use async processing for bulk signing workflows.

Prerequisites

  • Working Documenso integration
  • Redis or in-memory cache (recommended)
  • Completed documenso-sdk-patterns setup

Instructions

Step 1: Reduce API Calls with Templates

The biggest performance win: templates reduce a multi-step document creation (create + upload + add recipients + add fields + send = 5+ calls) to just 2 calls (create from template + send).

// WITHOUT templates: 5+ API calls per document
async function createDocumentManual(signer: { email: string; name: string }) {
  const doc = await client.documents.createV0({ title: "Contract" });              // 1
  await client.documents.setFileV0(doc.documentId, { file: pdfBlob });             // 2
  const recip = await client.documentsRecipients.createV0(doc.documentId, {        // 3
    email: signer.email, name: signer.name, role: "SIGNER",
  });
  await client.documentsFields.createV0(doc.documentId, {                          // 4
    recipientId: recip.recipientId, type: "SIGNATURE",
    pageNumber: 1, pageX: 10, pageY: 80, pageWidth: 30, pageHeight: 5,
  });
  await client.documents.sendV0(doc.documentId);                                   // 5
}

// WITH templates: 2 API calls per document
async function createDocumentFromTemplate(templateId: number, signer: { email: string; name: string }) {
  const res = await fetch(                                                          // 1
    `${BASE}/templates/${templateId}/create-document`,
    {
      method: "POST",
      headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
      body: JSON.stringify({
        title: `Contract — ${signer.name}`,
        recipients: [{ email: signer.email, name: signer.name, role: "SIGNER" }],
      }),
    }
  );
  const doc = await res.json();
  await fetch(`${BASE}/documents/${doc.documentId}/send`, {                         // 2
    method: "POST",
    headers: { Authorization: `Bearer ${API_KEY}` },
  });
}

Step 2: Cache Document Metadata

// src/cache/documenso-cache.ts
import NodeCache from "node-cache";

const cache = new NodeCache({ stdTTL: 300, checkperiod: 60 }); // 5 min TTL

export async function getCachedDocument(client: Documenso, documentId: number) {
  const key = `doc:${documentId}`;
  const cached = cache.get(key);
  if (cached) return cached;

  const doc = await client.documents.getV0(documentId);
  // Only cache completed documents (immutable)
  if (doc.status === "COMPLETED") {
    cache.set(key, doc, 3600); // 1 hour for completed
  } else {
    cache.set(key, doc, 30); // 30 seconds for in-progress
  }
  return doc;
}

// Invalidate on webhook events
export function invalidateDocument(documentId: number) {
  cache.del(`doc:${documentId}`);
}

Step 3: Batch Operations with Concurrency Control

// src/batch/documenso-batch.ts
import PQueue from "p-queue";

const queue = new PQueue({
  concurrency: 5,       // Max 5 concurrent API calls
  interval: 1000,       // Per second window
  intervalCap: 10,      // Max 10 per second
});

export async function batchCreateDocuments(
  client: Documenso,
  templateId: number,
  signers: Array<{ email: string; name: string; company: string }>
): Promise<Array<{ email: string; documentId?: number; error?: string }>> {
  const results = await Promise.allSettled(
    signers.map((signer) =>
      queue.add(async () => {
        const res = await fetch(
          `https://app.documenso.com/api/v1/templates/${templateId}/create-document`,
          {
            method: "POST",
            headers: {
              Authorization: `Bearer ${process.env.DOCUMENSO_API_KEY}`,
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              title: `Agreement — ${signer.company}`,
              recipients: [{ email: signer.email, name: signer.name, role: "SIGNER" }],
            }),
          }
        );
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const doc = await res.json();

        // Send immediately
        await fetch(
          `https://app.documenso.com/api/v1/documents/${doc.documentId}/send`,
          {
            method: "POST",
            headers: { Authorization: `Bearer ${process.env.DOCUMENSO_API_KEY}` },
          }
        );

        return { email: signer.email, documentId: doc.documentId };
      })
    )
  );

  return results.map((r, i) => {
    if (r.status === "fulfilled") return r.value as any;
    return { email: signers[i].email, error: (r.reason as Error).message };
  });
}

Step 4: Async Processing with Background Jobs

// src/jobs/signing-queue.ts
import Bull from "bull";

const signingQueue = new Bull("documenso-signing", process.env.REDIS_URL!);

// Producer: queue signing requests
export async function queueSigningRequest(data: {
  templateId: number;
  signerEmail: string;
  signerName: string;
}) {
  const job = await signingQueue.add(data, {
    attempts: 3,
    backoff: { type: "exponential", delay: 5000 },
  });
  return job.id;
}

// Consumer: process in background
signingQueue.process(5, async (job) => {
  const { templateId, signerEmail, signerName } = job.data;
  // Create and send document...
  return { status: "sent" };
});

signingQueue.on("completed", (job, result) => {
  console.log(`Job ${job.id} completed: ${JSON.stringify(result)}`);
});

signingQueue.on("failed", (job, err) => {
  console.error(`Job ${job.id} failed: ${err.message}`);
});

Step 5: Efficient Pagination

// Paginate through all documents without loading everything into memory
async function* iterateDocuments(client: Documenso, perPage = 50) {
  let page = 1;
  while (true) {
    const { documents } = await client.documents.findV0({
      page,
      perPage,
      orderByColumn: "createdAt",
      orderByDirection: "desc",
    });

    for (const doc of documents) {
      yield doc;
    }

    if (documents.length < perPage) break; // Last page
    page++;
  }
}

// Usage: process all documents without memory issues
for await (const doc of iterateDocuments(client)) {
  if (doc.status === "COMPLETED") {
    await archiveDocument(doc.id);
  }
}

Performance Targets

OperationTargetIf Exceeded
Single document create< 500msCheck network latency
Template create + send< 1sNormal for template workflow
Batch of 100 documents< 30sUse concurrency 5-10
Document list (page)< 300msAdd caching layer
Webhook processing< 100msProcess async, respond 200 immediately

Error Handling

Performance IssueCauseSolution
Slow responsesNo connection reuseUse singleton client pattern
Rate limit errorsToo many concurrent callsUse p-queue with concurrency cap
Memory issuesLoading all documentsUse async generator pagination
Queue backlogSlow processingIncrease worker concurrency

Resources

Next Steps

For cost optimization, see documenso-cost-tuning.

Prerequisites

Working Documenso integrationRedis or in-memory cacheCompleted documenso-sdk-patterns setup

Limitations

  • Performance targets are specific to Documenso operations
  • Requires external caching solution like Redis
  • Batching requires concurrency control setup

How it compares

This approach reduces API calls and improves response times compared to manual, sequential Documenso API interactions.

Compared to similar skills

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

SkillInstallsUpdatedSafetyDifficulty
documenso-performance-tuning (this skill)025dReviewIntermediate
gamma-performance-tuning025dNo flagsIntermediate
juicebox-prod-checklist125dCautionBeginner
instantly-performance-tuning025dCautionIntermediate

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

gamma-performance-tuning

jeremylongshore

Optimize Gamma API performance and reduce latency. Use when experiencing slow response times, optimizing throughput, or improving user experience with Gamma integrations. Trigger with phrases like "gamma performance", "gamma slow", "gamma latency", "gamma optimization", "gamma speed".

01

juicebox-prod-checklist

jeremylongshore

Execute Juicebox production deployment checklist. Use when preparing for production launch, validating deployment readiness, or performing pre-launch reviews. Trigger with phrases like "juicebox production", "deploy juicebox prod", "juicebox launch checklist", "juicebox go-live".

10

instantly-performance-tuning

jeremylongshore

Optimize Instantly API performance with caching, batching, and connection pooling. Use when experiencing slow API responses, implementing caching strategies, or optimizing request throughput for Instantly integrations. Trigger with phrases like "instantly performance", "optimize instantly", "instantly latency", "instantly caching", "instantly slow", "instantly batch".

00

perplexity-architecture-variants

jeremylongshore

Choose and implement Perplexity validated architecture blueprints for different scales. Use when designing new Perplexity integrations, choosing between monolith/service/microservice architectures, or planning migration paths for Perplexity applications. Trigger with phrases like "perplexity architecture", "perplexity blueprint", "how to structure perplexity", "perplexity project layout", "perplexity microservice".

00

idmp

ha0z1

Use when you need to deduplicate concurrent or repeated async calls, prevent duplicate API requests, cache async function results, add automatic retry with exponential backoff, memoize heavy computation wrapped in Promise, replace SWR/Provider for request sharing, invalidate cache with flush, or per

00

mcp-builder

anthropics

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

136215

Search skills

Search the agent skills registry