Securing your User Data is one of the most crucial yet underrated parts of any software if your goal is to avoid something like the Resend incident, or a lawsuit in other cases.
Ensuring the security of your user data is very important if your product has any chance of working out in the long term.
So, let's talk about some of the best practices you can use to avoid losing
Your Precious User Data

NOTE: All of these practices apply to all kinds of SQL/NoSQL databases.
First Let's look at some ways to secure our DB on the basis of where it is hosted.
IP Whitelisting
IP Whitelisting basically allows us to only connect to a database cluster from a trusted IP address. You can create a list of trusted IP addresses, referred to as an IP access list, that can be used to connect to your cluster and access your data.
Use IP whitelisting if you’re connecting to a cloud database like MongoDB or Neon Postgres so that only requests coming from your own servers can hit the database.
You can set up your IP access list in MongoDB by following the official docs.
Docker Networking
Container networking refers to the ability for containers to connect to and communicate with each other, or to non-Docker workloads.
If you want to make a container accessible to other containers, it isn't necessary to publish the container's ports. You can enable inter-container communication by connecting the containers to the same user-defined bridge network
, so they can communicate with each other using container IP addresses or container names.
You can read more about how to configure a user-defined network to only allow incoming network requests from specific IP addresses of your server containers at the official docker hub docs.
Virtual Private Cloud (VPC)
VPC as the name suggests is basically your own private cloud outside of the public internet which no one else has access to. You can use VPC to host your server and db so that outside public internet cannot connect directly to it.
Almost all big cloud service providers like AWS, GCP and Azure offer VPC or VPS (Virtual Private Servers) which may cost more than normal public instances but ensure top-tier security of your user data.
These are configurable with a set of policies and rules which I'm not an expert to explain in detail as it is a bit complex DevOps topic, but @webdevcody has a great video about securing your databases with a VPC that you should check it out.
Now, let's look at some Simple security practices to ensure data security in your apps:
1. Don't use Firebase on the client
Now, I'm not against Firebase I love it and use it a lot for quickly prototyping my MVPs or for delivering a freelance project as fast as possible for a client where deadlines are rather short.
What I'm against is using Firebase, Appwrite or any other BaaS which lets your client directly connect to your DB, if you want to do so, set a server specifically for connecting to your DB and exposing REST API endpoints to achieve any DB transaction.
Don't forget to set STRONG security rules so that only authenticated users with specific permissions can access data.
2. Never trust anyone with your user data
If you're not living under a rock, you must know that there's this ongoing debate on X after this Lex Fridman Podcast YouTube clip by Levelsio went viral in which he talks about how paying a vc backed company a lot of money to do the work that can be easily done by yourself with a little bit of time and effort.
My thoughts are that if you are not a startup or indie hacker that needs to ship as fast as possible and are currently at No/Very Few Users, Sure use whatever services make you more efficient.
But OWN your User Data
Why do you think all the big companies roll their own auth solutions? Because they cannot afford to compromise the Data Privacy of their users and You shouldn't also
You CAN roll your own Auth
You should always use tried and tested production-ready auth strategies and open source libraries like authjs, super tokens, passport js, lucia auth, auth0 and many more so you don't have to build everything from scratch but you should never compromise on your user data with a third-party vendor.
Most Cloud Solutions like the Triangle Company can get very expensive very fast as your user base grows.
Another reason why I'm against this is data egress fees which are the fees levied on you when you decide to step off of their platform, generally, these fees are so high that you would rather pay them than migrate your data which is so hard in itself without breaking stuff.
Your data should be kept in your own database in multiple replicas and backups.
Remember if you don't know where or how your user data is kept, it is not safe.
3. Avoid Dropping User Tables🤦♂️
You know what I'm talking about. You've just joined a new company and are working late on a Friday night to impress your new team but in your heart, you want to go to the comic book store to read the newest issue of Dark Knight: Chaos at Arkham and during data migration, you forget to take a backup and accidentally drops the user table and poof just became another victim of layoffs.
But in all seriousness, DON'T PUSH TO PROD ON FRIDAY
- Take regular database backups:
set up a weekly/monthly cron to back up your data either to a local server or a server at a different location to avoid data centre outages. Many cloud providers today do this for you with the click of a button. You can read about Mongo Atlas' backup policies here. Neon Postgres doesn't provide backups yet but you can still use the good old pg_dump,
Read these docs on how to do so.
- Sanitize user queries before running a database transaction:
Don't just put whatever you get from the client directly into the database. Especially SQL (I've been a victim of this). Validate client Data and sanitise the inputs so that attackers cannot just pass DROP TABLE users;
and nuke your countless hours of reading Design Patterns.
These were some of my strategies to ensure data privacy and safety of user data for the apps I've built that I've learned after fucking up over and over again.
Hope you'll not make the same mistakes as me after reading this.
What else did I miss? Tell me on X.
Until Next Time,
Happy Debugging Coding👋