It's been a while since I've done infra work, but here are some general things to keep in mind:
- Having a good frontend cache layer is helpful. Let the cache return results near instantly instead of hitting your servers. Cloudflare can handle this, so can Amazon CloudFront or Fastly.
- WAF - Web Application Firewall - While not specifically to protected against DDoS, it can help prevent bad actors from destroying your site in other ways (e.g. potential SQL injection).
- Have a scalable backend infrastructure. Whether this is containers (e.g. Docker), Infra as Code (Terraform) or something else, your site needs to be able to scale up when needed, and back down when there isn't much traffic. This could provide a cost savings to you as you can use fewer resources during low volume, and only scale up when needed during times of high traffic.
- Site health monitoring (e.g. New Relic or similar). This can provide you with alerts should errors start happening, or the load on your servers start to rise above a certain level. These statistics guide how you should set your infrastructure to respond to certain events. They can also provide insight into bottlenecks of your application so you can squeeze even more performance out of a single server (helping with cost savings).
The above doesn't come free, and if you're getting hit with a DDoS attack constantly, then IP banning is a quick, easy, cheap way to help prevent that. Pretty sure CloudFlare would allow you to route certain IP blocks to a parked page or something to keep the traffic off your site.
Also if you're bypassing CloudFlare's caching, you're probably not doing yourself any favors since every request that comes through CloudFlare will be forwarded to your backend server instead of potentially having the response delivered without touching your server.