Some attacks are not trying to take you offline. They are trying to make staying online too expensive.
On fixed hardware that threat barely existed: a server either coped or fell over, and the invoice was the same either way. On infrastructure billed by the request, the gigabyte and the log line, a flood that your platform absorbs perfectly is still a flood you pay for. The phrase for it, economic denial of sustainability, dates from 2008, when pay-per-use cloud was new enough that people were only beginning to notice.
What is EDoS testing?
EDoS testing is an authorised test that measures what an attack costs you while the service stays up: which metered services a flood touches, how fast each meter climbs, how long it keeps climbing after the attack stops, and how late your own controls find out. The result is a cost per attack-hour and a list of meters, not a pass or fail on availability.
Getting sign-off, drawing the scope and ramping safely are no different here than anywhere else, so they stay in the complete guide to DDoS testing. The autoscaling half of the problem, a fleet that grows because a flood looks like demand, has its own page on autoscaler exposure. This post is about everything else on the invoice.
| Availability test | EDoS test | |
|---|---|---|
| The question | Did the service stay up? | What did staying up cost, per hour of attack? |
| Unit of measurement | Goodput, latency, error rate | Billed units per meter: requests, GB, log volume, messages |
| A "good" result | Nothing fell over | Spend stayed bounded and someone noticed in minutes |
| Where the failure shows | Dashboards, users | The invoice, weeks later |
| Who reads the report | Engineering, incident lead | Engineering and whoever owns the cloud budget |
Where does a single attack request get billed?
In more places than the compute bill suggests. A request that never reaches a server can still pass four or five meters on the way in.
The edge counts it first
Most CDN and edge platforms bill per request handled, separately from bytes delivered. A flood of small requests that are answered at the edge is cheap in bandwidth and still counted, one by one.
Inspection is its own line item
Per-request WAF products typically charge for each request evaluated, plus a fee per rule or policy. Bot-management and fraud add-ons often carry their own per-request fee on top. The control that decides whether a request is hostile is metered on every request it looks at, hostile or not.
Egress can be billed twice on a miss
When a request misses the cache, the origin sends the object to the edge and the edge sends it to the client. Whether that first hop is billed depends on the pairing: it is free from an AWS origin into CloudFront, and Cloudflare does not meter egress at all, but an origin on a different cloud or on-prem usually pays for it. On those pairings a miss on a large object is paid for twice, and once more if the origin sits behind a NAT gateway that bills per gigabyte processed.
The load balancer bills in capacity units
Managed load balancers increasingly bill on composite capacity units: new connections, active connections, bytes processed, rule evaluations. Whichever dimension is highest sets the charge for that hour. A connection-heavy flood with tiny payloads can drive the bill on a dimension nobody was watching.
Logs can be billed three ways
Each request that reaches a logging pipeline is billed at ingestion, again for every month it is retained, and once more if it is forwarded to a SIEM licensed by daily volume. A one-hour flood that writes a structured log line per request can outlast its own attack on the invoice by the full retention period.
Some meters pay someone else
Anything your application calls per request on a paid third party is a meter the attacker can drive: SMS and voice verification, email sending, address lookup, payment pre-authorisation, a geocoding or AI inference API. These are usually priced per call and almost never sit behind the same rate limits as the front door.
Does blocking an attack stop the bill?
It stops some of it. Where you block decides how many meters a hostile request has already passed.
A block at the edge still pays for inspection
A WAF that blocks a request at the edge has still evaluated it, and on a per-request product that evaluation is billed. The block saves every meter behind it: egress, load balancer, compute, database. It does not save the edge request fee, the inspection fee, or the log line recording the block.
Some edge networks do not charge for traffic their DDoS layer mitigates, while charging normally for WAF evaluation on the same requests. Which of those a given flood lands in depends on which layer stopped it, and that is worth knowing before an incident, not after.
A block at the origin pays for almost everything
A rate limit enforced in the application or at an internal load balancer protects the database, and nothing in front of it. By the time the origin returns its 429, the request has crossed the edge, been inspected, been forwarded, been balanced, and been logged twice.
That is the economic case for filtering as far forward as the request allows, and it is a separate case from the availability one. A control placed late can be perfectly adequate for uptime and still leave most of the bill unguarded.
Logging every block is a decision
Full logging of blocked requests is useful forensically and expensive at flood volume. Sampling blocked-request logs at the edge, or logging a rolled-up count per rule per minute instead of one line per request, keeps the evidence and drops most of the ingestion. Decide it in advance; changing log configuration mid-incident is a poor use of an incident.
Provider cost protection is a claim, not a cap
Some managed DDoS services offer credits for scaling charges caused by a documented attack on enrolled resources. These schemes are scoped to particular resource types and applied for after the event, and the comparison of AWS Shield and Azure DDoS Protection covers how the two largest differ. Log ingestion, third-party APIs and resources outside the enrolment are generally your own problem.
Which requests cost the most to receive?
The ones where your side does far more billed work than the attacker spends sending them. The useful number is a ratio: billed units out per unit the attacker puts in.
Bytes out per byte in
A GET request with ordinary headers is well under a kilobyte. If it fetches a 5 MB file, every attacker byte buys several thousand bytes of your egress, and that is before any origin-side transfer a miss adds. The highest-ratio paths are almost always downloads, media, export endpoints and large API responses that the cache does not hold.
This is the bandwidth-shaped cousin of the amplification factor used for reflection attacks, except the reflector is you and the victim is your budget.
Cache misses on purpose
Appending a random query string to a cacheable URL forces a miss wherever the cache key includes the full query string. The mechanics of a cache-busting attack are covered on its own page. In an EDoS test the interesting measurement is narrower: the egress and origin cost per thousand forced misses, before and after the cache key is normalised to ignore parameters the application does not use.
Cardinality you did not mean to buy
Hosted metrics are often billed by active time series or by unique tag combinations. If a request metric is labelled with the raw URL path, the user agent, or a query parameter, every random value an attacker sends becomes a new series. The flood ends; the series stay billable for the retention window.
That one is easy to find in a test and almost invisible in production until the bill arrives, because nothing slows down.
Verification messages and pumping
An open signup or login form that sends an SMS one-time code is a per-message meter with a public trigger. The pattern known as SMS pumping, or artificially inflated traffic, abuses exactly this: automated requests send codes to number ranges where someone else earns a share of the termination fee.
The fix is not a bigger budget. It is per-destination and per-prefix limits, a challenge before any paid message is sent, and refusing to send to countries you do not serve.
The chart counts log ingestion and the SIEM as separate meters, so the SMS path reaches 11 although the map draws them as one box.
Why does the bill find out last?
Because every system that reacts to an attack runs on a faster clock than the one that measures its cost.
Minutes to scale, hours to bill
Edge request metrics refresh in about a minute. Autoscalers act within minutes. Billing data arrives far later: AWS, for example, documents its budget figures as refreshing up to three times a day, and other providers note that billing exports can lag by hours or more. An alert built on billing data cannot fire until hours of spend have already happened.
A budget is an alarm, not a ceiling
On most production cloud accounts there is no hard spending cap. A budget sends a notification when a threshold is crossed, and some providers let it trigger an action such as applying a restrictive policy or stopping instances. Even those act on the delayed billing figure.
The controls that actually bound spend are the ones that bound usage: max instance counts, reserved concurrency, egress quotas, per-key API limits, and the edge filter itself.
The tail outlasts the attack
When the flood stops, the spend does not. Scale-in is deliberately slower than scale-out (the autoscaler exposure page explains why, and the yo-yo attack shows how a pulsed flood exploits it). Retained logs bill monthly. New metric series bill until they expire. Capacity bought in a panic during the incident may carry a commitment term.
An EDoS test records the tail as carefully as the peak, because the tail is often larger.
Read the meters, not the bill
The fix for the lag is to detect cost from usage, not from billing. Requests per minute at the WAF, bytes out per minute at the CDN, log gigabytes ingested per hour, SMS sent per minute: each is a near-real-time proxy for spend. Multiplied by your contracted unit rates, they give a live cost estimate long before the provider's figure updates.
Can you measure the cost of a flood without paying for it?
Mostly, yes. An EDoS test is a cost event by design, so the craft is in measuring a rate at small volume and extrapolating, rather than paying for the full hour.
Cap the test's own spend
Set a spend ceiling for the run, derived from unit rates and the planned volume, and an abort when the live estimate crosses it. Run high-ratio paths at low volume and extrapolate; you do not need an hour of 5 MB downloads to learn what an hour costs. General ceilings, kill switches and production safety are in testing without disrupting production.
Tag and isolate the traffic
Mark test traffic so it can be separated in logs and usage reports: a header the edge records, a known source range, a cost-allocation tag on any resources created for the run. Without it, the test's spend disappears into the month's total and the report is guesswork.
Leave third parties out
Never drive a real paid third-party API at volume. Point verification flows at a sandbox or a stub, and measure the call rate your application would have made. The finding is the rate, not the bill.
Know which costs are already elsewhere
Serverless invocation and concurrency costs are covered in serverless DDoS testing, node and pod scaling in Kubernetes DDoS testing, and the backend cost of individual API endpoints in DDoS testing for APIs. An EDoS test should reference those results rather than re-measure them, and spend its own budget on the meters they do not reach.
What the report should contain
- Cost per attack-hour at each tested rate, built from usage counters and contracted rates.
- The meter of first spend: which line item climbed fastest, per path.
- Bill amplification per path: billed units out per attacker unit in.
- The tail: how long each meter kept billing after traffic stopped, and its share of the total.
- Time to cost detection: how long until any alert fired that a budget owner would see.
- Control order: whether usage-bounding controls engaged before or after each meter started climbing.
An EDoS testing checklist
- List every metered service on each public path, including logging, metrics and paid third parties.
- Record the billing unit for each meter and your contracted rate (internally, never in a report that leaves the team).
- Identify the highest-ratio paths: large uncached responses, exports, downloads, paid-message triggers.
- Check the cache key on each cacheable path and test it with random query strings.
- Check metric labels for attacker-controlled values such as raw paths and user agents.
- Confirm where each blocking control sits and which meters it saves.
- Decide the logging policy for blocked requests at flood volume.
- Build a live cost estimate from usage counters and alert on it, independent of billing data.
- Run the test with a spend ceiling, tagged traffic and third parties stubbed.
- Measure the tail after the attack stops, then repeat after each fix.
FAQ
Is EDoS the same as a DDoS attack?
It is a DDoS whose success condition is cost instead of downtime. The traffic can be identical; the difference is that the target absorbs it and pays. Any infrastructure that bills per request, per byte or per scaled unit is exposed.
Does a WAF protect against economic denial of sustainability?
Partly. A WAF placed at the edge saves every meter behind it, but on per-request products it is itself billed for each request it inspects, including the ones it blocks. It reduces the cost of a flood; it does not make the cost zero.
Can a budget alert stop an EDoS attack?
Not on its own. Billing data is refreshed hours after usage, so an alert built on it fires late, and on most accounts a budget notifies rather than caps. Bound usage directly with instance limits, quotas and edge rules, and alert on usage counters for speed.
What should an EDoS test measure?
Cost per attack-hour, the meter that climbs first on each path, billed units out per attacker unit in, the spend that continues after the attack ends, and how long it took for anyone responsible for the budget to be told.
Is SMS pumping an EDoS attack?
It is the purest form of one. Each request triggers a paid message, the service works exactly as designed, and the cost lands on you while someone else collects part of it. Per-destination limits and a challenge before sending are the controls to test.
Uptime is a yes or no; cost is a rate
An availability test can end with a clean answer: it held. An EDoS test never does. Every architecture that bills by use has a price for each hour of attack, and the only question is whether you know the number and whether it fits the budget.
The meters on a modern stack will keep changing: new add-ons billed per request, new log destinations, a new paid API behind the signup form. What does not change is the method: list the meters, find the ratio, read usage instead of the invoice, and put the filter in front of the most expensive thing you own.
The attacker already knows your price list. It is published.
