Design and limit consumption. Build throttling into the architecture, limit the amount of resources an unauthorized user can cause to be consumed, and place explicit scale limits on protocols. Use strong authentication and access control, protect login functionality against denial of service, consider caching database result sets, and track request rates so requests exceeding a defined threshold can be blocked.
The system can recognize an attack and deny further access for a period, or uniformly throttle requests so resources cannot be consumed faster than they are released. The first approach can itself deny service to a legitimate user, especially if an attacker impersonates that user, while uniform throttling is difficult to implement and only raises the attack cost rather than fully solving the problem. Ensure that every resource-allocation failure leaves the system in a safe posture.