This page is orientation, not legal advice. It describes the shape of the rules well enough for you to build sensibly and to know when the question has outgrown a lesson. If you are storing health data, data about children, or anything you would be uncomfortable seeing in a newspaper, talk to a lawyer in your jurisdiction rather than to a website.
The idea
If your project is run from the EU or serves people in it, the General Data Protection RegulationThe EU law governing what may be done with information about identifiable people. It applies to a one-person project the same way it applies to a company, though the paperwork expected is smaller. applies to anything that can identify a person: a name, an email, an account id, an IP address. The law is long, but the parts a small project runs into are few. Collect only what you need for a stated purpose, say plainly what you collect, keep it no longer than you need it, and delete it when someone asks. Those four are also the common core of the UK, Californian and Brazilian regimes, so a project outside the EU that builds this way is starting from roughly the right posture and should check the specifics of its own jurisdiction.
the field test, applied to a signup form
field needed for? keep?
----- ----------- -----
email the login itself yes
name addressing them yes, if you use it
company "might be useful later" no
phone nothing you built yet no
full address unshipped feature no
IP + user agent debugging, 30 days yes, with an expiryHow it works
Data minimisation is one of the principles in Article 5: what you hold must be adequate, relevant, and limited to what is necessary for the purpose you named. Purpose comes first, then the field. A signup form asking for a company name because the form template had one is collecting data with no purpose behind it.
Article 17 gives people the right to have their data erased, and you need a way to do it. The right is not unlimited: Article 17(3) keeps what you must hold for a legal obligation, which for most projects means invoices and order records your tax rules require you to keep for years. Erase the account, keep the invoice, and say so when you answer. For a small project the procedure can be documented and manual rather than a feature: an email address people can write to, and a written sequence of SQL statements you run to remove the rows. Order matters in that sequence, because a row other tables point at cannot be deleted until those rows are gone. Delete from the tables that reference the person first and the person's own row last. Say in your privacy notice what you collect, why, who else sees it (your hosting provider, Stripe, an email service like Resend), and how to ask for deletion. Written honestly, that is one short page.
Two things you should never store yourself. Passwords are stored as a The output of a one-way function. From the hash you cannot recover the original password, so a stolen database does not directly hand over anyone's login., produced by an established algorithm such as argon2 or bcrypt, and in practice you get this by using an authentication provider rather than writing it. Card numbers you arrange never to touch. Taking payments at all puts you under Payment Card Industry Data Security StandardThe card networks' rules for anyone involved in card payments. What you have to do depends on how much of the card number passes through your own systems., and what changes is how much you have to do about it. Stripe's hosted checkout collects the card on Stripe's own pages and returns you an identifier, which keeps you in the smallest category and reduces the obligation to a short annual self-assessment you confirm in the Stripe dashboard. Building your own card form replaces that with a far larger programme.
What to do
- List every column in your database that describes a person and write the purpose each one serves in the product today. That list is the work; the deleting comes after.
- Stop collecting the purposeless ones at the form first, deploy that, and only then remove the columns in a migration, with a backup taken first. Dropping a column deletes what is in it and nothing brings it back. Dropping it while the form still sends that field also breaks every signup.
- Write the deletion procedure as a file in your repository with the exact statements in order, and rehearse it on a copy of your database holding a few made-up accounts, never on the live one. The next page sets that copy up.
- Give ageing data an expiry you actually run: a dated
DELETEin a scheduled job, your log provider's retention setting, or a monthly reminder and a saved query. An expiry nobody executes is a sentence in a privacy notice.
Where it breaks
Deletion is harder than it looks, because copies live outside your database: in nightly backups, in your email provider's sent history, in the analytics tool, and in your own exports. You cannot usually rewrite a backup, so the honest position is a documented retention window after which the backups holding that person's row have rolled off. Anonymised data is another common trap, since a record with the name removed but a unique id and a timestamp attached often still identifies one person. And the rules differ by jurisdiction and by data type. This page is a starting posture, not a compliance review.