Always-on denylist
The $0 guarantee, the full rule table, and how to override it when you really mean it.
Before wisp deploy (or wisp synth) writes anything to your AWS account, it scans the fully synthesized
CloudFormation template for resources that cost money while idle — regardless of how they got there, whether from a
wisp primitive, addRawResource, or a transform(). If it finds one, the deploy is
blocked and you get the exact resource, its illustrative monthly cost, and a $0-idle alternative — never a silent
bill.
The rule table
| Code | Resource | ~Monthly cost | Alternative |
|---|---|---|---|
WISP-AON-001 | AWS::RDS::DBInstance | $15.33 | new Store(...) — DynamoDB on-demand |
WISP-AON-002 | AWS::RDS::DBCluster (not Serverless v2 at MinCapacity: 0) | $45 | new Store(...), or Aurora Serverless v2 pinned to zero |
WISP-AON-003 | AWS::EC2::NatGateway | $32.40 | Remove VpcConfig — wisp never needs a VPC |
WISP-AON-004 | AWS::ElasticLoadBalancingV2::LoadBalancer | $16.20 | The API Gateway HTTP API Api already emits |
WISP-AON-005 | AWS::ElastiCache::* | $12 | Store, or an HTTP-native cache |
WISP-AON-006 | AWS::ECS::Service with DesiredCount > 0 | varies | Workflow for long-running work |
WISP-AON-007 | AWS::OpenSearchService::Domain | $25 | A managed, usage-billed search API |
WISP-AON-008 | AWS::MSK::Cluster | $100 | Queue, or EventBridge |
WISP-AON-009 | Lambda with ProvisionedConcurrencyConfig | varies | Remove it — wisp cold starts are already small |
WISP-AON-010 | Lambda with VpcConfig | $32.40 | Remove it — wisp Store/Api never need a VPC |
WISP-AON-011 | AWS::EC2::Instance | varies | A wisp function — one Lambda per route, $0 idle |
WISP-AON-012 | A Store table not using on-demand billing | varies | Store always synthesizes PAY_PER_REQUEST — this table wasn't created through Store |
Costs are illustrative baseline on-demand figures for a small resource in a typical region — verify against current AWS pricing before treating them as exact.
Overriding it
Sometimes you genuinely need one of these — a legacy RDS instance you're migrating away from, say. Allow specific
codes past the gate in wisp.config.ts:
export default {
app: "my-app",
target: "aws",
region: "eu-north-1",
allowAlwaysOn: ["WISP-AON-001"],
};This is loud by design — per-code, never silent, and it strips the $0-idle guarantee for exactly the resources you
named. wisp estimate reflects the override in its idle-floor number, so you always see what it's costing you.

