From appfolio-pack
Optimizes AppFolio API costs by reducing redundant calls with caching, usage monitoring, and efficient query patterns. Useful for property management portfolios with high API volume.
How this skill is triggered — by the user, by Claude, or both
Slash command
/appfolio-pack:appfolio-cost-tuningThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
AppFolio Stack API pricing is partner-agreement based, with costs scaling by API call volume per managed property. Property management portfolios generate high-frequency reads for tenant lookups, lease status checks, and maintenance requests. Each redundant API call erodes margin on per-unit revenue. Optimizing call patterns directly impacts operational profitability, especially for portfolios ...
AppFolio Stack API pricing is partner-agreement based, with costs scaling by API call volume per managed property. Property management portfolios generate high-frequency reads for tenant lookups, lease status checks, and maintenance requests. Each redundant API call erodes margin on per-unit revenue. Optimizing call patterns directly impacts operational profitability, especially for portfolios managing hundreds or thousands of units where even small per-call costs compound rapidly.
| Component | Cost Driver | Optimization |
|---|---|---|
| Property/unit reads | Per-call pricing on tenant and unit endpoints | Cache with 10-15 min TTL; property data changes infrequently |
| Lease operations | Bulk lease queries across entire portfolio | Fetch all leases once, filter locally instead of per-unit calls |
| Maintenance requests | Polling for new work orders | Use webhooks to receive push notifications |
| Reporting exports | Large payload downloads for financial reports | Schedule off-peak, cache results for 24h |
| Vendor/owner lookups | Repeated lookups for the same contacts | Build a local lookup table, refresh daily |
class AppFolioCache {
private cache = new Map<string, { data: any; expiry: number }>();
get(key: string): any | null {
const entry = this.cache.get(key);
if (!entry || Date.now() > entry.expiry) return null;
return entry.data;
}
set(key: string, data: any, ttlMs = 600_000): void {
this.cache.set(key, { data, expiry: Date.now() + ttlMs });
}
async fetchWithCache(endpoint: string, ttlMs?: number): Promise<any> {
const cached = this.get(endpoint);
if (cached) return cached;
const response = await fetch(endpoint);
const data = await response.json();
this.set(endpoint, data, ttlMs);
return data;
}
}
class AppFolioUsageMonitor {
private calls: Array<{ endpoint: string; timestamp: number }> = [];
private budgetLimit = 10_000; // daily call budget
record(endpoint: string): void {
this.calls.push({ endpoint, timestamp: Date.now() });
const todayCalls = this.getTodayCount();
if (todayCalls > this.budgetLimit * 0.8) {
console.warn(`AppFolio API budget 80% consumed: ${todayCalls}/${this.budgetLimit}`);
}
}
getTodayCount(): number {
const startOfDay = new Date().setHours(0, 0, 0, 0);
return this.calls.filter(c => c.timestamp > startOfDay).length;
}
}
modified_since parameter| Issue | Cause | Fix |
|---|---|---|
| 429 Too Many Requests | Exceeded rate limit | Implement exponential backoff with jitter |
| Stale cache serving old data | TTL too long for volatile data | Reduce TTL for maintenance/lease endpoints to 2-5 min |
| Budget alerts firing daily | Polling loop running on short interval | Switch to webhook-driven architecture |
| Duplicate API calls | Multiple services fetching same data | Centralize through shared cache layer |
| Large payload timeouts | Fetching full portfolio in single call | Paginate requests, process in batches of 100 |
See appfolio-performance-tuning.
npx claudepluginhub fleet-to-force/claude-code-plugins-plus --plugin appfolio-pack5plugins reuse this skill
First indexed Jul 10, 2026
Optimizes AppFolio API costs by reducing redundant calls with caching, usage monitoring, and efficient query patterns. Useful for property management portfolios with high API volume.
Guides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.