Advice on working with AWS Lambda and Fly

Hey, I’m having a hard time deciding on how the discrete parts of my application should be tied together.
The three components are:

  1. I have a group of AWS Lamba’s that process inbound email (using SES). They essentially just parse/validate the raw inbound mail.
  2. I need a RDBMS (Postgres) to store the parsed mail in it’s entirety.
  3. I need API servers that can be accessed through client applications.

I want to use Fly for both the API server and the database but I’m not sure what’s the best way to work with AWS Lambda.

Things I’ve considered,

  1. Running PgBouncer on Fly and then connecting Fly and AWS Lambda using something like Tailscale. See Tailscale on AWS Lambda and Tailscale on Fly. I don’t really want to do this because it adds a lot of complexity to my existing setup.

  2. Have AWS Lambda call a webhook exposed by the API server on Fly. So the Fly server would be responsible for writing to the database. I could go the Tailscale route but I could also just use an authenticated public webhook endpoint. This option has fewer components but it makes provisioning/reliability more difficult to manage. AWS Lambda can scale pretty high and I’m afraid my costs could potentially sky-rocket. I could introduce a buffer (like NATS or something similar?) but that too adds another component I need to manage.

  3. Have the primary database be outside of Fly. Using something like AWS RDS (with the RDS Proxy) or Supabase allows AWS Lambda to perform writes to the DB. Then to continue to take advantage of the API servers on Fly I could setup globally distributed redis caches on Fly. (I’m unsure if I can setup postgres read replicas inside Fly with the primary being outside, at least not easily.) I think this option would have the least infrastructure management but I don’t know how effectively I’d be able to use the caches.

Is there a way I can simplify my setup? Is Option 3 something you would recommend?

Hi @tuhinnair444

Another couple of options is to:

  1. expose your DB publicly and have the AWS Lambda function simply connect to it
  2. use a wireguard tunnel

For option 1, there are tradeoffs and security concerns with this method so usually the recommendation is to run the AWS Lambda function inside a private subnet in your own VPC, then allow it internet access through a NAT Gateway / NAT Instance which resides in a public subnet, and apply an IP filtering rule on your publicly exposed DB.

For option 2, you can run your AWS Lambda in a VPC and connect to the DB over the secure wireguard tunnel.

Keep in mind that for best/lowest latency performance, API servers and other services that talk directly with your DB should be located as close as possible, in the same datacenter if possible.

Having the API servers and DB in the same cloud would be most beneficial, having the inbound email processing may not need such low latency requirements.