abar

abar

Hey all,

I’m trying to build a low-cost website serving a catalogue of items, with standard options of viewing/filtering said items. It is expected that a catalogue itself will be queried often, but rarely updated. It is also a requirement that the website is resilient against DDoS attacks and other script-kiddie-level threats.

Given the requirements (and, let’s be honest, my shallow level of Erlang/Elixir ecosystem knowledge), I was wondering if I can use Agent module to serve as an in-memory cache:

  1. Load whole db table into agent’s state as a list (or map of id → item);

  2. Whenever a user requests a page, get the table from the Agent’s state, and filter by whichever items are needed;

  3. In case of an update - reload table, replace the Agent’s state.

I read about immutability in Elixir and assumed that this would be an improvement compared to making calls to the DB each time, since copied/filtered lists and maps will still point to the same immutable list.

Then I tested both approaches locally by holding down the “F5” button and saw that memory usage goes up either way.

By now, I have read about “share-nothing concurrency” and realized that copying the whole table with the response between processes is probably not the best way to go. And while I can change Agent module to accept a filter and return only requested items (and spawn a bunch of them for good measure) - I wonder if the whole setup even makes sense in practical terms?

Maybe there’s already a module/library that does what I need, or maybe I should stop overthinking, put my server behind DDoS protection by something like Cloudflare, and call it a day?

I would be grateful to hear a hint from someone who has experience in actually deploying something to a live audience.

Showing Posts 1 to 8

Schultzer

Schultzer

Just use ETS for this.

al2o3cr

al2o3cr

Consider something like Cachex which does all the things you’re thinking of and a bunch more.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Strong agree.

Really you want a two layer defense:

  1. Making your app fast is good, and things like cachex will help if you have cachable items.

  2. For true DDOS protection you really want to shield from that at a higher layer like the load balancer or CDN. If you have highly cacheable items a CDN can be quite helpful too, in particular if you have highly cacheable items consider just having the CDN front that too.

AstonJ

AstonJ

Some great tips in the posts above!

As Ben mentioned you will generally want multi-layered protection to be effective against DDoS attacks. So enabling your firewall and installing something like sshguard or fail2ban, using rate-limiting on the server level so requests are blocked before they touch your app (with something like HAProxy) and then rate limiting in your app and caching if possible.

The most efficient way to block attacks will be at the firewall level, followed by the proxy/load balancer (HAProxy), followed by your app (most expensive in terms of resources required - so block attacks before they hit your app whenever possible!)

You’ll then need to monitor the server and if you are getting attacked employ measures to mitigate them… but all that can be a lot so as you mentioned yourself many will opt to use a WAF like Cloudfare.

Whether you use Cloudfare or not you’ll want to ensure you harden your server, but again, it is a fairly big topic. The firewall with something like sshguard or fail2ban, changing SSH ports, removing root-login with password, etc, is a good place to start. Alternatively (and if this is commercial project) you could just get a managed server* and they should take care of a lot of it, or if this is a personal/hobby project you could start with a cloud provider like Digital Ocean because they have lots of set-up and administration guides that should help.

*When I started out we first had managed servers for a few years, then after I felt comfortable we moved to un-managed. So don’t feel like you have to dive straight into the deep end.

abar

abar OP

Thank you all for great replies! I’ll try Cachex, and I was thinking about starting with DigitalOcean, so, will just read more into what they offer.

dimitarvp

dimitarvp

Or go to Cloudflare. You can get very far with DDoS protection before having to pay.

BartOtten

BartOtten

Once you have added caching to offload DB request handling (Cachex works wonderful) and implemented rate-limiting to limit the stream of requests you cover the most common issues but are still vulnerable for a zillion other types of (D)DOS attacks (enormous headers, excessive opening of connections, slow lorris etc etc)

Better use an external service, accept you have to invest serious time setting up defense or accept you cant defend when some evil person targets the service.

The latter might not be the worst option. With the BEAM the risk is lowered due to the way it does concurrency.

Don’t forget how half the internet went dark due to an issue with CloudFlare.

AstonJ

AstonJ

One other thing I’d add is that server specs can help too - the more powerful a server the better it will be able to process requests and deal with attacks to help prevent the server going down (especially when it comes to layer 7 attacks). When an attack is ongoing I’ve seen HAProxy use significant resources, far more than it normally would, from barely hitting 1% in normal use to 50% during an attack. More memory and SSDs can help too.

However, try not to worry or overthink it. If you’re just starting out a managed server or providers like Digital Ocean are are great place to start as they will take care of most things on the server side (or provide set-up guides to help you) leaving you to focus on your app, where you’d consider the things you already are: caching, rate-limiting, optimising queries… and of course using a language that is resilient and scalable like Elixir :003:

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews