environment-setup-guide
Guide developers through setting up development environments with proper tools, dependencies, and configurations
guidewire-cost-tuning
Optimize Guidewire Cloud costs including license management, resource allocation, API usage optimization, and cloud infrastructure right-sizing. Trigger with phrases like "guidewire costs", "reduce spending", "license optimization", "cloud costs", "resource optimization guidewire".
Full skill instructions
Optimize Guidewire Cloud Platform costs through license management, API efficiency, resource right-sizing, and operational best practices.
| Component | Billing Model | Optimization Focus |
|---|---|---|
| Licensing | Per user/policy | User management, policy counts |
| API Calls | Per call/volume | Request optimization, caching |
| Storage | Per GB | Data retention, archiving |
| Compute | Per instance-hour | Right-sizing, auto-scaling |
| Data Transfer | Per GB | Efficient payloads, compression |
// Cost analysis utilities
interface UsageMetrics {
period: string;
apiCalls: number;
activeUsers: number;
storageGB: number;
computeHours: number;
dataTransferGB: number;
}
interface CostBreakdown {
licensing: number;
apiCalls: number;
storage: number;
compute: number;
dataTransfer: number;
total: number;
}
class CostAnalyzer {
async getUsageReport(startDate: Date, endDate: Date): Promise<UsageMetrics> {
const token = await this.getToken();
const response = await fetch(
`${this.gccUrl}/api/v1/usage?start=${startDate.toISOString()}&end=${endDate.toISOString()}`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.json();
}
async getCostBreakdown(startDate: Date, endDate: Date): Promise<CostBreakdown> {
const usage = await this.getUsageReport(startDate, endDate);
return {
licensing: this.calculateLicensingCost(usage),
apiCalls: this.calculateApiCost(usage),
storage: this.calculateStorageCost(usage),
compute: this.calculateComputeCost(usage),
dataTransfer: this.calculateTransferCost(usage),
total: 0 // Sum calculated below
};
}
identifyOptimizations(usage: UsageMetrics): Optimization[] {
const optimizations: Optimization[] = [];
// Check for inactive users
if (usage.activeUsers < usage.totalLicensedUsers * 0.7) {
optimizations.push({
type: 'licensing',
description: 'Reduce unused user licenses',
potentialSavings: (usage.totalLicensedUsers - usage.activeUsers) * this.perUserCost,
priority: 'high'
});
}
// Check for high API volume
if (usage.apiCalls > usage.expectedApiCalls * 1.5) {
optimizations.push({
type: 'api',
description: 'Implement API response caching',
potentialSavings: usage.apiCalls * 0.3 * this.perApiCallCost,
priority: 'medium'
});
}
// Check for storage growth
if (usage.storageGrowthRate > 0.1) { // 10% monthly growth
optimizations.push({
type: 'storage',
description: 'Implement data archiving policy',
potentialSavings: usage.storageGB * 0.2 * this.perGBCost,
priority: 'medium'
});
}
return optimizations;
}
}
// User license management
interface UserActivity {
userId: string;
lastLogin: Date;
loginCount30Days: number;
role: string;
department: string;
}
class LicenseOptimizer {
async analyzeUserActivity(): Promise<UserActivityReport> {
const users = await this.getUserActivity();
const inactive30Days = users.filter(u =>
daysSince(u.lastLogin) > 30 && u.loginCount30Days === 0
);
const inactive90Days = users.filter(u =>
daysSince(u.lastLogin) > 90
);
const lowActivity = users.filter(u =>
u.loginCount30Days < 5 && u.loginCount30Days > 0
);
return {
totalUsers: users.length,
inactive30Days: inactive30Days.length,
inactive90Days: inactive90Days.length,
lowActivity: lowActivity.length,
recommendations: this.generateRecommendations(inactive30Days, inactive90Days, lowActivity)
};
}
generateRecommendations(
inactive30: UserActivity[],
inactive90: UserActivity[],
lowActivity: UserActivity[]
): Recommendation[] {
const recommendations: Recommendation[] = [];
// Deactivate 90-day inactive users
if (inactive90.length > 0) {
recommendations.push({
action: 'DEACTIVATE_USERS',
users: inactive90.map(u => u.userId),
reason: 'No activity for 90+ days',
estimatedSavings: inactive90.length * this.userLicenseCost
});
}
// Review 30-day inactive users
if (inactive30.length > 0) {
recommendations.push({
action: 'REVIEW_USERS',
users: inactive30.map(u => u.userId),
reason: 'No activity for 30+ days',
estimatedSavings: inactive30.length * 0.5 * this.userLicenseCost
});
}
// Consider read-only licenses for low activity
if (lowActivity.length > 0) {
recommendations.push({
action: 'DOWNGRADE_LICENSE',
users: lowActivity.map(u => u.userId),
reason: 'Low activity - consider read-only license',
estimatedSavings: lowActivity.length * 0.6 * this.userLicenseCost
});
}
return recommendations;
}
}
// API usage optimization
class ApiCostOptimizer {
private callCounts: Map<string, number> = new Map();
// Track API call patterns
trackCall(endpoint: string, responseSize: number): void {
const key = endpoint.replace(/\/[a-f0-9-]{36}/g, '/{id}'); // Normalize IDs
this.callCounts.set(key, (this.callCounts.get(key) || 0) + 1);
}
// Identify optimization opportunities
analyzePatterns(): ApiOptimization[] {
const optimizations: ApiOptimization[] = [];
// Find frequently called endpoints
const topEndpoints = Array.from(this.callCounts.entries())
.sort((a, b) => b[1] - a[1])
.slice(0, 10);
topEndpoints.forEach(([endpoint, count]) => {
// Suggest caching for read-heavy endpoints
if (endpoint.includes('GET') && count > 1000) {
optimizations.push({
type: 'CACHE',
endpoint,
callCount: count,
suggestion: 'Implement response caching',
potentialReduction: 0.7
});
}
// Suggest batching for related calls
if (endpoint.includes('/accounts/') && count > 500) {
optimizations.push({
type: 'BATCH',
endpoint,
callCount: count,
suggestion: 'Use includes parameter to reduce calls',
potentialReduction: 0.5
});
}
});
return optimizations;
}
}
// Implement efficient API patterns
class EfficientApiClient {
private cache: LRUCache<string, any>;
private batchQueue: Map<string, Promise<any>>;
// Cache responses for repeated requests
async getCached<T>(
cacheKey: string,
fetcher: () => Promise<T>,
ttlMs: number = 60000
): Promise<T> {
const cached = this.cache.get(cacheKey);
if (cached) {
return cached;
}
const result = await fetcher();
this.cache.set(cacheKey, result, { ttl: ttlMs });
return result;
}
// Batch multiple requests into one
async batchGetAccounts(accountIds: string[]): Promise<Account[]> {
// Instead of N calls, use filter parameter
const filter = accountIds.map(id => `id:eq:${id}`).join(',or,');
return this.client.get(`/account/v1/accounts?filter=${filter}`);
}
// Use includes to reduce round trips
async getAccountComplete(accountId: string): Promise<AccountComplete> {
// Single call instead of 4
return this.client.get(
`/account/v1/accounts/${accountId}?include=policies,contacts,locations,activities`
);
}
// Compress large payloads
async postLargePayload(endpoint: string, data: any): Promise<any> {
const compressed = await gzip(JSON.stringify(data));
return this.client.post(endpoint, compressed, {
headers: {
'Content-Encoding': 'gzip',
'Content-Type': 'application/json'
}
});
}
}
// Data archiving and retention
package gw.cost.storage
uses gw.api.database.Query
uses gw.api.util.Logger
uses gw.transaction.Transaction
class StorageOptimizer {
private static final var LOG = Logger.forCategory("StorageOptimizer")
// Archive old claims
static function archiveOldClaims(olderThanDays : int) {
var cutoffDate = Date.Today.addDays(-olderThanDays)
var claimsToArchive = Query.make(Claim)
.compare(Claim#CloseDate, LessThan, cutoffDate)
.compare(Claim#State, Equals, ClaimState.TC_CLOSED)
.select()
.toList()
LOG.info("Found ${claimsToArchive.Count} claims to archive")
claimsToArchive.batch(100).each(\batch -> {
Transaction.runWithNewBundle(\bundle -> {
batch.each(\claim -> {
var c = bundle.add(claim)
c.archiveToExternalStorage() // Custom archive implementation
})
})
})
}
// Purge old audit logs
static function purgeAuditLogs(olderThanDays : int) {
var cutoffDate = Date.Today.addDays(-olderThanDays)
var deleted = Query.make(AuditLog)
.compare(AuditLog#CreateTime, LessThan, cutoffDate)
.delete()
LOG.info("Purged ${deleted} audit log entries")
}
// Compress document attachments
static function compressAttachments(claim : Claim) {
claim.Documents.each(\doc -> {
if (doc.Size > 1024 * 1024 && !doc.IsCompressed) { // > 1MB
Transaction.runWithNewBundle(\bundle -> {
var d = bundle.add(doc)
d.compress()
})
}
})
}
// Generate storage report
static function getStorageReport() : StorageReport {
var report = new StorageReport()
report.TotalDocumentsMB = calculateTotalDocumentSize()
report.TotalAuditLogsMB = calculateAuditLogSize()
report.TotalHistoryMB = calculateHistorySize()
report.ArchivableClaims = Query.make(Claim)
.compare(Claim#CloseDate, LessThan, Date.Today.addYears(-2))
.select()
.Count
report.PurgeableAuditLogs = Query.make(AuditLog)
.compare(AuditLog#CreateTime, LessThan, Date.Today.addDays(-90))
.select()
.Count
return report
}
}
// Resource utilization analysis
interface ResourceMetrics {
cpuUtilization: number[]; // Hourly samples
memoryUtilization: number[];
requestsPerSecond: number[];
timestamp: Date[];
}
class ResourceOptimizer {
async analyzeUtilization(days: number = 30): Promise<ResourceAnalysis> {
const metrics = await this.getMetrics(days);
const cpuP95 = percentile(metrics.cpuUtilization, 95);
const memoryP95 = percentile(metrics.memoryUtilization, 95);
const rpsP95 = percentile(metrics.requestsPerSecond, 95);
const recommendations: ResourceRecommendation[] = [];
// CPU under-utilized
if (cpuP95 < 40) {
recommendations.push({
resource: 'CPU',
currentUtilization: cpuP95,
recommendation: 'Reduce CPU allocation',
potentialSavings: this.calculateCpuSavings(cpuP95)
});
}
// Memory over-provisioned
if (memoryP95 < 50) {
recommendations.push({
resource: 'Memory',
currentUtilization: memoryP95,
recommendation: 'Reduce memory allocation',
potentialSavings: this.calculateMemorySavings(memoryP95)
});
}
// Auto-scaling opportunities
const utilizationVariance = calculateVariance(metrics.cpuUtilization);
if (utilizationVariance > 0.3) {
recommendations.push({
resource: 'Compute',
recommendation: 'Enable auto-scaling',
reason: 'High utilization variance detected',
potentialSavings: this.calculateAutoScalingSavings(metrics)
});
}
return {
cpuP95,
memoryP95,
rpsP95,
recommendations
};
}
async implementAutoScaling(): Promise<void> {
const config = {
minInstances: 2,
maxInstances: 10,
targetCpuUtilization: 70,
scaleUpCooldown: 300,
scaleDownCooldown: 600
};
await this.configureAutoScaling(config);
}
}
// Cost monitoring and alerting
interface CostAlert {
threshold: number;
period: 'daily' | 'weekly' | 'monthly';
metric: string;
recipients: string[];
}
class CostMonitor {
private alerts: CostAlert[] = [];
addAlert(alert: CostAlert): void {
this.alerts.push(alert);
}
async checkAlerts(): Promise<AlertNotification[]> {
const notifications: AlertNotification[] = [];
for (const alert of this.alerts) {
const currentValue = await this.getCurrentValue(alert.metric, alert.period);
if (currentValue > alert.threshold) {
notifications.push({
alert,
currentValue,
exceededBy: ((currentValue - alert.threshold) / alert.threshold) * 100,
timestamp: new Date()
});
}
}
return notifications;
}
async generateReport(): Promise<CostReport> {
const currentMonth = await this.getMonthToDateCosts();
const previousMonth = await this.getPreviousMonthCosts();
return {
currentMonth,
previousMonth,
change: ((currentMonth.total - previousMonth.total) / previousMonth.total) * 100,
breakdown: {
licensing: currentMonth.licensing,
api: currentMonth.apiCalls,
storage: currentMonth.storage,
compute: currentMonth.compute
},
recommendations: await this.generateRecommendations()
};
}
}
// Example cost alert setup
const costMonitor = new CostMonitor();
costMonitor.addAlert({
threshold: 10000,
period: 'daily',
metric: 'api_calls',
recipients: ['[email protected]']
});
costMonitor.addAlert({
threshold: 5000,
period: 'monthly',
metric: 'total_cost',
recipients: ['[email protected]', '[email protected]']
});
| Category | Action | Potential Savings |
|---|---|---|
| Licensing | Deactivate inactive users | 10-30% |
| Licensing | Review license tiers | 5-15% |
| API | Implement caching | 20-50% |
| API | Use batch operations | 10-30% |
| Storage | Archive old data | 15-40% |
| Storage | Compress attachments | 10-20% |
| Compute | Right-size instances | 20-40% |
| Compute | Enable auto-scaling | 15-30% |
For architecture patterns, see guidewire-reference-architecture.
Guide developers through setting up development environments with proper tools, dependencies, and configurations
Implement Exa lint rules, policy enforcement, and automated guardrails. Use when setting up code quality rules for Exa integrations, implementing pre-commit hooks, or configuring CI policy checks for Exa best practices. Trigger with phrases like "exa policy", "exa lint", "exa guardrails", "exa be...
Configure CI/CD pipelines for Documenso integrations. Use when setting up automated testing, deployment pipelines, or continuous integration for Documenso projects. Trigger with phrases like "documenso CI", "documenso GitHub Actions", "documenso pipeline", "documenso automated testing".
Build check model availability and implement fallback chains. Use when building resilient systems or handling model outages. Trigger with phrases like 'openrouter availability', 'openrouter fallback', 'openrouter model down', 'openrouter health check'.
Configure Langfuse enterprise organization management and access control. Use when implementing team access controls, configuring organization settings, or setting up role-based permissions for Langfuse projects. Trigger with phrases like "langfuse RBAC", "langfuse teams", "langfuse organization"...
Execute compliance and security auditing for Cursor usage. Triggers on "cursor compliance", "cursor audit", "cursor security review", "cursor soc2", "cursor gdpr". Use when analyzing or auditing cursor compliance audit. Trigger with phrases like "cursor compliance audit", "cursor audit", "cursor".
Configure Apollo.io CI/CD integration. Use when setting up automated testing, continuous integration, or deployment pipelines for Apollo integrations. Trigger with phrases like "apollo ci", "apollo github actions", "apollo pipeline", "apollo ci/cd", "apollo automated tests".
Create robust Python automation with full logging and safety checks. Use when tasks need complex data processing, authenticated API work, conditional file operations, or error handling beyond simple shell commands.
Configure PostHog across development, staging, and production environments. Use when setting up multi-environment deployments, configuring per-environment secrets, or implementing environment-specific PostHog configurations. Trigger with phrases like "posthog environments", "posthog staging", "po...
Expert in designing and building autonomous AI agents. Masters tool use, memory systems, planning strategies, and multi-agent orchestration. Use when: build agent, AI agent, autonomous agent, tool use, function calling.
Validate insecure deserialization checker operations. Auto-activating skill for Security Fundamentals. Triggers on: insecure deserialization checker, insecure deserialization checker Part of the Security Fundamentals skill category. Use when working with insecure deserialization checker functiona...
Manage path traversal finder operations. Auto-activating skill for Security Fundamentals. Triggers on: path traversal finder, path traversal finder Part of the Security Fundamentals skill category. Use when working with path traversal finder functionality. Trigger with phrases like "path traversa...
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience