Appendix A — Single or multi-tenant
Comment or suggest a change. Select any text to comment on it. Press Suggest edits to change the wording right on this page, then send your changes. Or comment at the end of the page with your GitHub account.
For stored data the choice barely matters, because each user’s rows are locked under that user’s own key. It matters for the server’s memory, for cost, and for who can see metadata.
| One shared database | One database per user | |
|---|---|---|
| Stored data | Isolated by each user’s key: another user’s rows, served by mistake, do not decrypt | The same, plus physical separation |
| A compromised server | Sees what every active user’s requests decrypt while it is compromised | Sees one user’s |
| Metadata: counts, sizes, times | Visible to the operator. Per-user tag keys stop matching across users. | Visible to whoever runs it |
| Deleting a user | Delete their copies of the account key and their rows | Delete the database |
| Cost and operations | One database to run | One per user |

Figure A.1. One shared database compared with one database per user · Text version
The recommendation is one codebase that runs either way. Shared by default, with row-level security in the database as a second line behind the keys. A dedicated instance, run by the operator or by the user, for anyone who wants the smaller blast radius. The keys stay with the user in both.