| name | documenso-cost-tuning |
| description | Optimize Documenso usage costs and manage subscription efficiency.
Use when analyzing costs, optimizing document usage,
or managing Documenso subscription tiers.
Trigger with phrases like "documenso costs", "documenso pricing",
"optimize documenso spending", "documenso usage".
|
| allowed-tools | Read, Write, Edit |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Documenso Cost Tuning
Overview
Optimize Documenso costs through efficient usage patterns, template reuse, and monitoring.
Prerequisites
- Documenso account with billing access
- Understanding of your usage patterns
- Access to usage analytics
Documenso Pricing Model
Documenso offers multiple plans:
| Plan | Best For | Key Limits |
|---|
| Free | Testing/Personal | Limited documents |
| Individual | Freelancers | Higher document limits |
| Teams | Small teams | Team collaboration |
| Enterprise | Large organizations | Custom limits |
Cost Optimization Strategies
Strategy 1: Template Reuse
async function createContractExpensive(data: ContractData) {
const doc = await client.documents.createV0({
title: data.title,
file: await generatePdf(data),
});
await client.documentsRecipients.createV0({
documentId: doc.documentId!,
email: data.signerEmail,
name: data.signerName,
role: "SIGNER",
});
await client.documentsFields.createV0({
documentId: doc.documentId!,
recipientId: "...",
type: "SIGNATURE",
page: 1,
positionX: 100,
positionY: 600,
width: 200,
height: 60,
});
return doc;
}
() {
envelope = client..({
: ,
: data.,
: [
{
: data.,
: data.,
: ,
},
],
});
envelope;
}
Strategy 2: Document Consolidation
async function handleDealExpensive(deal: Deal) {
await createDocument("NDA", deal);
await createDocument("MSA", deal);
await createDocument("SOW", deal);
}
async function handleDealEfficient(deal: Deal) {
const combinedPdf = await combinePdfs([
"./templates/nda.pdf",
"./templates/msa.pdf",
"./templates/sow.pdf",
]);
await createDocument("Deal Package", deal, combinedPdf);
}
Strategy 3: Draft Cleanup
async function cleanupOldDrafts(daysOld = 30): Promise<number> {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - daysOld);
const docs = await client.documents.findV0({});
const oldDrafts = docs.documents?.filter(
(d) =>
d.status === "DRAFT" &&
new Date(d.createdAt!) < cutoffDate
) ?? [];
let deleted = 0;
for (const draft of oldDrafts) {
try {
await client.documents.deleteV0({ documentId: draft.id! });
deleted++;
} catch (error) {
console.warn(`Failed to delete draft ${draft.id}`);
}
}
console.log(`Deleted ${deleted} old drafts`);
return deleted;
}
Strategy 4: Usage Monitoring
interface UsageMetrics {
period: { start: Date; end: Date };
documentsCreated: number;
documentsCompleted: number;
templateUsage: Map<string, number>;
activeRecipients: Set<string>;
}
async function trackUsage(): Promise<UsageMetrics> {
const now = new Date();
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
const metrics: UsageMetrics = {
period: { start: startOfMonth, end: now },
documentsCreated: 0,
documentsCompleted: 0,
templateUsage: new Map(),
activeRecipients: new Set(),
};
const docs = await client.documents.({});
( doc docs. ?? []) {
createdAt = (doc.!);
(createdAt >= startOfMonth) {
metrics.++;
(doc. === ) {
metrics.++;
}
( recipient doc. ?? []) {
metrics..(recipient.!);
}
}
}
metrics;
}
() {
metrics = ();
= ;
usagePercent = (metrics. / ) * ;
(usagePercent > ) {
.();
}
}
Strategy 5: Efficient Field Placement
async function addFieldsEfficiently(
documentId: string,
fields: FieldConfig[]
): Promise<void> {
if (fields.length > 1) {
await client.documentsFields.createManyV0({
documentId,
fields: fields.map((f) => ({
recipientId: f.recipientId,
type: f.type as any,
page: f.page,
positionX: f.x,
positionY: f.y,
width: f.width ?? 200,
height: f.height ?? 60,
})),
});
} else if (fields.length === 1) {
const f = fields[0];
await client.documentsFields.createV0({
documentId,
recipientId: f.recipientId,
: f. ,
: f.,
: f.,
: f.,
: f. ?? ,
: f. ?? ,
});
}
}
Strategy 6: Self-Hosting Consideration
For high-volume use cases, self-hosting may be more cost-effective:
version: '3.8'
services:
documenso:
image: documenso/documenso:latest
ports:
- "3000:3000"
environment:
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
- NEXT_PRIVATE_DATABASE_URL=${DATABASE_URL}
- NEXT_PRIVATE_SMTP_HOST=${SMTP_HOST}
volumes:
- ./cert.p12:/opt/documenso/cert.p12:ro
postgres:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Cost comparison (example):
- Cloud: $49/user/month at 10 users = $490/month
- Self-hosted: Server + DB + maintenance = ~$100-200/month
Strategy 7: Usage Reporting Dashboard
async function generateCostReport(month: Date): Promise<CostReport> {
const metrics = await trackUsage();
const perDocumentCost = 0.5;
const estimatedCost = metrics.documentsCreated * perDocumentCost;
const report = {
period: `${month.getFullYear()}-${String(month.getMonth() + 1).padStart(2, "0")}`,
metrics: {
documentsCreated: metrics.documentsCreated,
documentsCompleted: metrics.documentsCompleted,
completionRate:
(metrics.documentsCompleted / metrics.documentsCreated) * 100,
uniqueRecipients: metrics.activeRecipients.size,
},
costs: {
estimated: estimatedCost,
perDocument: perDocumentCost,
},
recommendations: [] as string[],
};
if (report.metrics. < ) {
report..(
);
}
(metrics. > ) {
report..(
);
}
report;
}
Cost Optimization Checklist
Output
- Optimized document creation patterns
- Usage monitoring in place
- Cost reports available
- Self-hosting evaluated
Error Handling
| Cost Issue | Indicator | Solution |
|---|
| Overage charges | Exceeding limits | Upgrade plan or optimize |
| Unused features | Low completion rate | Simplify workflow |
| Duplicate documents | High creation rate | Use templates |
| Abandoned drafts | Many DRAFT status | Implement cleanup |
Resources
Next Steps
For architecture patterns, see documenso-reference-architecture.